mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 08:44:27 +00:00
Fix NullabilityEliminator to substitute type parameters in bounds.
R=brianwilkerson@google.com, paulberry@google.com Change-Id: I9b3d986a52f8006854b23db600493566aea86cb9 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/135527 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Paul Berry <paulberry@google.com>
This commit is contained in:
parent
0966e06ee4
commit
84ff9e5008
4 changed files with 50 additions and 2 deletions
|
@ -359,10 +359,13 @@ class ElementDisplayStringBuilder {
|
|||
if (type is TypeParameterType) {
|
||||
referencedTypeParameters.add(type.element);
|
||||
} else if (type is FunctionType) {
|
||||
collectTypeParameters(type.returnType);
|
||||
for (var typeParameter in type.typeFormals) {
|
||||
collectTypeParameters(typeParameter.bound);
|
||||
}
|
||||
for (var parameter in type.parameters) {
|
||||
collectTypeParameters(parameter.type);
|
||||
}
|
||||
collectTypeParameters(type.returnType);
|
||||
} else if (type is InterfaceType) {
|
||||
for (var typeArgument in type.typeArguments) {
|
||||
collectTypeParameters(typeArgument);
|
||||
|
|
|
@ -137,6 +137,7 @@ class NullabilityEliminator extends DartTypeVisitor<DartType> {
|
|||
}
|
||||
|
||||
var freshElements = List<TypeParameterElement>(elements.length);
|
||||
var substitutionMap = <TypeParameterElement, TypeParameterType>{};
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
// TODO (kallentu) : Clean up TypeParameterElementImpl casting once
|
||||
// variance is added to the interface.
|
||||
|
@ -145,8 +146,19 @@ class NullabilityEliminator extends DartTypeVisitor<DartType> {
|
|||
if (!element.isLegacyCovariant) {
|
||||
freshElement.variance = element.variance;
|
||||
}
|
||||
freshElement.bound = freshBounds[i];
|
||||
freshElements[i] = freshElement;
|
||||
substitutionMap[element] = freshElement.instantiate(
|
||||
nullabilitySuffix: NullabilitySuffix.none,
|
||||
);
|
||||
}
|
||||
|
||||
var substitution = Substitution.fromMap(substitutionMap);
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
var bound = freshBounds[i];
|
||||
if (bound != null) {
|
||||
var freshElement = freshElements[i] as TypeParameterElementImpl;
|
||||
freshElement.bound = substitution.substituteType(bound);
|
||||
}
|
||||
}
|
||||
|
||||
FunctionType newType = replaceTypeParameters(type, freshElements);
|
||||
|
|
|
@ -207,6 +207,20 @@ class NullabilityEliminatorTest with ElementsTypesMixin {
|
|||
);
|
||||
}
|
||||
|
||||
test_functionType_typeParameters_bound_other() {
|
||||
var T = typeParameter('T', bound: intNone);
|
||||
var U = typeParameter('U', bound: typeParameterTypeNone(T));
|
||||
|
||||
_verifyStr(
|
||||
functionTypeNone(
|
||||
typeFormals: [T, U],
|
||||
returnType: typeParameterTypeNone(T),
|
||||
),
|
||||
'T Function<T extends int, U extends T>()',
|
||||
'T* Function<T extends int*, U extends T*>()*',
|
||||
);
|
||||
}
|
||||
|
||||
test_functionType_typeParameters_bound_question() {
|
||||
var T = typeParameter('T', bound: intQuestion);
|
||||
|
||||
|
|
|
@ -431,6 +431,25 @@ class A<X extends int> {}
|
|||
import 'a.dart';
|
||||
|
||||
class A1<T extends Null> extends A<T> {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_extends_optIn_fromOptOut_otherTypeParameter() async {
|
||||
newFile('/test/lib/a.dart', content: r'''
|
||||
void foo<T extends U, U>() {
|
||||
}
|
||||
''');
|
||||
|
||||
await assertNoErrorsInCode(r'''
|
||||
// @dart=2.6
|
||||
import 'a.dart';
|
||||
|
||||
class A {}
|
||||
class B extends A {}
|
||||
|
||||
main() {
|
||||
foo<B, A>();
|
||||
}
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue