Remove deep future flattening from analyzer and DDC

Change-Id: Ic48f29adec3a46744b259ba5b2b8ad7d97caa6c2
Reviewed-on: https://dart-review.googlesource.com/37424
Reviewed-by: Jenny Messerly <jmesserly@google.com>
This commit is contained in:
Leaf Petersen 2018-01-30 18:11:11 +00:00
parent ec6eb06d2f
commit 991753313f
9 changed files with 16 additions and 58 deletions

View file

@ -11,6 +11,19 @@
#### Strong Mode
* Future flattening is now done only as specified in the Dart 2.0 spec, rather
than more broadly. This means that the following code will now have an error on
the assignment to `y`.
```dart
test() {
Future<int> f;
var x = f.then<Future<List<int>>>((x) => []);
Future<List<int>> y = x;
}
```
### Core library changes
* `dart:async`

View file

@ -2127,33 +2127,6 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
return this;
}
if (isDartAsyncFuture && newTypeArguments.isNotEmpty) {
//
// In strong mode interpret Future< T > as Future< flatten(T) >
//
// For example, Future<Future<T>> will flatten to Future<T>.
//
// In the Dart 3rd edition spec, this flatten operation is used for
// `async` and `await`. In strong mode, we extend it to all Future<T>
// instantiations. This allows typing of Future-related operations
// in dart:async in a way that matches their runtime behavior and provides
// precise return types for users of these APIs.
//
// For example:
//
// abstract class Future<T> {
// Future<S> then<S>(S onValue(T value), ...);
// }
//
// Given a call where S <: Future<R> for some R, we will need to flatten
// the return type so it is Future< flatten(S) >, yielding Future<R>.
//
if (element.library.context.analysisOptions.strongMode) {
TypeImpl t = newTypeArguments[0];
newTypeArguments[0] = t.flattenFutures(new StrongTypeSystemImpl(null));
}
}
InterfaceTypeImpl newType = new InterfaceTypeImpl(element, prune);
newType.typeArguments = newTypeArguments;
return newType;

View file

@ -1642,7 +1642,7 @@ m1() {
Future<int> f;
var x = f.then<Future<List<int>>>(/*info:INFERRED_TYPE_CLOSURE*/
(x) => /*error:RETURN_OF_INVALID_TYPE_FROM_CLOSURE*/[]);
Future<List<int>> y = x;
Future<List<int>> y = /*error:INVALID_ASSIGNMENT*/x;
}
m2() {
Future<int> f;

View file

@ -1232,10 +1232,6 @@ class CodeGenerator extends Object
var genericCall = _callHelper('generic(#)', [genericArgs]);
if (element.library.isDartAsync &&
(element.name == "Future" || element.name == "_Future")) {
genericCall = _callHelper('flattenFutures(#)', [genericCall]);
}
var genericName = _emitTopLevelNameNoInterop(element, suffix: '\$');
return js.statement('{ # = #; # = #(); }',
[genericName, genericCall, _emitTopLevelName(element), genericName]);

View file

@ -579,10 +579,6 @@ class ProgramCompiler
var genericCall = _callHelper('generic(#)', [genericArgs]);
if (getLibrary(c) == coreTypes.asyncLibrary &&
(name == "Future" || name == "_Future")) {
genericCall = _callHelper('flattenFutures(#)', [genericCall]);
}
var genericName = _emitTopLevelNameNoInterop(c, suffix: '\$');
return js.statement('{ # = #; # = #(); }',
[genericName, genericCall, _emitTopLevelName(c), genericName]);

View file

@ -58,24 +58,6 @@ final _originalDeclaration = JS('', 'Symbol("originalDeclaration")');
final mixinNew = JS('', 'Symbol("dart.mixinNew")');
/// Wrap a generic class builder function with future flattening.
flattenFutures(builder) => JS('', '''(() => {
function flatten(T) {
if (!T) return $builder($dynamic);
let futureClass = $getGenericClass($Future);
//TODO(leafp): This only handles the direct flattening case.
// It would probably be good to at least search up the class
// hierarchy. If we keep doing flattening long term, we may
// want to implement the full future flattening per spec.
if ($getGenericClass(T) == futureClass) {
let args = $getGenericArgs(T);
if (args) return $builder(args[0]);
}
return $builder(T);
}
return flatten;
})()''');
/// Memoize a generic type constructor function.
generic(typeConstructor, setBaseClass) => JS('', '''(() => {
let length = $typeConstructor.length;

View file

@ -282,7 +282,7 @@ class MockCompiler extends Compiler {
}
/// Create a new [MockCompiler] and apply it asynchronously to [f].
static Future<T> create<T>(T f(MockCompiler compiler)) {
static Future<T> create<T>(FutureOr<T> f(MockCompiler compiler)) {
MockCompiler compiler = new MockCompiler.internal();
return compiler.init().then((_) => f(compiler));
}

View file

@ -8,7 +8,6 @@ abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeE
abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError # Issue #30568
abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError # Issue #30568
assertion_initializer_const_function_test/01: MissingCompileTimeError
async_return_types_test/nestedFuture: MissingCompileTimeError
bad_initializer2_negative_test: Fail # Issue 14880
black_listed_test/none: Fail # Issue 14228
built_in_identifier_prefix_test: CompileTimeError
@ -1228,7 +1227,6 @@ accessor_conflict_import_test: CompileTimeError # Issue 25626
additional_interface_adds_optional_args_test: CompileTimeError # Issue #30568
assertion_initializer_const_function_test/01: MissingStaticWarning
assertion_initializer_test: CompileTimeError
async_return_types_test/nestedFuture: MissingCompileTimeError
cascaded_forwarding_stubs_test: CompileTimeError
config_import_corelib_test: CompileTimeError
const_types_test/07: MissingCompileTimeError # Incorrectly allows using type parameter in const expression.

View file

@ -343,6 +343,7 @@ async_await_syntax_test/d10a: MissingCompileTimeError
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/nestedFuture: MissingCompileTimeError
async_return_types_test/tooManyTypeParameters: MissingCompileTimeError
async_return_types_test/wrongReturnType: MissingCompileTimeError
bad_named_parameters2_test/01: MissingCompileTimeError
@ -1030,7 +1031,6 @@ truncdiv_test: RuntimeError # Issue 29920; Expect.throws fails: Did not throw
abstract_override_adds_optional_args_concrete_subclass_test: MissingCompileTimeError # Issue #30568
abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError # Issue #30568
abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError # Issue #30568
async_return_types_test/nestedFuture: MissingCompileTimeError
bit_operations_test/01: MissingCompileTimeError
bit_operations_test/02: MissingCompileTimeError
built_in_identifier_prefix_test: CompileTimeError