Fix second half on #33343: disallow generic functions as type arguments.

There is a seeming parse error in typedefs, and an open question on the
issue (33343) about what to do when a generic function type is inferred.

Otherwise this seems ready to go.

Bug: 33343
Change-Id: I10d2ea9b6ca26ed2c6ff6b24ffe5008fc4797ef2
Reviewed-on: https://dart-review.googlesource.com/61109
Commit-Queue: Mike Fairhurst <mfairhurst@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 316443a..1557389 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -130,6 +130,7 @@
   CompileTimeErrorCode.FINAL_INITIALIZED_MULTIPLE_TIMES,
   CompileTimeErrorCode.GENERIC_FUNCTION_TYPED_PARAM_UNSUPPORTED,
   CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND,
+  CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT,
   CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME,
   CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS,
   CompileTimeErrorCode.IMPLEMENTS_DISALLOWED_CLASS,
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index e071c48..5d1bada 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -2410,6 +2410,18 @@
               ' of the larger declaration signature');
 
   /**
+   * It is a compile-time error if a generic function type is used as an actual
+   * type argument.
+   */
+  static const CompileTimeErrorCode GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT =
+      const CompileTimeErrorCode(
+          'GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT',
+          "Generic function has type parameters '<{0}>', so it may not be used"
+          ' as a type argument',
+          correction: "Try removing the type parameters '<{0}>', or using"
+              " 'dynamic' as the type argument here instead of a function.");
+
+  /**
    * 15.3.1 Typedef: Any self reference, either directly, or recursively via
    * another typedef, is a compile time error.
    */
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 7cf79c0..b470ac2 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -5947,11 +5947,19 @@
       for (int i = 0; i < loopThroughIndex; i++) {
         TypeAnnotation argumentNode = argumentNodes[i];
         DartType argType = argumentNode.type;
+        if (argType is FunctionType && argType.typeFormals.isNotEmpty) {
+          _errorReporter.reportTypeErrorForNode(
+              CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT,
+              argumentNode,
+              [argType.typeFormals.join(', ')]);
+          continue;
+        }
         DartType boundType = parameterElements[i].bound;
         if (argType != null && boundType != null) {
           if (shouldSubstitute) {
             boundType = boundType.substitute2(arguments, parameterTypes);
           }
+
           if (!_typeSystem.isSubtypeOf(argType, boundType)) {
             ErrorCode errorCode;
             if (_isInConstInstanceCreation) {
@@ -6471,6 +6479,15 @@
         //     <T extends Clonable<T>>
         //
         DartType argType = typeArgs[i];
+
+        if (argType is FunctionType && argType.typeFormals.isNotEmpty) {
+          _errorReporter.reportTypeErrorForNode(
+              CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT,
+              typeArgumentList[i],
+              [argType.typeFormals.join(', ')]);
+          continue;
+        }
+
         DartType bound =
             fnTypeParams[i].bound.substitute2(typeArgs, fnTypeParams);
         if (!_typeSystem.isSubtypeOf(argType, bound)) {
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index e54318a..a500975 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -15,7 +15,8 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart' show TypeParameterMember;
 import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/error/codes.dart' show StrongModeCode;
+import 'package:analyzer/src/error/codes.dart'
+    show StrongModeCode, CompileTimeErrorCode;
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisContext, AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
index 8232bc7..97fa300 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
@@ -3133,6 +3133,34 @@
   test_genericFunctionTypeAsBound_typedef() async {
     await super.test_genericFunctionTypeAsBound_typedef();
   }
+
+  @override
+  @failingTest
+  @potentialAnalyzerProblem
+  test_genericFunctionTypeArgument_class() async {
+    await super.test_genericFunctionTypeArgument_class();
+  }
+
+  @override
+  @failingTest
+  @potentialAnalyzerProblem
+  test_genericFunctionTypeArgument_functionType() async {
+    await super.test_genericFunctionTypeArgument_functionType();
+  }
+
+  @override
+  @failingTest
+  @potentialAnalyzerProblem
+  test_genericFunctionTypeArgument_function() async {
+    await super.test_genericFunctionTypeArgument_function();
+  }
+
+  @override
+  @failingTest
+  @potentialAnalyzerProblem
+  test_genericFunctionTypeArgument_method() async {
+    await super.test_genericFunctionTypeArgument_method();
+  }
 }
 
 /// Tests marked with this annotation fail because of a Fasta problem.
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 8b91102..6f250b2 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -7063,6 +7063,98 @@
     verify([source]);
   }
 
+  test_genericFunctionTypeArgument_class() async {
+    Source source = addSource(r'''
+class C<T> {}
+C<T Function<T>(T)> c;''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
+    verify([source]);
+  }
+
+  test_genericFunctionTypeArgument_functionType() async {
+    Source source = addSource(r'''
+T Function<T>(T) f;
+main() { f<S Function<S>(S)>(null); }''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
+    verify([source]);
+  }
+
+  test_genericFunctionTypeArgument_function() async {
+    Source source = addSource(r'''
+T f<T>(T) => null;
+main() { f<S Function<S>(S)>(null); }''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
+    verify([source]);
+  }
+
+  test_genericFunctionTypeArgument_method() async {
+    Source source = addSource(r'''
+class C {
+  T f<T>(T) => null;
+}
+main() { new C().f<S Function<S>(S)>(null); }''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
+    verify([source]);
+  }
+
+  @failingTest
+  test_genericFunctionTypeArgument_inference_functionType() async {
+    // TODO(mfairhurst) how should these inference errors be reported?
+    Source source = addSource(r'''
+T Function<T>(T) f;
+main() { f(<S>(S s) => s); }''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
+    verify([source]);
+  }
+
+  @failingTest
+  test_genericFunctionTypeArgument_inference_function() async {
+    // TODO(mfairhurst) how should these inference errors be reported?
+    Source source = addSource(r'''
+T f<T>(T) => null;
+main() { f(<S>(S s) => s); }''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
+    verify([source]);
+  }
+
+  @failingTest
+  test_genericFunctionTypeArgument_inference_method() async {
+    // TODO(mfairhurst) how should these inference errors be reported?
+    Source source = addSource(r'''
+class C {
+  T f<T>(T) => null;
+}
+main() { new C().f(<S>(S s) => s); }''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
+    verify([source]);
+  }
+
+  @failingTest
+  test_genericFunctionTypeArgument_typedef() async {
+    // TODO(mfairhurst) diagnose these parse errors to give the correct error
+    Source source = addSource(r'''
+typedef T f<T>(T t);
+final T<Function<S>(int)> x = null;''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
+    verify([source]);
+  }
+
   test_undefinedAnnotation_unresolved_identifier() async {
     Source source = addSource(r'''
 @unresolved
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index 79bacbd..705f190 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -33,7 +33,6 @@
 final_syntax_test/04: Fail # Issue 11124
 function_type_parameter2_negative_test: CompileTimeError
 function_type_parameter_negative_test: CompileTimeError
-generic_function_type_as_type_argument_test/01: MissingCompileTimeError # Issue 30929
 generic_function_type_as_type_argument_test/02: MissingCompileTimeError # Issue 30929
 generic_local_functions_test: CompileTimeError # Issue 28515
 generic_methods_generic_function_parameter_test: CompileTimeError # Issue 28515
@@ -1354,7 +1353,6 @@
 generic_constructor_mixin_test/01: MissingCompileTimeError
 generic_field_mixin6_test/01: MissingCompileTimeError
 generic_function_typedef2_test/04: MissingCompileTimeError
-generic_methods_generic_function_result_test/01: MissingCompileTimeError # Issue #30207
 generic_methods_overriding_test/01: MissingCompileTimeError
 generic_test/01: MissingCompileTimeError
 identical_const_test/01: MissingCompileTimeError
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index d93e1c8..a643e67 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -384,6 +384,7 @@
 function_type_parameter2_negative_test: Fail
 function_type_parameter_negative_test: Fail
 generic_function_bounds_test: RuntimeError
+generic_function_type_as_type_argument_test/01: MissingCompileTimeError # Issue 29920
 generic_methods_generic_function_result_test/01: MissingCompileTimeError
 generic_methods_overriding_test/01: MissingCompileTimeError # Issue 29920
 generic_methods_recursive_bound_test/02: MissingCompileTimeError
@@ -666,7 +667,6 @@
 flatten_test/12: MissingRuntimeError # Issue 29920
 for_variable_capture_test: RuntimeError # Issue 29920; Expect.equals(expected: <1>, actual: <0>) fails.
 function_subtype_inline2_test: RuntimeError # Expect.fail('Missing type error: 'new C.c1(m2)'.')
-generic_function_type_as_type_argument_test/01: MissingCompileTimeError # Issue 29920
 generic_function_type_as_type_argument_test/02: MissingCompileTimeError # Issue 29920
 generic_instanceof2_test: RuntimeError # Issue 29920; ReferenceError: FooOfK$String is not defined
 generic_is_check_test: RuntimeError # Issue 29920; Expect.isTrue(false) fails.