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

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

Issue 2757233004: fix #29108, improve inference error messages (Closed)
Patch Set: 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') | no next file » | 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..534655d022fa6fdbaccea7c6dc278937d2ff499e 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' but it did not work:
Leaf 2017/03/20 22:46:55 <bikeshed> "it did not work" feels a bit clunky to
Jennifer Messerly 2017/03/21 01:08:08 Done.
+ Argument 'f' inferred as '(int) → double'
Leaf 2017/03/20 22:46:55 The key to this section is making it absolutely 10
Jennifer Messerly 2017/03/21 01:08:36 oops! also I did this one too. Forgot to save comm
+ must be a '(T) → T'.
Jennifer Messerly 2017/03/20 22:03:27 should we show this as (double) → double? ... it'
+
+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' but it did not work:
+ Argument 'a' inferred as '(int) → double'
+ must be a '(T) → T'.
+ Argument 'b' inferred as '(double) → int'
+ must be a '(T) → T'.
+
+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' but it did not work:
+ Type parameter 'T' declared to extend 'num'.
Jennifer Messerly 2017/03/20 22:03:27 like I feel this one is pretty good, but YMMV
Leaf 2017/03/20 22:46:55 Agreed.
+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' but it did not 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' but it did not 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') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698