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 e86f73a04fe196a71fc9f8fd644ee30c832f4184..60c1dc38273dba72a30c8d92f845a6c6aa5e394a 100644 |
--- a/pkg/analyzer/test/generated/strong_mode_test.dart |
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart |
@@ -955,6 +955,51 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
expect(functionReturnValue(4).staticType, typeProvider.stringType); |
} |
+ test_futureOr_assignFromFuture() async { |
+ // Test a Future<T> can be assigned to FutureOr<T>. |
+ MethodInvocation invoke = await _testFutureOr(r''' |
+ FutureOr<T> mk<T>(Future<T> x) => x; |
+ test() => mk(new Future<int>.value(42)); |
+ '''); |
+ _isFutureOrOfInt(invoke.staticType); |
+ } |
+ |
+ test_futureOr_assignFromValue() async { |
+ // Test a T can be assigned to FutureOr<T>. |
+ MethodInvocation invoke = await _testFutureOr(r''' |
+ FutureOr<T> mk<T>(T x) => x; |
+ test() => mk(42); |
+ '''); |
+ _isFutureOrOfInt(invoke.staticType); |
+ } |
+ |
+ test_futureOr_asyncExpressionBody() async { |
+ // A FutureOr<T> can be used as the expression body for an async function |
+ MethodInvocation invoke = await _testFutureOr(r''' |
+ Future<T> mk<T>(FutureOr<T> x) async => x; |
+ test() => mk(42); |
+ '''); |
+ _isFutureOfInt(invoke.staticType); |
+ } |
+ |
+ test_futureOr_asyncReturn() async { |
+ // A FutureOr<T> can be used as the return value for an async function |
+ MethodInvocation invoke = await _testFutureOr(r''' |
+ Future<T> mk<T>(FutureOr<T> x) async { return x; } |
+ test() => mk(42); |
+ '''); |
+ _isFutureOfInt(invoke.staticType); |
+ } |
+ |
+ test_futureOr_await() async { |
+ // Test a FutureOr<T> can be awaited. |
+ MethodInvocation invoke = await _testFutureOr(r''' |
+ Future<T> mk<T>(FutureOr<T> x) async => await x; |
+ test() => mk(42); |
+ '''); |
+ _isFutureOfInt(invoke.staticType); |
+ } |
+ |
test_futureOr_downwards1() async { |
// Test that downwards inference interacts correctly with FutureOr |
// parameters. |
@@ -1090,51 +1135,6 @@ class StrongModeLocalInferenceTest extends ResolverTestCase { |
_isFutureOf([_isObject])(invoke.staticType); |
} |
- test_futureOr_assignFromValue() async { |
- // Test a T can be assigned to FutureOr<T>. |
- MethodInvocation invoke = await _testFutureOr(r''' |
- FutureOr<T> mk<T>(T x) => x; |
- test() => mk(42); |
- '''); |
- _isFutureOrOfInt(invoke.staticType); |
- } |
- |
- test_futureOr_assignFromFuture() async { |
- // Test a Future<T> can be assigned to FutureOr<T>. |
- MethodInvocation invoke = await _testFutureOr(r''' |
- FutureOr<T> mk<T>(Future<T> x) => x; |
- test() => mk(new Future<int>.value(42)); |
- '''); |
- _isFutureOrOfInt(invoke.staticType); |
- } |
- |
- test_futureOr_await() async { |
- // Test a FutureOr<T> can be awaited. |
- MethodInvocation invoke = await _testFutureOr(r''' |
- Future<T> mk<T>(FutureOr<T> x) async => await x; |
- test() => mk(42); |
- '''); |
- _isFutureOfInt(invoke.staticType); |
- } |
- |
- test_futureOr_asyncExpressionBody() async { |
- // A FutureOr<T> can be used as the expression body for an async function |
- MethodInvocation invoke = await _testFutureOr(r''' |
- Future<T> mk<T>(FutureOr<T> x) async => x; |
- test() => mk(42); |
- '''); |
- _isFutureOfInt(invoke.staticType); |
- } |
- |
- test_futureOr_asyncReturn() async { |
- // A FutureOr<T> can be used as the return value for an async function |
- MethodInvocation invoke = await _testFutureOr(r''' |
- Future<T> mk<T>(FutureOr<T> x) async { return x; } |
- test() => mk(42); |
- '''); |
- _isFutureOfInt(invoke.staticType); |
- } |
- |
test_inference_hints() async { |
Source source = addSource(r''' |
void main () { |
@@ -2756,14 +2756,41 @@ void test() { |
expectIdentifierType('cc', "C<int, B<int>, A<dynamic>>"); |
} |
+ @failingTest |
+ test_instantiateToBounds_class_error_extension_malbounded() async { |
+ // Test that superclasses are strictly checked for malbounded default |
+ // types |
+ String code = r''' |
+class C<T0 extends List<T1>, T1 extends List<T0>> {} |
+class D extends C {} |
+'''; |
+ await resolveTestUnit(code, noErrors: false); |
+ assertErrors(testSource, [StrongModeCode.NO_DEFAULT_BOUNDS]); |
+ } |
+ |
+ @failingTest |
+ test_instantiateToBounds_class_error_instantiation_malbounded() async { |
+ // Test that instance creations are strictly checked for malbounded default |
+ // types |
+ String code = r''' |
+class C<T0 extends List<T1>, T1 extends List<T0>> {} |
+void test() { |
+ var c = new C(); |
+} |
+'''; |
+ await resolveTestUnit(code, noErrors: false); |
+ assertErrors(testSource, [StrongModeCode.NO_DEFAULT_BOUNDS]); |
+ expectIdentifierType('c;', 'C<List<dynamic>, List<dynamic>>'); |
+ } |
+ |
test_instantiateToBounds_class_error_recursion() async { |
String code = r''' |
class C<T0 extends List<T1>, T1 extends List<T0>> {} |
C c; |
'''; |
await resolveTestUnit(code, noErrors: false); |
- assertErrors(testSource, [StrongModeCode.NO_DEFAULT_BOUNDS]); |
- expectIdentifierType('c;', 'C<dynamic, dynamic>'); |
+ assertNoErrors(testSource); |
+ expectIdentifierType('c;', 'C<List<dynamic>, List<dynamic>>'); |
} |
test_instantiateToBounds_class_error_recursion_self() async { |
@@ -2772,8 +2799,8 @@ class C<T extends C<T>> {} |
C c; |
'''; |
await resolveTestUnit(code, noErrors: false); |
- assertErrors(testSource, [StrongModeCode.NO_DEFAULT_BOUNDS]); |
- expectIdentifierType('c;', 'C<dynamic>'); |
+ assertNoErrors(testSource); |
+ expectIdentifierType('c;', 'C<C<dynamic>>'); |
} |
test_instantiateToBounds_class_error_recursion_self2() async { |
@@ -2783,8 +2810,8 @@ class C<T extends A<T>> {} |
C c; |
'''; |
await resolveTestUnit(code, noErrors: false); |
- assertErrors(testSource, [StrongModeCode.NO_DEFAULT_BOUNDS]); |
- expectIdentifierType('c;', 'C<dynamic>'); |
+ assertNoErrors(testSource); |
+ expectIdentifierType('c;', 'C<A<dynamic>>'); |
} |
test_instantiateToBounds_class_error_typedef() async { |
@@ -2794,8 +2821,8 @@ class C<T extends F<T>> {} |
C c; |
'''; |
await resolveTestUnit(code, noErrors: false); |
- assertErrors(testSource, [StrongModeCode.NO_DEFAULT_BOUNDS]); |
- expectIdentifierType('c;', 'C<dynamic>'); |
+ assertNoErrors(testSource); |
+ expectIdentifierType('c;', 'C<(dynamic) → dynamic>'); |
} |
test_instantiateToBounds_class_ok_implicitDynamic_multi() async { |
@@ -2870,6 +2897,22 @@ void main() { |
expectIdentifierType('d;', 'D<A<dynamic>>'); |
} |
+ @failingTest |
+ test_instantiateToBounds_generic_function_error_malbounded() async { |
+ // Test that generic methods are strictly checked for malbounded default |
+ // types |
+ String code = r''' |
+T0 f<T0 extends List<T1>, T1 extends List<T0>>() {} |
+void g() { |
+ var c = f(); |
+ return; |
+} |
+'''; |
+ await resolveTestUnit(code, noErrors: false); |
+ assertErrors(testSource, [StrongModeCode.NO_DEFAULT_BOUNDS]); |
+ expectIdentifierType('c;', 'List<dynamic>'); |
+ } |
+ |
test_instantiateToBounds_method_ok_referenceOther_before() async { |
String code = r''' |
class C<T> { |