Instantiate parameterized types of type parameters with 'dynamic' type arguments.

There is internal code like the added test, which caused us to use
out of scope type parameter during inferred type computation.

Possibly related issues.
https://github.com/dart-lang/sdk/issues/26990
https://github.com/dart-lang/sdk/issues/27072

R=brianwilkerson@google.com, leafp@google.com, paulberry@google.com
BUG=

Review URL: https://codereview.chromium.org/2376213003 .
This commit is contained in:
Konstantin Shcheglov 2016-10-03 11:06:57 -07:00
parent 43e338d437
commit b0d8f47563
4 changed files with 23 additions and 34 deletions

View file

@ -8129,21 +8129,6 @@ abstract class TypeParameterizedElementMixin
*/
List<UnlinkedTypeParam> get unlinkedTypeParams;
/**
* Determine the default value of type argument [i]. in most cases this will
* be `dynamic`, but sometimes it will be the bound of the ith type parameter.
*/
DartType computeDefaultTypeArgument(int i) {
// If strong mode is off, or we can tell quickly from the summary that there
// is no bound, then the default type argument is `dynamic`; we don't have
// to call `typeParameters` to find that out.
if (!context.analysisOptions.strongMode ||
(unlinkedTypeParams != null && unlinkedTypeParams[i].bound == null)) {
return DynamicTypeImpl.instance;
}
return typeParameters[i].bound ?? DynamicTypeImpl.instance;
}
/**
* Convert the given [index] into a type parameter type.
*/

View file

@ -606,14 +606,14 @@ class ClassElementForLink_Class extends ClassElementForLink
DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
int numTypeParameters = _unlinkedClass.typeParameters.length;
if (numTypeParameters != 0) {
return new InterfaceTypeImpl.elementWithNameAndArgs(this, name, () {
List<DartType> typeArguments = new List<DartType>(numTypeParameters);
for (int i = 0; i < numTypeParameters; i++) {
typeArguments[i] =
getTypeArgument(i) ?? computeDefaultTypeArgument(i);
}
return typeArguments;
});
List<DartType> typeArguments =
new List<DartType>.generate(numTypeParameters, getTypeArgument);
if (typeArguments.contains(null)) {
return context.typeSystem.instantiateToBounds(this.type);
} else {
return new InterfaceTypeImpl.elementWithNameAndArgs(
this, name, () => typeArguments);
}
} else {
return _type ??= new InterfaceTypeImpl(this);
}
@ -3177,12 +3177,15 @@ class FunctionTypeAliasElementForLink extends Object
DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
int numTypeParameters = _unlinkedTypedef.typeParameters.length;
if (numTypeParameters != 0) {
List<DartType> typeArguments = new List<DartType>(numTypeParameters);
for (int i = 0; i < numTypeParameters; i++) {
typeArguments[i] = getTypeArgument(i) ?? computeDefaultTypeArgument(i);
List<DartType> typeArguments =
new List<DartType>.generate(numTypeParameters, getTypeArgument);
if (typeArguments.contains(null)) {
return context.typeSystem
.instantiateToBounds(new FunctionTypeImpl.forTypedef(this));
} else {
return new FunctionTypeImpl.elementWithNameAndArgs(
this, name, typeArguments, true);
}
return new FunctionTypeImpl.elementWithNameAndArgs(
this, name, typeArguments, true);
} else {
return _type ??= new FunctionTypeImpl.forTypedef(this);
}
@ -4407,6 +4410,9 @@ abstract class ReferenceableElementForLink implements Element {
*/
TypeInferenceNode get asTypeInferenceNode => null;
@override
ElementLocation get location => new ElementLocationImpl.con1(this);
/**
* Return the type indicated by this element when it is used in a
* type instantiation context. If this element can't legally be

View file

@ -152,12 +152,6 @@ class AstInferredTypeTest extends AbstractResynthesizeTest
super.test_circularReference_viaClosures_initializerTypes();
}
@override
@failingTest
void test_constructors_inferenceFBounded() {
super.test_constructors_inferenceFBounded();
}
@override
@failingTest
void test_constructors_inferFromArguments() {

View file

@ -3578,6 +3578,10 @@ C c;
checkLibrary('''
class C<T extends C<T>> {}
C c;
var c2 = new C();
class B {
var c3 = new C();
}
''');
}