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() {