| 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
|
|
|