| Index: pkg/compiler/lib/src/ssa/builder.dart
|
| diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
|
| index 13350ca4400098b06c50736383263ede3859390c..c67afb43fafc5ca3fafa673473625c65c1d21280 100644
|
| --- a/pkg/compiler/lib/src/ssa/builder.dart
|
| +++ b/pkg/compiler/lib/src/ssa/builder.dart
|
| @@ -1058,6 +1058,13 @@ class SsaBuilder extends ResolvedVisitor {
|
| // We build the Ssa graph by simulating a stack machine.
|
| List<HInstruction> stack = <HInstruction>[];
|
|
|
| + /// Returns `true` if the current element is an `async` function.
|
| + bool get isBuildingAsyncFunction {
|
| + Element element = sourceElement;
|
| + return (element is FunctionElement &&
|
| + element.asyncMarker == AsyncMarker.ASYNC);
|
| + }
|
| +
|
| SsaBuilder(JavaScriptBackend backend,
|
| CodegenWorkItem work,
|
| this.nativeEmitter,
|
| @@ -5179,6 +5186,28 @@ class SsaBuilder extends ResolvedVisitor {
|
| emitReturn(value, node);
|
| }
|
|
|
| + /// Returns true if the [type] is a valid return type for an asynchronous
|
| + /// function.
|
| + ///
|
| + /// Asynchronous functions return a `Future`, and a valid return is thus
|
| + /// either dynamic, Object, or Future.
|
| + ///
|
| + /// We do not accept the internal Future implementation class.
|
| + bool isValidAsyncReturnType(DartType type) {
|
| + assert (isBuildingAsyncFunction);
|
| + // TODO(sigurdm): In an internal library a function could be declared:
|
| + //
|
| + // _FutureImpl foo async => 1;
|
| + //
|
| + // This should be valid (because the actual value returned from an async
|
| + // function is a `_FutureImpl`), but currently false is returned in this
|
| + // case.
|
| + return type.isDynamic ||
|
| + type.isObject ||
|
| + (type is InterfaceType &&
|
| + type.element == compiler.futureClass);
|
| + }
|
| +
|
| visitReturn(ast.Return node) {
|
| if (identical(node.beginToken.stringValue, 'native')) {
|
| native.handleSsaNative(this, node.expression);
|
| @@ -5190,7 +5219,19 @@ class SsaBuilder extends ResolvedVisitor {
|
| } else {
|
| visit(node.expression);
|
| value = pop();
|
| - value = potentiallyCheckOrTrustType(value, returnType);
|
| + if (isBuildingAsyncFunction) {
|
| + if (compiler.enableTypeAssertions &&
|
| + !isValidAsyncReturnType(returnType)) {
|
| + String message =
|
| + "Async function returned a Future, "
|
| + "was declared to return a $returnType.";
|
| + generateTypeError(node, message);
|
| + pop();
|
| + return;
|
| + }
|
| + } else {
|
| + value = potentiallyCheckOrTrustType(value, returnType);
|
| + }
|
| }
|
|
|
| handleInTryStatement();
|
|
|