diff --git a/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart b/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart index 73430bb86f3..4736c9a3fa6 100644 --- a/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart +++ b/pkg/analyzer/test/src/diagnostics/could_not_infer_test.dart @@ -15,6 +15,74 @@ main() { @reflectiveTest class CouldNotInferTest extends DriverResolutionTest { + test_constructors_inferenceFBounded() async { + await assertErrorsInCode(''' +class C {} + +class P, U extends C> { + T t; + U u; + P(this.t, this.u); + P._(); + P get reversed => new P(u, t); +} + +main() { + P._(); +} +''', [ + error(CompileTimeErrorCode.COULD_NOT_INFER, 154, 3), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 154, 1), + error(CompileTimeErrorCode.COULD_NOT_INFER, 154, 3), + ]); + } + + test_constructors_inferFromArguments_argumentNotAssignable() async { + await assertErrorsInCode(''' +class A {} + +typedef T F(); + +class C { + C(F f); +} + +class NotA {} +NotA myF() => null; + +main() { + var x = C(myF); +} +''', [ + error(HintCode.UNUSED_LOCAL_VARIABLE, 120, 1), + error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 124, 1), + error(CompileTimeErrorCode.COULD_NOT_INFER, 124, 1), + ]); + } + + test_downwardInference_fixes_noUpwardsErrors() async { + await assertErrorsInCode(r''' +import 'dart:math'; +// T max(T x, T y); +main() { + num x; + dynamic y; + + num a = max(x, y); + Object b = max(x, y); + dynamic c = max(x, y); + var d = max(x, y); +} +''', [ + error(HintCode.UNUSED_LOCAL_VARIABLE, 93, 1), + error(HintCode.UNUSED_LOCAL_VARIABLE, 117, 1), + error(HintCode.UNUSED_LOCAL_VARIABLE, 142, 1), + error(CompileTimeErrorCode.COULD_NOT_INFER, 146, 3), + error(HintCode.UNUSED_LOCAL_VARIABLE, 163, 1), + error(CompileTimeErrorCode.COULD_NOT_INFER, 167, 3), + ]); + } + test_function() async { await assertErrorsInCode(r''' T f(T t) => null; @@ -25,7 +93,7 @@ main() { f((S s) => s); } } test_functionType() async { - await assertErrorsInCode(r''' + await assertErrorsInCode(''' T Function(T) f; main() { f((S s) => s); } ''', [ @@ -33,6 +101,141 @@ main() { f((S s) => s); } ]); } + test_functionType_allSameSubtype() async { + await assertNoErrorsInCode(r''' +external T f(T a, T b); +void g(int cb(int a, int b)) {} +void main() { + g(f); +} +'''); + } + + test_functionType_parameterIsBound_returnIsBound() async { + await assertNoErrorsInCode(r''' +external T f(T a, T b); +void g(num cb(num a, num b)) {} +void main() { + g(f); +} +'''); + } + + test_functionType_parameterIsObject_returnIsBound() async { + await assertErrorsInCode(''' +external T f(T a, T b); +void g(num cb(Object a, Object b)) {} +void main() { + g(f); +} +''', [ + error(CompileTimeErrorCode.COULD_NOT_INFER, 95, 1), + error(CompileTimeErrorCode.INVALID_CAST_FUNCTION, 95, 1), + ]); + } + + test_functionType_parameterIsObject_returnIsBound_prefixedFunction() async { + newFile('/test/lib/a.dart', content: ''' +external T f(T a, T b); +'''); + await assertErrorsInCode(''' +import 'a.dart' as a; +void g(num cb(Object a, Object b)) {} +void main() { + g(a.f); +} +''', [ + error(CompileTimeErrorCode.COULD_NOT_INFER, 78, 3), + error(CompileTimeErrorCode.INVALID_CAST_FUNCTION, 78, 3), + ]); + } + + test_functionType_parameterIsObject_returnIsSubtype() async { + await assertErrorsInCode(''' +external T f(T a, T b); +void g(int cb(Object a, Object b)) {} +void main() { + g(f); +} +''', [ + error(CompileTimeErrorCode.COULD_NOT_INFER, 95, 1), + error(CompileTimeErrorCode.INVALID_CAST_FUNCTION, 95, 1), + ]); + } + + test_functionType_parameterIsObject_returnIsSubtype_tearOff() async { + await assertErrorsInCode(''' +class C { + T m(T x, T y) { + throw 'error'; + } +} +void g(int cb(Object a, Object b)) {} +void main() { + g(C().m); +} +''', [ + error(CompileTimeErrorCode.COULD_NOT_INFER, 124, 5), + ]); + } + + test_functionType_parameterIsSubtype_returnIsBound() async { + await assertNoErrorsInCode(r''' +external T f(T a, T b); +void g(num cb(int a, int b)) {} +void main() { + g(f); +} +'''); + } + + test_functionType_parameterIsSubtype_returnIsObject() async { + await assertNoErrorsInCode(''' +external T f(T a, T b); +void g(Object cb(int a, int b)) {} +void main() { + g(f); +} +'''); + } + + test_functionType_parametersAreSubtypes_returnIsBound() async { + await assertNoErrorsInCode(''' +external T f(T a, T b); +void g(num cb(int a, double b)) {} +void main() { + g(f); +} +'''); + } + + test_functionType_parametersAreSubtypes_returnIsOne() async { + await assertErrorsInCode(''' +external T f(T a, T b); +void g(int cb(int a, double b)) {} +void main() { + g(f); +} +''', [ + error(CompileTimeErrorCode.COULD_NOT_INFER, 92, 1), + error(CompileTimeErrorCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, 92, 1), + ]); + } + + test_genericMethods_correctlyRecognizeGenericUpperBound() async { + // Regression test for https://github.com/dart-lang/sdk/issues/25740. + await assertErrorsInCode(r''' +class Foo { + U method(U u) => u; +} +main() { + new Foo()./*error:COULD_NOT_INFER*/method(42); +} +''', [ + error(CompileTimeErrorCode.COULD_NOT_INFER, 122, 6), + ]); + } + test_method() async { await assertErrorsInCode(r''' class C { diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart index c5d902ad10f..0ec1da6767e 100644 --- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart +++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart @@ -393,29 +393,6 @@ void main() { '''); } - test_constructors_inferenceFBounded() async { - var errors = 'error:COULD_NOT_INFER,error:COULD_NOT_INFER,' - 'error:TYPE_ARGUMENT_NOT_MATCHING_BOUNDS'; -// if (hasExtraTaskModelPass) errors = '$errors,$errors'; - var unit = await checkFile(''' -class Cloneable {} - -class Pair, U extends Cloneable> { - T t; - U u; - Pair(this.t, this.u); - Pair._(); - Pair get reversed => new Pair(u, t); -} - -main() { - final x = new /*$errors*/Pair._(); -} -'''); - var x = findLocalVariable(unit, 'x'); - _assertTypeStr(x.type, 'Pair, Cloneable>'); - } - test_constructors_inferFromArguments() async { var unit = await checkFile(''' class C { @@ -445,28 +422,6 @@ main() { _assertTypeStr(findLocalVariable(unit, 'c_dynamic').type, 'C'); } - test_constructors_inferFromArguments_argumentNotAssignable() async { - var unit = await checkFile(''' -class A {} - -typedef T F(); - -class C { - C(F f); -} - -class NotA {} -NotA myF() => null; - -main() { - var x = new - /*error:COULD_NOT_INFER,error:TYPE_ARGUMENT_NOT_MATCHING_BOUNDS*/C(myF); -} -'''); - var x = findLocalVariable(unit, 'x'); - _assertTypeStr(x.type, 'C'); - } - test_constructors_inferFromArguments_const() async { var unit = await checkFile(''' class C { @@ -713,21 +668,6 @@ test() { '''); } - test_downwardInference_fixes_noUpwardsErrors() async { - await checkFileElement(r''' -import 'dart:math'; -// T max(T x, T y); -main() { - num x; - dynamic y; - - num a = max(x, y); - Object b = max(x, y); - dynamic c = /*error:COULD_NOT_INFER*/max(x, y); - var d = /*error:COULD_NOT_INFER*/max(x, y); -}'''); - } - test_downwardInference_miscellaneous() async { await checkFileElement(''' typedef T Function2(S x); @@ -1738,18 +1678,6 @@ main() { '''); } - test_genericMethods_correctlyRecognizeGenericUpperBound() async { - // Regression test for https://github.com/dart-lang/sdk/issues/25740. - await checkFileElement(r''' -class Foo { - U method(U u) => u; -} -main() { - new Foo()./*error:COULD_NOT_INFER*/method(42); -} -'''); - } - test_genericMethods_dartMathMinMax() async { await checkFileElement(''' import 'dart:math'; @@ -1900,100 +1828,6 @@ typedef V F(); _assertTypeStr(f.type, 'U Function() Function(U)'); } - test_genericMethods_inferGenericInstantiation() async { - await checkFileElement(''' -import 'dart:math' as math; -import 'dart:math' show min; - -class C { -T m(T x, T y) => null; -} - -main() { -takeIII(math.max); -takeDDD(math.max); -takeNNN(math.max); -takeIDN(math.max); -takeDIN(math.max); -takeIIN(math.max); -takeDDN(math.max); -takeIIO(math.max); -takeDDO(math.max); - -takeOOI(/*error:COULD_NOT_INFER,error:INVALID_CAST_FUNCTION*/math.max); -takeIDI(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max); -takeDID(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/math.max); -takeOON(/*error:COULD_NOT_INFER,error:INVALID_CAST_FUNCTION*/math.max); -takeOOO(/*error:COULD_NOT_INFER,error:INVALID_CAST_FUNCTION*/math.max); - -// Also test SimpleIdentifier -takeIII(min); -takeDDD(min); -takeNNN(min); -takeIDN(min); -takeDIN(min); -takeIIN(min); -takeDDN(min); -takeIIO(min); -takeDDO(min); - -takeOOI(/*error:COULD_NOT_INFER,error:INVALID_CAST_FUNCTION*/min); -takeIDI(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min); -takeDID(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/min); -takeOON(/*error:COULD_NOT_INFER,error:INVALID_CAST_FUNCTION*/min); -takeOOO(/*error:COULD_NOT_INFER,error:INVALID_CAST_FUNCTION*/min); - -// Also PropertyAccess -takeIII(new C().m); -takeDDD(new C().m); -takeNNN(new C().m); -takeIDN(new C().m); -takeDIN(new C().m); -takeIIN(new C().m); -takeDDN(new C().m); -takeIIO(new C().m); -takeDDO(new C().m); - -// Note: this is a warning because a downcast of a method tear-off could work -// (derived method can be a subtype): -// -// class D extends C { -// S m(Object x, Object y); -// } -// -// That's legal because we're loosening parameter types. -// -// We do issue the inference error though, similar to generic function calls. -takeOON(/*error:COULD_NOT_INFER*/new C().m); -takeOOO(/*error:COULD_NOT_INFER*/new C().m); - -// Note: this is a warning because a downcast of a method tear-off could work -// in "normal" Dart, due to bivariance. -// -// We do issue the inference error though, similar to generic function calls. -takeOOI(/*error:COULD_NOT_INFER*/new C().m); - -takeIDI(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m); -takeDID(/*error:COULD_NOT_INFER,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/new C().m); -} - -void takeIII(int fn(int a, int b)) {} -void takeDDD(double fn(double a, double b)) {} -void takeIDI(int fn(double a, int b)) {} -void takeDID(double fn(int a, double b)) {} -void takeIDN(num fn(double a, int b)) {} -void takeDIN(num fn(int a, double b)) {} -void takeIIN(num fn(int a, int b)) {} -void takeDDN(num fn(double a, double b)) {} -void takeNNN(num fn(num a, num b)) {} -void takeOON(num fn(Object a, Object b)) {} -void takeOOO(num fn(Object a, Object b)) {} -void takeOOI(int fn(Object a, Object b)) {} -void takeIIO(Object fn(int a, int b)) {} -void takeDDO(Object fn(double a, double b)) {} -'''); - } - test_genericMethods_inferGenericMethodType() async { // Regression test for https://github.com/dart-lang/sdk/issues/25668 await checkFileElement('''