diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart index dac1d39a7a2..6fa534577b6 100644 --- a/pkg/analyzer/lib/src/generated/resolver.dart +++ b/pkg/analyzer/lib/src/generated/resolver.dart @@ -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); diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart index b7d45f75057..fafb7b9c9fa 100644 --- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart +++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart @@ -623,46 +623,45 @@ class StaticTypeAnalyzer extends SimpleAstVisitor { return null; } + DartType listDynamicType = + _typeProvider.listType.instantiate([_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 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([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([_dynamicType])); + _recordStaticType(node, listDynamicType); return null; } @@ -682,6 +681,9 @@ class StaticTypeAnalyzer extends SimpleAstVisitor { Object visitMapLiteral(MapLiteral node) { TypeArgumentList typeArguments = node.typeArguments; + DartType mapDynamicType = _typeProvider.mapType + .instantiate([_dynamicType, _dynamicType]); + // If we have type arguments, use them if (typeArguments != null) { DartType staticKeyType = _dynamicType; @@ -710,43 +712,40 @@ class StaticTypeAnalyzer extends SimpleAstVisitor { // 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([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([_dynamicType, _dynamicType])); + _recordStaticType(node, mapDynamicType); return null; } @@ -1986,7 +1985,7 @@ class StaticTypeAnalyzer extends SimpleAstVisitor { } } 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 { 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. * diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart index 8826bfb0256..39bd24b8f15 100644 --- a/pkg/analyzer/lib/src/generated/type_system.dart +++ b/pkg/analyzer/lib/src/generated/type_system.dart @@ -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/**/( TypeProvider typeProvider, - FunctionType fnType, - List correspondingParameterTypes, + /*=T*/ genericType, + List declaredParameterTypes, List 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 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 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 + // 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*/ genericType, + List typeFormals, DartType declaredReturnType, [ErrorReporter errorReporter, AstNode errorNode]) { List 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 diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart index 868218a80f5..f0a818d337d 100644 --- a/pkg/analyzer/lib/src/summary/link.dart +++ b/pkg/analyzer/lib/src/summary/link.dart @@ -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; } } diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart index 2fc3fc5cae1..60854a9b2aa 100644 --- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart +++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart @@ -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([_typeProvider.dynamicType]), + resultType); _listener.assertNoErrors(); } diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart index 877be1e47f6..530e3f883b9 100644 --- a/pkg/analyzer/test/generated/strong_mode_test.dart +++ b/pkg/analyzer/test/generated/strong_mode_test.dart @@ -1450,6 +1450,12 @@ class D { checkBody("D"); } + void test_genericFunction_upwardsAndDownwards() { + // Regression tests for https://github.com/dart-lang/sdk/issues/27151. + resolveTestUnit(r'List x = [1, 2];'); + expectInitializerType('x', 'List'); + } + void test_genericMethod() { resolveTestUnit(r''' class C { diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart index 909dfdcf591..af08bb4d678 100644 --- a/pkg/analyzer/test/generated/type_system_test.dart +++ b/pkg/analyzer/test/generated/type_system_test.dart @@ -1124,8 +1124,13 @@ class StrongGenericFunctionInferenceTest { List _inferCall(FunctionTypeImpl ft, List 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; } } diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart index 0490b744239..85ee428d6c1 100644 --- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart +++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart @@ -888,7 +888,7 @@ class Baz {} checkFile(''' void main() { List 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 l0 = await /*info:INFERRED_TYPE_LITERAL*/[/*info:DYNAMIC_CAST*/d]; - List l1 = await /*info:INFERRED_TYPE_ALLOCATION*/new Future.value(/*info:INFERRED_TYPE_LITERAL*/[/*info:DYNAMIC_CAST*/d]); + List l0 = await /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*info:DYNAMIC_CAST*/d]; + List 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> 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> l0 = /*info:INFERRED_TYPE_CLOSURE*/(int x) => null; Function2> l1 = (int x) => /*info:INFERRED_TYPE_LITERAL*/["hello"]; Function2> l2 = /*error:INVALID_ASSIGNMENT*/(String x) => /*info:INFERRED_TYPE_LITERAL*/["hello"]; - Function2> l3 = (int x) => /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3]; - Function2> l4 = /*info:INFERRED_TYPE_CLOSURE*/(int x) {return /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];}; + Function2> l3 = (int x) => /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3]; + Function2> l4 = /*info:INFERRED_TYPE_CLOSURE*/(int x) {return /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];}; } { Function2 l0 = /*info:INFERRED_TYPE_CLOSURE*/(x) => x; @@ -1093,42 +1093,42 @@ 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]]); 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*//**/(int x) => null; v = /**/(int x) => /*info:INFERRED_TYPE_LITERAL*/["hello"]; v = /*error:INVALID_ASSIGNMENT*//**/(String x) => /*info:INFERRED_TYPE_LITERAL*/["hello"]; - v = /**/(int x) => /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3]; - v = /*info:INFERRED_TYPE_CLOSURE*//**/(int x) {return /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];}; + v = /**/(int x) => /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3]; + v = /*info:INFERRED_TYPE_CLOSURE*//**/(int x) {return /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/3];}; } { int int2int/**/(int x) => null; @@ -1283,8 +1283,8 @@ void main() { a: /*info:INFERRED_TYPE_LITERAL*/[3], b: /*info:INFERRED_TYPE_LITERAL*/["hello"]); A 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 a2 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello", 3, "hello"); A a3 = /*info:INFERRED_TYPE_ALLOCATION*/new F.named(3, "hello"); A 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 list1 = /*info:INFERRED_TYPE_LITERAL*/const [], - List list2 = /*info:INFERRED_TYPE_LITERAL*/const [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/42]]) { + List 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 l0 = /*info:INFERRED_TYPE_LITERAL*/[]; List l1 = /*info:INFERRED_TYPE_LITERAL*/[3]; - List l2 = /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]; - List l3 = /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]; + List l2 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]; + List l3 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]; } { List l0 = []; @@ -1324,14 +1324,14 @@ void main() { { Iterable i0 = /*info:INFERRED_TYPE_LITERAL*/[]; Iterable i1 = /*info:INFERRED_TYPE_LITERAL*/[3]; - Iterable i2 = /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]; - Iterable i3 = /*info:INFERRED_TYPE_LITERAL*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]; + Iterable i2 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]; + Iterable i3 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]; } { const List c0 = /*info:INFERRED_TYPE_LITERAL*/const []; const List c1 = /*info:INFERRED_TYPE_LITERAL*/const [3]; - const List c2 = /*info:INFERRED_TYPE_LITERAL*/const [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello"]; - const List c3 = /*info:INFERRED_TYPE_LITERAL*/const [/*error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE,error:LIST_ELEMENT_TYPE_NOT_ASSIGNABLE*/"hello", 3]; + const List 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 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 m1 = /*info:INFERRED_TYPE_LITERAL*/const {1: "hello"}, - Map m2 = /*info:INFERRED_TYPE_LITERAL*/const { + Map 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 l0 = /*info:INFERRED_TYPE_LITERAL*/{}; Map l1 = /*info:INFERRED_TYPE_LITERAL*/{3: "hello"}; - Map l2 = /*info:INFERRED_TYPE_LITERAL*/{ + Map l2 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/{ /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello": "hello" }; - Map l3 = /*info:INFERRED_TYPE_LITERAL*/{ + Map l3 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/{ 3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3 }; - Map l4 = /*info:INFERRED_TYPE_LITERAL*/{ + Map 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 l0 = /*info:INFERRED_TYPE_LITERAL*/{}; Map l1 = /*info:INFERRED_TYPE_LITERAL*/{3: "hello"}; Map l2 = /*info:INFERRED_TYPE_LITERAL*/{"hello": "hello"}; - Map l3 = /*info:INFERRED_TYPE_LITERAL*/{ + Map l3 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/{ 3: /*error:MAP_VALUE_TYPE_NOT_ASSIGNABLE*/3 }; - Map l4 = /*info:INFERRED_TYPE_LITERAL*/{ + Map 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 l0 = /*info:INFERRED_TYPE_LITERAL*/{}; Map l1 = /*info:INFERRED_TYPE_LITERAL*/{3: "hello"}; - Map l2 = /*info:INFERRED_TYPE_LITERAL*/{ + Map l2 = /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/{ /*error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/"hello": "hello" }; Map l3 = /*info:INFERRED_TYPE_LITERAL*/{3: 3}; - Map l4 = /*info:INFERRED_TYPE_LITERAL*/{ + Map 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 l0 = /*info:INFERRED_TYPE_LITERAL*/const {}; const Map l1 = /*info:INFERRED_TYPE_LITERAL*/const {3: "hello"}; - const Map l2 = /*info:INFERRED_TYPE_LITERAL*/const { + const Map 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 l3 = /*info:INFERRED_TYPE_LITERAL*/const { + const Map 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 l4 = /*info:INFERRED_TYPE_LITERAL*/const { + const Map 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.value(new B()); + var c = new Future.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 list = result; + list = result2; +} + +class A {} +class B extends A {} +class C extends A {} + '''); + } + void test_genericMethods_basicDownwardInference() { checkFile(r''' /*=T*/ f/**/(/*=S*/ s) => null; @@ -1833,7 +1854,7 @@ main() { /*=T*/ f/**/(List/**/ 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 { main() { // List inside map var map = >{ - '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 = >[ - /*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>( - /*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/')] ); } ''');