Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(38)

Unified Diff: pkg/analyzer/test/generated/strong_mode_test.dart

Issue 2757233004: fix #29108, improve inference error messages (Closed)
Patch Set: rebuild ddc Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer/lib/src/generated/type_system.dart ('k') | pkg/dev_compiler/lib/sdk/ddc_sdk.sum » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer/test/generated/strong_mode_test.dart
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index 89f75d53d953ebbba2cae6afd82c0355bba92fc3..a2600acd223fb761370c23cad88e14dc220f237b 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -1098,6 +1098,176 @@ class StrongModeLocalInferenceTest extends ResolverTestCase {
_isInstantiationOf(_hasElement(elementC))([_isDynamic])(cType);
}
+ test_inference_error_arguments() async {
+ Source source = addSource(r'''
+typedef R F<T, R>(T t);
+
+F<T, T> g<T>(F<T, T> f) => (x) => f(f(x));
+
+test() {
+ var h = g((int x) => 42.0);
+}
+ ''');
+ await computeAnalysisResult(source);
+ _expectInferenceError(
+ source,
+ [
+ StrongModeCode.COULD_NOT_INFER,
+ StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ ],
+ r'''
+Couldn't infer type parameter 'T'.
+
+Tried to infer 'double' for 'T' which doesn't work:
+ Parameter 'f' declared as '(T) → T'
+ but argument is '(int) → double'.
+
+Consider passing explicit type argument(s) to the generic.
+
+''');
+ }
+
+ test_inference_error_arguments2() async {
+ Source source = addSource(r'''
+typedef R F<T, R>(T t);
+
+F<T, T> g<T>(F<T, T> a, F<T, T> b) => (x) => a(b(x));
+
+test() {
+ var h = g((int x) => 42.0, (double x) => 42);
+}
+ ''');
+ await computeAnalysisResult(source);
+ _expectInferenceError(
+ source,
+ [
+ StrongModeCode.COULD_NOT_INFER,
+ StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE,
+ StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ ],
+ r'''
+Couldn't infer type parameter 'T'.
+
+Tried to infer 'num' for 'T' which doesn't work:
+ Parameter 'a' declared as '(T) → T'
+ but argument is '(int) → double'.
+ Parameter 'b' declared as '(T) → T'
+ but argument is '(double) → int'.
+
+Consider passing explicit type argument(s) to the generic.
+
+''');
+ }
+
+ test_inference_error_extendsFromReturn() async {
+ // This is not an inference error because we successfully infer Null.
+ Source source = addSource(r'''
+T max<T extends num>(T x, T y) => x;
+
+test() {
+ String hello = max(1, 2);
+}
+ ''');
+ var analysisResult = await computeAnalysisResult(source);
+ assertErrors(source, [
+ StrongModeCode.INVALID_CAST_LITERAL,
+ StrongModeCode.INVALID_CAST_LITERAL
+ ]);
+ var unit = analysisResult.unit;
+ var h = (AstFinder.getStatementsInTopLevelFunction(unit, "test")[0]
+ as VariableDeclarationStatement)
+ .variables
+ .variables[0];
+ var call = h.initializer as MethodInvocation;
+ expect(call.staticInvokeType.toString(), '(Null, Null) → Null');
+ }
+
+ test_inference_error_extendsFromReturn2() async {
+ Source source = addSource(r'''
+typedef R F<T, R>(T t);
+F<T, T> g<T extends num>() => (y) => y;
+
+test() {
+ F<String, String> hello = g();
+}
+ ''');
+ await computeAnalysisResult(source);
+ _expectInferenceError(
+ source,
+ [
+ StrongModeCode.COULD_NOT_INFER,
+ ],
+ r'''
+Couldn't infer type parameter 'T'.
+
+Tried to infer 'String' for 'T' which doesn't work:
+ Type parameter 'T' declared to extend 'num'.
+The type 'String' was inferred from:
+ Return type declared as '(T) → T'
+ used where '(String) → String' is required.
+
+Consider passing explicit type argument(s) to the generic.
+
+''');
+ }
+
+
+ test_inference_error_genericFunction() async {
+ Source source = addSource(r'''
+T max<T extends num>(T x, T y) => x < y ? y : x;
+abstract class Iterable<T> {
+ T get first;
+ S fold<S>(S s, S f(S s, T t));
+}
+test(Iterable values) {
+ num n = values.fold(values.first as num, max);
+}
+ ''');
+ await computeAnalysisResult(source);
+ _expectInferenceError(
+ source,
+ [
+ StrongModeCode.COULD_NOT_INFER,
+ StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE
+ ],
+ r'''
+Couldn't infer type parameter 'T'.
+
+Tried to infer 'dynamic' for 'T' which doesn't work:
+ Function type declared as '<T extends num>(T, T) → T'
+ used where '(num, dynamic) → num' is required.
+
+Consider passing explicit type argument(s) to the generic.
+
+''');
+ }
+
+ test_inference_error_returnContext() async {
+ Source source = addSource(r'''
+typedef R F<T, R>(T t);
+
+F<T, T> g<T>(T t) => (x) => t;
+
+test() {
+ F<num, int> h = g(42);
+}
+ ''');
+ await computeAnalysisResult(source);
+ _expectInferenceError(
+ source,
+ [StrongModeCode.COULD_NOT_INFER],
+ r'''
+Couldn't infer type parameter 'T'.
+
+Tried to infer 'num' for 'T' which doesn't work:
+ Return type declared as '(T) → T'
+ used where '(num) → int' is required.
+
+Consider passing explicit type argument(s) to the generic.
+
+''');
+ }
+
test_inference_hints() async {
Source source = addSource(r'''
void main () {
@@ -2137,6 +2307,23 @@ num test(Iterable values) => values.fold(values.first as num, max);
check("f3", _isListOf((DartType type) => _isListOf(_isInt)(type)));
}
+ /// Verifies the source has the expected [errorCodes] as well as the
+ /// expected [errorMessage].
+ void _expectInferenceError(
+ Source source, List<ErrorCode> errorCodes, String errorMessage) {
+ assertErrors(source, errorCodes);
+ var errors = analysisResults[source]
+ .errors
+ .where((e) => e.errorCode == StrongModeCode.COULD_NOT_INFER)
+ .map((e) => e.message)
+ .toList();
+ expect(errors.length, 1);
+ var actual = errors[0];
+ expect(actual,
+ errorMessage, // Print the literal error message for easy copy+paste:
+ reason: 'Actual error did not match expected error:\n$actual');
+ }
+
/// Helper method for testing `FutureOr<T>`.
///
/// Validates that [code] produces [errors]. It should define a function
« no previous file with comments | « pkg/analyzer/lib/src/generated/type_system.dart ('k') | pkg/dev_compiler/lib/sdk/ddc_sdk.sum » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698