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:
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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/')]
|
||||
);
|
||||
}
|
||||
''');
|
||||
|
||||
Reference in New Issue
Block a user