fix #31541, DDC/K for async bodies declared to return FutureOr

Change-Id: I3aa1c9bbdfe95fa6f5759f80850ee8d3d6307bce
Reviewed-on: https://dart-review.googlesource.com/35383
Reviewed-by: Vijay Menon <vsm@google.com>
Commit-Queue: Jenny Messerly <jmesserly@google.com>
This commit is contained in:
Jenny Messerly 2018-01-17 21:40:30 +00:00 committed by commit-bot@chromium.org
parent 01e5fcd315
commit 8d48151e16
3 changed files with 14 additions and 13 deletions

View file

@ -6070,15 +6070,16 @@ class CodeGenerator extends Object
return type;
}
}
if (type.isDynamic) {
return type;
} else if (type is InterfaceType && type.element == expectedType.element) {
if (type.isDynamic) return type;
if (type is InterfaceType &&
(type.element == expectedType.element ||
expectedType == types.futureType &&
type.element == types.futureOrType.element)) {
return type.typeArguments[0];
} else {
// TODO(leafp): The above only handles the case where the return type
// is exactly Future/Stream/Iterable. Handle the subtype case.
return DynamicTypeImpl.instance;
}
// TODO(leafp): The above only handles the case where the return type
// is exactly Future/Stream/Iterable. Handle the subtype case.
return DynamicTypeImpl.instance;
}
JS.Expression _callHelper(String code, [args]) {

View file

@ -2768,19 +2768,20 @@ class ProgramCompiler
//
// In the body of an `async`, `await` is generated simply as `yield`.
var gen = emitGeneratorFn((_) => []);
var returnType = _getExpectedReturnType(function, coreTypes.futureClass);
// Return type of an async body is `Future<flatten(T)>`, where T is the
// declared return type.
var returnType = types.unfutureType(function.functionType.returnType);
return js.call('#.async(#, #)',
[emitLibraryName(coreTypes.asyncLibrary), _emitType(returnType), gen])
..sourceInformation = function;
}
// TODO(leafp): Various analyzer pieces computed similar things.
// Share this logic somewhere?
/// Gets the expected return type of a `sync*` or `async*` body.
DartType _getExpectedReturnType(FunctionNode f, Class expected) {
var type = f.functionType.returnType;
if (type is InterfaceType) {
var match = hierarchy.getTypeAsInstanceOf(type, expected);
return match.typeArguments[0];
if (match != null) return match.typeArguments[0];
}
return const DynamicType();
}

View file

@ -143,8 +143,7 @@ async_or_generator_return_type_stacktrace_test/01: MissingCompileTimeError
async_or_generator_return_type_stacktrace_test/02: MissingCompileTimeError
async_or_generator_return_type_stacktrace_test/03: MissingCompileTimeError
async_return_types_test/tooManyTypeParameters: MissingCompileTimeError
async_return_types_test/wrongReturnType: Crash # Maltyped input from Fasta, issue 31414
await_test: Crash # Issue 31541
async_return_types_test/wrongReturnType: MissingCompileTimeError
bad_named_parameters2_test/01: MissingCompileTimeError
bad_named_parameters_test/01: MissingCompileTimeError
bad_named_parameters_test/02: MissingCompileTimeError