From 8d48151e16f04dd8ec7a06e4537a5ac815479ce7 Mon Sep 17 00:00:00 2001 From: Jenny Messerly Date: Wed, 17 Jan 2018 21:40:30 +0000 Subject: [PATCH] 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 Commit-Queue: Jenny Messerly --- .../lib/src/analyzer/code_generator.dart | 15 ++++++++------- pkg/dev_compiler/lib/src/kernel/compiler.dart | 9 +++++---- tests/language_2/language_2_dartdevc.status | 3 +-- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart index d08f1e3fddd..d8cf050c873 100644 --- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart +++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart @@ -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]) { diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart index f1f76612918..429846f5eb1 100644 --- a/pkg/dev_compiler/lib/src/kernel/compiler.dart +++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart @@ -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`, 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(); } diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status index 2e88f06b930..5b61bb5ff07 100644 --- a/tests/language_2/language_2_dartdevc.status +++ b/tests/language_2/language_2_dartdevc.status @@ -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