Skip to content

Commit 832f0b0

Browse files
author
John Messerly
committed
fix #27134, future unions in downwards generic method inference
[email protected], [email protected] Review URL: https://codereview.chromium.org/2280463002 .
1 parent 9429183 commit 832f0b0

File tree

4 files changed

+31
-13
lines changed

4 files changed

+31
-13
lines changed

pkg/analyzer/lib/src/generated/resolver.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7260,7 +7260,7 @@ class ResolverVisitor extends ScopedVisitor {
72607260
DartType contextType = node.staticInvokeType;
72617261
if (contextType is FunctionType) {
72627262
DartType originalType = node.function.staticType;
7263-
DartType returnContextType = InferenceContext.getType(node);
7263+
DartType returnContextType = InferenceContext.getContext(node);
72647264
TypeSystem ts = typeSystem;
72657265
if (returnContextType != null &&
72667266
node.typeArguments == null &&

pkg/analyzer/lib/src/generated/static_type_analyzer.dart

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1944,16 +1944,6 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
19441944
}
19451945
}
19461946

1947-
DartType returnContext = InferenceContext.getContext(node);
1948-
DartType returnType;
1949-
if (returnContext is FutureUnionType) {
1950-
returnType = _resolver.isSubtypeOfFuture(fnType.returnType)
1951-
? returnContext.futureOfType
1952-
: returnContext.type;
1953-
} else {
1954-
returnType = returnContext;
1955-
}
1956-
19571947
// Special case Future<T>.then upwards inference. It has signature:
19581948
//
19591949
// <S>(T -> (S | Future<S>)) -> Future<S>
@@ -1991,8 +1981,8 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
19911981
}
19921982
}
19931983
}
1994-
return ts.inferGenericFunctionCall(
1995-
_typeProvider, fnType, paramTypes, argTypes, returnType);
1984+
return ts.inferGenericFunctionCall(_typeProvider, fnType, paramTypes,
1985+
argTypes, InferenceContext.getContext(node));
19961986
}
19971987
return null;
19981988
}

pkg/analyzer/lib/src/generated/type_system.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,16 @@ class StrongTypeSystemImpl extends TypeSystem {
277277
return fnType;
278278
}
279279

280+
// If we're in a future union context, choose either the Future<T> or the T
281+
// based on the function's return type.
282+
if (returnContextType is FutureUnionType) {
283+
var futureUnion = returnContextType as FutureUnionType;
284+
returnContextType =
285+
isSubtypeOf(fnType.returnType, typeProvider.futureDynamicType)
286+
? futureUnion.futureOfType
287+
: futureUnion.type;
288+
}
289+
280290
// Create a TypeSystem that will allow certain type parameters to be
281291
// inferred. It will optimistically assume these type parameters can be
282292
// subtypes (or supertypes) as necessary, and track the constraints that

pkg/analyzer/test/src/task/strong/inferred_type_test.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1676,6 +1676,24 @@ $downwards<int> g3(bool x) async {
16761676
checkFile(build(downwards: "Future", upwards: "MyFuture"));
16771677
}
16781678

1679+
void test_futureUnion_downwardsGenericMethods() {
1680+
// Regression test for https://github.com/dart-lang/sdk/issues/27134
1681+
//
1682+
// We need to take a future union into account for both directions of
1683+
// generic method inference.
1684+
checkFile(r'''
1685+
import 'dart:async';
1686+
1687+
foo() async {
1688+
Future<List<A>> f1 = null;
1689+
Future<List<A>> f2 = null;
1690+
List<List<A>> merged = await Future.wait(/*info:INFERRED_TYPE_LITERAL*/[f1, f2]);
1691+
}
1692+
1693+
class A {}
1694+
''');
1695+
}
1696+
16791697
void test_futureUnion_downwards() {
16801698
String build({String declared, String downwards, String upwards}) {
16811699
// TODO(leafp): The use of matchTypes in visitInstanceCreationExpression

0 commit comments

Comments
 (0)