Report inference err for C<<T>()> for some C and some function with params

Fix #33661

Bug: 33343
Change-Id: I8478a6f0ba3f3d57bcdb3415aa5c9b9a485e4ff2
Reviewed-on: https://dart-review.googlesource.com/64644
Reviewed-by: Jenny Messerly <jmesserly@google.com>
Commit-Queue: Mike Fairhurst <mfairhurst@google.com>
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 3158176..f0c4a9cd 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -215,6 +215,22 @@
         // more errors (e.g. because `dynamic` is the most common bound).
       }
 
+      if (inferred is FunctionType && inferred.typeFormals.isNotEmpty) {
+        errorReporter
+            ?.reportErrorForNode(StrongModeCode.COULD_NOT_INFER, errorNode, [
+          typeParam,
+          ' Inferred candidate type $inferred has type parameters'
+              ' ${(inferred as FunctionType).typeFormals}, but a function with'
+              ' type parameters cannot be used as a type argument.'
+        ]);
+
+        // Heuristic: Using a generic function type as a bound makes subtyping
+        // undecidable. Therefore, we cannot keep [inferred] unless we wish to
+        // generate bogus subtyping errors. Instead generate plain [Function],
+        // which is the most general function type.
+        inferred = typeProvider.functionType;
+      }
+
       if (UnknownInferredType.isKnown(inferred)) {
         knownTypes[typeParam] = inferred;
       }
@@ -828,10 +844,10 @@
    */
   DartType getLeastNullableSupertype(InterfaceType type) {
     // compute set of supertypes
-    List<InterfaceType> s = InterfaceTypeImpl
-        .computeSuperinterfaceSet(type, strong: true)
-        .where(isNullableType)
-        .toList();
+    List<InterfaceType> s =
+        InterfaceTypeImpl.computeSuperinterfaceSet(type, strong: true)
+            .where(isNullableType)
+            .toList();
     return InterfaceTypeImpl.computeTypeAtMaxUniqueDepth(s);
   }
 
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 61c6acf..b0b538a 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
@@ -824,6 +824,27 @@
   @override
   @failingTest
   @potentialAnalyzerProblem
+  test_genericFunctionTypeArgument_inference_function() async {
+    await super.test_genericFunctionTypeArgument_inference_function();
+  }
+
+  @override
+  @failingTest
+  @potentialAnalyzerProblem
+  test_genericFunctionTypeArgument_inference_functionType() async {
+    await super.test_genericFunctionTypeArgument_inference_functionType();
+  }
+
+  @override
+  @failingTest
+  @potentialAnalyzerProblem
+  test_genericFunctionTypeArgument_inference_method() async {
+    await super.test_genericFunctionTypeArgument_inference_method();
+  }
+
+  @override
+  @failingTest
+  @potentialAnalyzerProblem
   test_genericFunctionTypeArgument_method() async {
     await super.test_genericFunctionTypeArgument_method();
   }
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 474e0eb..fb0d657 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -585,16 +585,6 @@
     verify([source]);
   }
 
-  test_builtInIdentifierAsType_dynamicMissingPrefix() async {
-    Source source = addSource(r"""
-import 'dart:core' as core;
-
-dynamic x;
-""");
-    await computeAnalysisResult(source);
-    assertErrors(source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE]);
-  }
-
   test_builtInIdentifierAsMixinName_classTypeAlias() async {
     Source source = addSource(r'''
 class A {}
@@ -621,6 +611,16 @@
     verify([source]);
   }
 
+  test_builtInIdentifierAsType_dynamicMissingPrefix() async {
+    Source source = addSource(r"""
+import 'dart:core' as core;
+
+dynamic x;
+""");
+    await computeAnalysisResult(source);
+    assertErrors(source, [CompileTimeErrorCode.BUILT_IN_IDENTIFIER_AS_TYPE]);
+  }
+
   test_builtInIdentifierAsType_formalParameter_field() async {
     Source source = addSource(r'''
 class A {
@@ -2858,41 +2858,32 @@
     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;
+T f<T>(T t) => null;
 main() { f(<S>(S s) => s); }''');
     await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
+    assertErrors(source, [StrongModeCode.COULD_NOT_INFER]);
     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]);
+    assertErrors(source, [StrongModeCode.COULD_NOT_INFER]);
     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;
+  T f<T>(T t) => null;
 }
 main() { new C().f(<S>(S s) => s); }''');
     await computeAnalysisResult(source);
-    assertErrors(source,
-        [CompileTimeErrorCode.GENERIC_FUNCTION_CANNOT_BE_TYPE_ARGUMENT]);
+    assertErrors(source, [StrongModeCode.COULD_NOT_INFER]);
     verify([source]);
   }
 
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 19d4b8e..4992e56 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -2085,7 +2085,7 @@
   test_forEach_genericFunctionType() async {
     Source source = addSource(r'''
 main() {
-  for (Null Function<T>(T, Null) e in []) {
+  for (Null Function<T>(T, Null) e in <dynamic>[]) {
     e;
   }
 }''');
@@ -3570,6 +3570,32 @@
     verify([source]);
   }
 
+  Future test_issue32114() async {
+    addNamedSource('/a.dart', '''
+class O {}
+
+typedef T Func<T extends O>(T e);
+''');
+    addNamedSource('/b.dart', '''
+import 'a.dart';
+export 'a.dart' show Func;
+
+abstract class A<T extends O> {
+  Func<T> get func;
+}
+''');
+    final Source source = addSource('''
+import 'b.dart';
+
+class B extends A {
+  Func get func => (x) => x;
+}
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   test_issue_24191() async {
     Source source = addSource('''
 import 'dart:async';
@@ -6065,6 +6091,17 @@
     assertNoErrors(source);
   }
 
+  Future test_useDynamicWithPrefix() async {
+    final Source source = addSource('''
+import 'dart:core' as core;
+
+core.dynamic dynamicVariable;
+''');
+    await computeAnalysisResult(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   test_wrongNumberOfParametersForOperator1() async {
     await _check_wrongNumberOfParametersForOperator1("<");
     await _check_wrongNumberOfParametersForOperator1(">");
@@ -6367,43 +6404,6 @@
     verify([source]);
   }
 
-  Future test_issue32114() async {
-    addNamedSource('/a.dart', '''
-class O {}
-
-typedef T Func<T extends O>(T e);
-''');
-    addNamedSource('/b.dart', '''
-import 'a.dart';
-export 'a.dart' show Func;
-
-abstract class A<T extends O> {
-  Func<T> get func;
-}
-''');
-    final Source source = addSource('''
-import 'b.dart';
-
-class B extends A {
-  Func get func => (x) => x;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  Future test_useDynamicWithPrefix() async {
-    final Source source = addSource('''
-import 'dart:core' as core;
-
-core.dynamic dynamicVariable;
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
   Future<Null> _check_wrongNumberOfParametersForOperator(
       String name, String parameters) async {
     Source source = addSource("""
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index 8c33ba2..1ca6def 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -90,7 +90,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/02: MissingCompileTimeError # Issue 30929
 generic_local_functions_test: CompileTimeError # Issue 28515
 generic_methods_generic_function_parameter_test: CompileTimeError # Issue 28515
 generic_no_such_method_dispatcher_simple_test: Skip # This test is just for kernel.
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 92d0df5..b32ddf4 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -368,6 +368,7 @@
 function_type_parameter_negative_test: Fail
 generic_function_bounds_test: RuntimeError
 generic_function_type_as_type_argument_test/01: MissingCompileTimeError # Issue 29920
+generic_function_type_as_type_argument_test/02: 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
@@ -635,7 +636,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/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.
 generic_tearoff_test: CompileTimeError
diff --git a/tests/language_2/tearoff_dynamic_test.dart b/tests/language_2/tearoff_dynamic_test.dart
index 09446e7..c47edf7 100644
--- a/tests/language_2/tearoff_dynamic_test.dart
+++ b/tests/language_2/tearoff_dynamic_test.dart
@@ -110,7 +110,7 @@
   testType([1, 2, 3]);
   testType({'a': 'b'});
   testType((x) => x + 1);
-  testType(testType);
+  testType(testType as dynamic); // illegal inferred type for T otherwise
 }
 
 class N {
@@ -159,7 +159,7 @@
   testType([1, 2, 3]);
   testType({'a': 'b'});
   testType((x) => x + 1);
-  testType(testType);
+  testType(testType as dynamic); // illegal inferred type for T otherwise
 }
 
 main() {