fix #27151, list and map literals infer using up and down info

R=leafp@google.com

Review URL: https://codereview.chromium.org/2343713002 .
This commit is contained in:
John Messerly
2016-09-14 16:35:26 -07:00
parent 87dcad607e
commit 79a9409f75
8 changed files with 206 additions and 167 deletions
+1 -1
View File
@@ -7282,7 +7282,7 @@ class ResolverVisitor extends ScopedVisitor {
originalType.typeFormals.isNotEmpty &&
ts is StrongTypeSystemImpl) {
contextType = ts.inferGenericFunctionCall(typeProvider, originalType,
DartType.EMPTY_LIST, DartType.EMPTY_LIST, returnContextType);
DartType.EMPTY_LIST, DartType.EMPTY_LIST, originalType.returnType, returnContextType);
}
InferenceContext.setType(node.argumentList, contextType);
@@ -623,46 +623,45 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
return null;
}
DartType listDynamicType =
_typeProvider.listType.instantiate(<DartType>[_dynamicType]);
// If there are no type arguments and we are in strong mode, try to infer
// some arguments.
if (_strongMode) {
DartType contextType = InferenceContext.getType(node);
// If we have a type from the context, use it.
if (contextType is InterfaceType &&
contextType.typeArguments.length == 1 &&
contextType.element == _typeProvider.listType.element) {
_resolver.inferenceContext.recordInference(node, contextType);
_recordStaticType(node, contextType);
return null;
}
// Use both downwards and upwards information to infer the type.
var ts = _typeSystem as StrongTypeSystemImpl;
var elementTypes = node.elements
.map((e) => e.staticType)
.where((t) => t != null)
.toList();
var listTypeParam = _typeProvider.listType.typeParameters[0].type;
// If we don't have a type from the context, try to infer from the
// elements
if (node.elements.isNotEmpty) {
// Infer the list type from the arguments.
Iterable<DartType> types =
node.elements.map((e) => e.staticType).where((t) => t != null);
if (types.isEmpty) {
return null;
}
DartType staticType = types.reduce(_leastUpperBound);
if (staticType.isBottom) {
staticType = _dynamicType;
}
DartType listLiteralType =
_typeProvider.listType.instantiate(<DartType>[staticType]);
if (!staticType.isDynamic) {
_resolver.inferenceContext.recordInference(node, listLiteralType);
}
_recordStaticType(node, listLiteralType);
DartType inferred = ts.inferGenericFunctionCall(
_typeProvider,
_typeProvider.listType,
new List.filled(elementTypes.length, listTypeParam),
elementTypes,
_typeProvider.listType,
contextType,
errorReporter: _resolver.errorReporter,
errorNode: node);
if (inferred != listDynamicType) {
// TODO(jmesserly): this results in an "inferred" message even when we
// in fact had an error above, because it will still attempt to return
// a type. Perhaps we should record inference from TypeSystem if
// everything was successful?
_resolver.inferenceContext.recordInference(node, inferred);
_recordStaticType(node, inferred);
return null;
}
}
// If we have no type arguments and couldn't infer any, use dynamic.
_recordStaticType(
node, _typeProvider.listType.instantiate(<DartType>[_dynamicType]));
_recordStaticType(node, listDynamicType);
return null;
}
@@ -682,6 +681,9 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
Object visitMapLiteral(MapLiteral node) {
TypeArgumentList typeArguments = node.typeArguments;
DartType mapDynamicType = _typeProvider.mapType
.instantiate(<DartType>[_dynamicType, _dynamicType]);
// If we have type arguments, use them
if (typeArguments != null) {
DartType staticKeyType = _dynamicType;
@@ -710,43 +712,40 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
// then try to infer type arguments.
if (_strongMode) {
DartType contextType = InferenceContext.getType(node);
// If we have a context type, use that for inference.
if (contextType is InterfaceType &&
contextType.typeArguments.length == 2 &&
contextType.element == _typeProvider.mapType.element) {
_resolver.inferenceContext.recordInference(node, contextType);
_recordStaticType(node, contextType);
return null;
}
// Otherwise, try to infer a type from the keys and values.
if (node.entries.isNotEmpty) {
DartType staticKeyType =
node.entries.map((e) => e.key.staticType).reduce(_leastUpperBound);
DartType staticValueType = node.entries
.map((e) => e.value.staticType)
.reduce(_leastUpperBound);
if (staticKeyType.isBottom) {
staticKeyType = _dynamicType;
}
if (staticValueType.isBottom) {
staticValueType = _dynamicType;
}
DartType mapLiteralType = _typeProvider.mapType
.instantiate(<DartType>[staticKeyType, staticValueType]);
if (!(staticValueType.isDynamic && staticKeyType.isDynamic)) {
_resolver.inferenceContext.recordInference(node, mapLiteralType);
}
_recordStaticType(node, mapLiteralType);
// Use both downwards and upwards information to infer the type.
var ts = _typeSystem as StrongTypeSystemImpl;
var keyTypes =
node.entries.map((e) => e.key.staticType).where((t) => t != null);
var valueTypes =
node.entries.map((e) => e.value.staticType).where((t) => t != null);
var keyTypeParam = _typeProvider.mapType.typeParameters[0].type;
var valueTypeParam = _typeProvider.mapType.typeParameters[1].type;
DartType inferred = ts.inferGenericFunctionCall(
_typeProvider,
_typeProvider.mapType,
new List.filled(keyTypes.length, keyTypeParam, growable: true)
..addAll(new List.filled(valueTypes.length, valueTypeParam)),
new List.from(keyTypes)..addAll(valueTypes),
_typeProvider.mapType,
contextType,
errorReporter: _resolver.errorReporter,
errorNode: node);
if (inferred != mapDynamicType) {
// TODO(jmesserly): this results in an "inferred" message even when we
// in fact had an error above, because it will still attempt to return
// a type. Perhaps we should record inference from TypeSystem if
// everything was successful?
_resolver.inferenceContext.recordInference(node, inferred);
_recordStaticType(node, inferred);
return null;
}
}
// If no type arguments and no inference, use dynamic
_recordStaticType(
node,
_typeProvider.mapType
.instantiate(<DartType>[_dynamicType, _dynamicType]));
_recordStaticType(node, mapDynamicType);
return null;
}
@@ -1986,7 +1985,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
}
}
return ts.inferGenericFunctionCall(_typeProvider, fnType, paramTypes,
argTypes, InferenceContext.getContext(node),
argTypes, fnType.returnType, InferenceContext.getContext(node),
errorReporter: _resolver.errorReporter, errorNode: errorNode);
}
return null;
@@ -2250,14 +2249,6 @@ class StaticTypeAnalyzer extends SimpleAstVisitor<Object> {
parent.operator.type == TokenType.PERIOD);
}
/**
* Computes the least upper bound between two types.
*
* See [TypeSystem.getLeastUpperBound].
*/
DartType _leastUpperBound(DartType s, DartType t) =>
_typeSystem.getLeastUpperBound(_typeProvider, s, t);
/**
* Record that the propagated type of the given node is the given type.
*
+32 -24
View File
@@ -363,7 +363,8 @@ class StrongTypeSystemImpl extends TypeSystem {
}
// Try to infer and instantiate the resulting type.
var resultType = inferringTypeSystem._infer(fnType);
var resultType = inferringTypeSystem._infer(
fnType, fnType.typeFormals, fnType.returnType);
// If the instantiation failed (because some type variable constraints
// could not be solved, in other words, we could not find a valid subtype),
@@ -393,26 +394,21 @@ class StrongTypeSystemImpl extends TypeSystem {
/// As a simplification, we do not actually store all constraints on each type
/// parameter Tj. Instead we track Uj and Lj where U is the upper bound and
/// L is the lower bound of that type parameter.
FunctionType inferGenericFunctionCall(
/*=T*/ inferGenericFunctionCall/*<T extends ParameterizedType>*/(
TypeProvider typeProvider,
FunctionType fnType,
List<DartType> correspondingParameterTypes,
/*=T*/ genericType,
List<DartType> declaredParameterTypes,
List<DartType> argumentTypes,
DartType declaredReturnType,
DartType returnContextType,
{ErrorReporter errorReporter,
AstNode errorNode}) {
if (fnType.typeFormals.isEmpty) {
return fnType;
}
// If we're in a future union context, choose either the Future<T> or the T
// based on the function's return type.
if (returnContextType is FutureUnionType) {
var futureUnion = returnContextType as FutureUnionType;
returnContextType =
isSubtypeOf(fnType.returnType, typeProvider.futureDynamicType)
? futureUnion.futureOfType
: futureUnion.type;
// TODO(jmesserly): expose typeFormals on ParameterizedType.
List<TypeParameterElement> typeFormals = genericType is FunctionType
? genericType.typeFormals
: genericType.typeParameters;
if (typeFormals.isEmpty) {
return genericType;
}
// Create a TypeSystem that will allow certain type parameters to be
@@ -420,20 +416,31 @@ class StrongTypeSystemImpl extends TypeSystem {
// subtypes (or supertypes) as necessary, and track the constraints that
// are implied by this.
var inferringTypeSystem =
new _StrongInferenceTypeSystem(typeProvider, this, fnType.typeFormals);
new _StrongInferenceTypeSystem(typeProvider, this, typeFormals);
if (returnContextType != null) {
inferringTypeSystem.isSubtypeOf(fnType.returnType, returnContextType);
// If we're in a future union context, choose either the Future<T>
// or the T based on the declared return type.
if (returnContextType is FutureUnionType) {
var futureUnion = returnContextType as FutureUnionType;
returnContextType =
isSubtypeOf(declaredReturnType, typeProvider.futureDynamicType)
? futureUnion.futureOfType
: futureUnion.type;
}
inferringTypeSystem.isSubtypeOf(declaredReturnType, returnContextType);
}
for (int i = 0; i < argumentTypes.length; i++) {
// Try to pass each argument to each parameter, recording any type
// parameter bounds that were implied by this assignment.
inferringTypeSystem.isSubtypeOf(
argumentTypes[i], correspondingParameterTypes[i]);
argumentTypes[i], declaredParameterTypes[i]);
}
return inferringTypeSystem._infer(fnType, errorReporter, errorNode);
return inferringTypeSystem._infer(
genericType, typeFormals, declaredReturnType, errorReporter, errorNode);
}
/**
@@ -1511,10 +1518,11 @@ class _StrongInferenceTypeSystem extends StrongTypeSystemImpl {
/// Given the constraints that were given by calling [isSubtypeOf], find the
/// instantiation of the generic function that satisfies these constraints.
FunctionType _infer(FunctionType fnType,
/*=T*/ _infer/*<T extends ParameterizedType>*/(/*=T*/ genericType,
List<TypeParameterElement> typeFormals, DartType declaredReturnType,
[ErrorReporter errorReporter, AstNode errorNode]) {
List<TypeParameterType> fnTypeParams =
TypeParameterTypeImpl.getTypes(fnType.typeFormals);
TypeParameterTypeImpl.getTypes(typeFormals);
// Initialize the inferred type array.
//
@@ -1561,7 +1569,7 @@ class _StrongInferenceTypeSystem extends StrongTypeSystemImpl {
//
// Otherwise we choose the more precise lower bound.
_TypeParameterVariance variance =
new _TypeParameterVariance.from(typeParam, fnType.returnType);
new _TypeParameterVariance.from(typeParam, declaredReturnType);
_TypeParameterBound bound = _bounds[typeParam];
DartType lowerBound = bound.lower;
@@ -1600,7 +1608,7 @@ class _StrongInferenceTypeSystem extends StrongTypeSystemImpl {
}
// Return the instantiated type.
return fnType.instantiate(inferredTypes);
return genericType.instantiate(inferredTypes) as dynamic/*=T*/;
}
@override
+6 -1
View File
@@ -2624,7 +2624,12 @@ class ExprTypeComputer {
});
// Perform inference.
FunctionType inferred = ts.inferGenericFunctionCall(
typeProvider, rawMethodType, paramTypes, argTypes, null);
typeProvider,
rawMethodType,
paramTypes,
argTypes,
rawMethodType.returnType,
null);
return inferred;
}
}
@@ -1100,7 +1100,10 @@ class StaticTypeAnalyzerTest extends EngineTestCase {
Identifier identifier = AstFactory.identifier3('a');
Expression node = AstFactory.listLiteral([identifier]);
DartType resultType = _analyze(node);
expect(resultType, isNull);
_assertType2(
_typeProvider.listType
.instantiate(<DartType>[_typeProvider.dynamicType]),
resultType);
_listener.assertNoErrors();
}
@@ -1450,6 +1450,12 @@ class D<S> {
checkBody("D");
}
void test_genericFunction_upwardsAndDownwards() {
// Regression tests for https://github.com/dart-lang/sdk/issues/27151.
resolveTestUnit(r'List<num> x = [1, 2];');
expectInitializerType('x', 'List<int>');
}
void test_genericMethod() {
resolveTestUnit(r'''
class C<E> {
@@ -1124,8 +1124,13 @@ class StrongGenericFunctionInferenceTest {
List<DartType> _inferCall(FunctionTypeImpl ft, List<DartType> arguments,
[DartType returnType]) {
FunctionType inferred = typeSystem.inferGenericFunctionCall(typeProvider,
ft, ft.parameters.map((p) => p.type).toList(), arguments, returnType);
FunctionType inferred = typeSystem.inferGenericFunctionCall(
typeProvider,
ft,
ft.parameters.map((p) => p.type).toList(),
arguments,
ft.returnType,
returnType);
return inferred?.typeArguments;
}
}
@@ -888,7 +888,7 @@ class Baz {}
checkFile('''
void main() {
List<int> l;
l = /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
l = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
l = (l = /*info:INFERRED_TYPE_LITERAL*/[1]);
}
''');
@@ -899,8 +899,8 @@ void main() {
import 'dart:async';
Future test() async {
dynamic d;
List<int> l0 = await /*info:INFERRED_TYPE_LITERAL*/[/*info:DYNAMIC_CAST*/d];
List<int> l1 = await /*info:INFERRED_TYPE_ALLOCATION*/new Future.value(/*info:INFERRED_TYPE_LITERAL*/[/*info:DYNAMIC_CAST*/d]);
List<int> l0 = await /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*info:DYNAMIC_CAST*/d];
List<int> l1 = await /*info:INFERRED_TYPE_ALLOCATION*/new Future.value(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*info:DYNAMIC_CAST*/d]);
}
''');
}
@@ -949,30 +949,30 @@ class F4 {
void main() {
new F0(/*info:INFERRED_TYPE_LITERAL*/[]);
new F0(/*info:INFERRED_TYPE_LITERAL*/[3]);
new F0(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
new F0(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello",
new F0(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
new F0(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello",
3]);
new F1(a: /*info:INFERRED_TYPE_LITERAL*/[]);
new F1(a: /*info:INFERRED_TYPE_LITERAL*/[3]);
new F1(a: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
new F1(a: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F1(a: /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
new F1(a: /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F2(/*info:INFERRED_TYPE_LITERAL*/[]);
new F2(/*info:INFERRED_TYPE_LITERAL*/[3]);
new F2(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
new F2(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F2(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
new F2(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F3(/*info:INFERRED_TYPE_LITERAL*/[]);
new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F4(a: /*info:INFERRED_TYPE_LITERAL*/[]);
new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
/*info:INFERRED_TYPE_LITERAL*/[3]]);
}
''');
@@ -988,28 +988,28 @@ void f4({Iterable<Iterable<int>> a}) {}
void main() {
f0(/*info:INFERRED_TYPE_LITERAL*/[]);
f0(/*info:INFERRED_TYPE_LITERAL*/[3]);
f0(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
f0(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
f0(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
f0(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
f1(a: /*info:INFERRED_TYPE_LITERAL*/[]);
f1(a: /*info:INFERRED_TYPE_LITERAL*/[3]);
f1(a: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
f1(a: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
f1(a: /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
f1(a: /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
f2(/*info:INFERRED_TYPE_LITERAL*/[]);
f2(/*info:INFERRED_TYPE_LITERAL*/[3]);
f2(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
f2(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
f2(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
f2(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
f3(/*info:INFERRED_TYPE_LITERAL*/[]);
f3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
f3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
f3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"], /*info:INFERRED_TYPE_LITERAL*/[3]]);
f3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
f3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"], /*info:INFERRED_TYPE_LITERAL*/[3]]);
f4(a: /*info:INFERRED_TYPE_LITERAL*/[]);
f4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
f4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
f4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"], /*info:INFERRED_TYPE_LITERAL*/[3]]);
f4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
f4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"], /*info:INFERRED_TYPE_LITERAL*/[3]]);
}
''');
}
@@ -1037,8 +1037,8 @@ void main () {
Function2<int, List<String>> l0 = /*info:INFERRED_TYPE_CLOSURE*/(int x) => null;
Function2<int, List<String>> l1 = (int x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
Function2<int, List<String>> l2 = /*error:INVALID_ASSIGNMENT*/(String x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
Function2<int, List<String>> l3 = (int x) => /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];
Function2<int, List<String>> l4 = /*info:INFERRED_TYPE_CLOSURE*/(int x) {return /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];};
Function2<int, List<String>> l3 = (int x) => /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];
Function2<int, List<String>> l4 = /*info:INFERRED_TYPE_CLOSURE*/(int x) {return /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];};
}
{
Function2<int, int> l0 = /*info:INFERRED_TYPE_CLOSURE*/(x) => x;
@@ -1093,42 +1093,42 @@ class F4<T> {
void main() {
new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[]);
new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[3]);
new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello",
new F0<int>(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
new F0<int>(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello",
3]);
new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[]);
new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[3]);
new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
new F1<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F1<int>(a: /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
new F1<int>(a: /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[]);
new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[3]);
new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
new F2<int>(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F2<int>(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]);
new F2<int>(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]);
new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[]);
new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
new F3<int>(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[]);
new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]]);
new F4<int>(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F3(/*info:INFERRED_TYPE_LITERAL*/[]);
new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/["hello"]]);
new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/["hello"],
/*info:INFERRED_TYPE_ALLOCATION*/new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
/*info:INFERRED_TYPE_ALLOCATION*/new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/["hello"]]);
/*info:INFERRED_TYPE_ALLOCATION*/new F3(/*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/["hello"],
/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F4(a: /*info:INFERRED_TYPE_LITERAL*/[]);
new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/["hello"]]);
new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/["hello"],
/*info:INFERRED_TYPE_ALLOCATION*/new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/[3]]);
/*info:INFERRED_TYPE_ALLOCATION*/new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/["hello"]]);
/*info:INFERRED_TYPE_ALLOCATION*/new F4(a: /*info:INFERRED_TYPE_LITERAL*/[/*info:INFERRED_TYPE_LITERAL*/["hello"],
/*info:INFERRED_TYPE_LITERAL*/[3]]);
}
''');
@@ -1161,8 +1161,8 @@ void main () {
v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) => null;
v = /*<T>*/(int x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
v = /*error:INVALID_ASSIGNMENT*//*<T>*/(String x) => /*info:INFERRED_TYPE_LITERAL*/["hello"];
v = /*<T>*/(int x) => /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];
v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) {return /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];};
v = /*<T>*/(int x) => /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];
v = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(int x) {return /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];};
}
{
int int2int/*<S>*/(int x) => null;
@@ -1283,8 +1283,8 @@ void main() {
a: /*info:INFERRED_TYPE_LITERAL*/[3],
b: /*info:INFERRED_TYPE_LITERAL*/["hello"]);
A<int, String> a1 = /*info:INFERRED_TYPE_ALLOCATION*/new F(3, "hello",
a: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
b: /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3]);
a: /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"],
b: /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3]);
A<int, String> a2 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello", 3, "hello");
A<int, String> a3 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello");
A<int, String> a4 = /*info:INFERRED_TYPE_ALLOCATION*/new /*error:COULD_NOT_INFER,error:COULD_NOT_INFER*/F.named(3, "hello",
@@ -1299,15 +1299,15 @@ void main() {
void test_downwardsInferenceOnListLiterals_inferDownwards() {
checkFile('''
void foo([List<String> list1 = /*info:INFERRED_TYPE_LITERAL*/const [],
List<String> list2 = /*info:INFERRED_TYPE_LITERAL*/const [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/42]]) {
List<String> list2 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/const [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/42]]) {
}
void main() {
{
List<int> l0 = /*info:INFERRED_TYPE_LITERAL*/[];
List<int> l1 = /*info:INFERRED_TYPE_LITERAL*/[3];
List<int> l2 = /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
List<int> l3 = /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
List<int> l2 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
List<int> l3 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
}
{
List<dynamic> l0 = [];
@@ -1324,14 +1324,14 @@ void main() {
{
Iterable<int> i0 = /*info:INFERRED_TYPE_LITERAL*/[];
Iterable<int> i1 = /*info:INFERRED_TYPE_LITERAL*/[3];
Iterable<int> i2 = /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
Iterable<int> i3 = /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
Iterable<int> i2 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
Iterable<int> i3 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
}
{
const List<int> c0 = /*info:INFERRED_TYPE_LITERAL*/const [];
const List<int> c1 = /*info:INFERRED_TYPE_LITERAL*/const [3];
const List<int> c2 = /*info:INFERRED_TYPE_LITERAL*/const [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
const List<int> c3 = /*info:INFERRED_TYPE_LITERAL*/const [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
const List<int> c2 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/const [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"];
const List<int> c3 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/const [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3];
}
}
''');
@@ -1399,7 +1399,7 @@ main() {
void test_downwardsInferenceOnMapLiterals() {
checkFile('''
void foo([Map<int, String> m1 = /*info:INFERRED_TYPE_LITERAL*/const {1: "hello"},
Map<int, String> m2 = /*info:INFERRED_TYPE_LITERAL*/const {
Map<int, String> m2 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/const {
// One error is from type checking and the other is from const evaluation.
/*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
"world"
@@ -1409,13 +1409,13 @@ void main() {
{
Map<int, String> l0 = /*info:INFERRED_TYPE_LITERAL*/{};
Map<int, String> l1 = /*info:INFERRED_TYPE_LITERAL*/{3: "hello"};
Map<int, String> l2 = /*info:INFERRED_TYPE_LITERAL*/{
Map<int, String> l2 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/{
/*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello": "hello"
};
Map<int, String> l3 = /*info:INFERRED_TYPE_LITERAL*/{
Map<int, String> l3 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/{
3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
};
Map<int, String> l4 = /*info:INFERRED_TYPE_LITERAL*/{
Map<int, String> l4 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER,error:COULD_NOT_INFER*/{
3: "hello",
/*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
/*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
@@ -1432,10 +1432,10 @@ void main() {
Map<dynamic, String> l0 = /*info:INFERRED_TYPE_LITERAL*/{};
Map<dynamic, String> l1 = /*info:INFERRED_TYPE_LITERAL*/{3: "hello"};
Map<dynamic, String> l2 = /*info:INFERRED_TYPE_LITERAL*/{"hello": "hello"};
Map<dynamic, String> l3 = /*info:INFERRED_TYPE_LITERAL*/{
Map<dynamic, String> l3 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/{
3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
};
Map<dynamic, String> l4 = /*info:INFERRED_TYPE_LITERAL*/{
Map<dynamic, String> l4 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/{
3: "hello",
"hello": /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
};
@@ -1443,11 +1443,11 @@ void main() {
{
Map<int, dynamic> l0 = /*info:INFERRED_TYPE_LITERAL*/{};
Map<int, dynamic> l1 = /*info:INFERRED_TYPE_LITERAL*/{3: "hello"};
Map<int, dynamic> l2 = /*info:INFERRED_TYPE_LITERAL*/{
Map<int, dynamic> l2 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/{
/*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello": "hello"
};
Map<int, dynamic> l3 = /*info:INFERRED_TYPE_LITERAL*/{3: 3};
Map<int, dynamic> l4 = /*info:INFERRED_TYPE_LITERAL*/{
Map<int, dynamic> l4 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/{
3:"hello",
/*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello": 3
};
@@ -1460,14 +1460,14 @@ void main() {
{
const Map<int, String> l0 = /*info:INFERRED_TYPE_LITERAL*/const {};
const Map<int, String> l1 = /*info:INFERRED_TYPE_LITERAL*/const {3: "hello"};
const Map<int, String> l2 = /*info:INFERRED_TYPE_LITERAL*/const {
const Map<int, String> l2 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/const {
/*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
"hello"
};
const Map<int, String> l3 = /*info:INFERRED_TYPE_LITERAL*/const {
const Map<int, String> l3 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/const {
3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE,error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
};
const Map<int, String> l4 = /*info:INFERRED_TYPE_LITERAL*/const {
const Map<int, String> l4 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER,error:COULD_NOT_INFER*/const {
3:"hello",
/*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello":
/*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE,error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3
@@ -1746,6 +1746,27 @@ class A {}
''');
}
void test_futureUnion_upwardsGenericMethods() {
// Regression test for https://github.com/dart-lang/sdk/issues/27151
checkFile(r'''
import 'dart:async';
main() async {
var b = new Future<B>.value(new B());
var c = new Future<C>.value(new C());
var lll = /*info:INFERRED_TYPE_LITERAL*/[b, c];
var result = await Future.wait(lll);
var result2 = await Future.wait(/*info:INFERRED_TYPE_LITERAL*/[b, c]);
List<A> list = result;
list = result2;
}
class A {}
class B extends A {}
class C extends A {}
''');
}
void test_genericMethods_basicDownwardInference() {
checkFile(r'''
/*=T*/ f/*<S, T>*/(/*=S*/ s) => null;
@@ -1833,7 +1854,7 @@ main() {
/*=T*/ f/*<T>*/(List/*<T>*/ s) => null;
main() {
String x = f(/*info:INFERRED_TYPE_LITERAL*/['hi']);
String y = f(/*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/42]);
String y = f(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/42]);
}
''');
}
@@ -2734,17 +2755,17 @@ class Foo<T> {
main() {
// List inside map
var map = <String, List<Folder>>{
'pkgA': /*info:INFERRED_TYPE_LITERAL*/[/*info:DOWN_CAST_IMPLICIT*/getResource('/pkgA/lib/')],
'pkgB': /*info:INFERRED_TYPE_LITERAL*/[/*info:DOWN_CAST_IMPLICIT*/getResource('/pkgB/lib/')]
'pkgA': /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*info:DOWN_CAST_IMPLICIT*/getResource('/pkgA/lib/')],
'pkgB': /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*info:DOWN_CAST_IMPLICIT*/getResource('/pkgB/lib/')]
};
// Also try map inside list
var list = <Map<String, Folder>>[
/*info:INFERRED_TYPE_LITERAL*/{ 'pkgA': /*info:DOWN_CAST_IMPLICIT*/getResource('/pkgA/lib/') },
/*info:INFERRED_TYPE_LITERAL*/{ 'pkgB': /*info:DOWN_CAST_IMPLICIT*/getResource('/pkgB/lib/') },
/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/{ 'pkgA': /*info:DOWN_CAST_IMPLICIT*/getResource('/pkgA/lib/') },
/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/{ 'pkgB': /*info:DOWN_CAST_IMPLICIT*/getResource('/pkgB/lib/') },
];
// Instance creation too
var foo = new Foo<List<Folder>>(
/*info:INFERRED_TYPE_LITERAL*/[/*info:DOWN_CAST_IMPLICIT*/getResource('/pkgA/lib/')]
/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*info:DOWN_CAST_IMPLICIT*/getResource('/pkgA/lib/')]
);
}
''');