blob: 663fdf45fbb533901afdc50629a2924853582c64 [file] [log] [blame]
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// This test verifies that for an async method, the following three
// types are all appropriately matched:
// - The static return type
// - The return type of reified runtime type of a tearoff of the function or
// method
// - The reified type of the future returned by the function or method
// Specific attention is paid to the following conditions:
// - The static return type is determined by type inference
// - The static return type is `dynamic`
// - The function or method immediately returns a value or future with a
// different type (possibly using `=>` syntax)
import 'dart:async';
import 'package:expect/expect.dart';
class A {}
class B extends A {}
Future quick() async {}
Future<B> futureB() => new Future<B>.value(new B());
abstract class I {
dynamic f_inferred_dynamic();
Future<A> f_inferred_A();
class C implements I {
f_inferred_dynamic() async {
await quick();
return new B();
f_inferred_A() async {
await quick();
return new B();
dynamic f_dynamic() async {
await quick();
return new B();
Future<A> f_A() async {
await quick();
return new B();
Future<A> f_immediateReturn_B() async {
return new B();
Future<A> f_immediateReturn_FutureB() async {
return futureB();
Future<A> f_expressionSyntax_B() async => new B();
Future<A> f_expressionSyntax_FutureB() async => futureB();
// Not executed
void checkStaticTypes(C c) {
// Check that f_inferred_dynamic's static return type is `dynamic`, by
// verifying that no error occurs if we try to call `foo` on its return value.
// Check that f_inferred_A's static return type is `Future<A>`, by verifying
// that its return value can be assigned to `Future<A>` but not
// `Future<B>`.
Future<A> v1 = c.f_inferred_A();
Future<B> v2 = c.f_inferred_A();
// ^^^^^^^^^^^^^^^^
// ^
// [cfe] A value of type 'Future<A>' can't be assigned to a variable of type 'Future<B>'.
void checkDynamic(dynamic tearoff) {
Expect.isTrue(tearoff is dynamic Function());
Expect.isFalse(tearoff is Future<dynamic> Function());
dynamic f = tearoff();
Expect.isTrue(f is Future<dynamic>);
Expect.isFalse(f is Future<A>);
void checkFutureA(dynamic tearoff) {
Expect.isTrue(tearoff is Future<A> Function());
Expect.isFalse(tearoff is Future<B> Function());
dynamic f = tearoff();
Expect.isTrue(f is Future<A>);
Expect.isFalse(f is Future<B>);
void test(C c) {
main() {
test(new C());