fix #26139, allow inferring a more precise return type

we were losing a lot of information on statement lambdas

R=vsm@google.com

Review URL: https://codereview.chromium.org/2225413002 .
This commit is contained in:
John Messerly
2016-08-09 08:49:24 -07:00
parent 1077b24c31
commit cdcc426f82
3 changed files with 24 additions and 12 deletions
+8 -12
View File
@@ -4719,12 +4719,9 @@ class InferenceContext {
if (_returnStack.isEmpty) {
return;
}
DartType context = _returnStack.last;
if (context == null || context.isDynamic) {
DartType inferred = _inferredReturn.last;
inferred = _typeSystem.getLeastUpperBound(_typeProvider, type, inferred);
_inferredReturn[_inferredReturn.length - 1] = inferred;
}
DartType inferred = _inferredReturn.last;
inferred = _typeSystem.getLeastUpperBound(_typeProvider, type, inferred);
_inferredReturn[_inferredReturn.length - 1] = inferred;
}
/**
@@ -4746,15 +4743,14 @@ class InferenceContext {
* bound of all types added with [addReturnOrYieldType].
*/
void popReturnContext(BlockFunctionBody node) {
assert(_returnStack.isNotEmpty && _inferredReturn.isNotEmpty);
if (_returnStack.isNotEmpty) {
_returnStack.removeLast();
}
if (_inferredReturn.isNotEmpty) {
if (_returnStack.isNotEmpty && _inferredReturn.isNotEmpty) {
DartType context = _returnStack.removeLast() ?? DynamicTypeImpl.instance;
DartType inferred = _inferredReturn.removeLast();
if (!inferred.isBottom) {
if (!inferred.isBottom && _typeSystem.isSubtypeOf(inferred, context)) {
setType(node, inferred);
}
} else {
assert(false);
}
}
@@ -194,6 +194,10 @@ abstract class Iterable<E> {
/*=R*/ fold/*<R>*/(/*=R*/ initialValue,
/*=R*/ combine(/*=R*/ previousValue, E element));
Iterable/*<T>*/ expand/*<T>*/(Iterable/*<T>*/ f(E element));
List<E> toList();
}
class List<E> implements Iterable<E> {
@@ -2554,6 +2554,18 @@ main() {
expect(fns[9].type.toString(), '() → Stream<int>');
}
void test_inferReturnOfStatementLambda() {
// Regression test for https://github.com/dart-lang/sdk/issues/26139
checkFile(r'''
List<String> strings() {
var stuff = [].expand(/*info:INFERRED_TYPE_CLOSURE*/(i) {
return <String>[];
});
return stuff.toList();
}
''');
}
void test_inferred_nonstatic_field_depends_on_static_field_complex() {
var mainUnit = checkFile('''
class C {