Skip to content

Commit 84ff9e5

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
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>
1 parent 0966e06 commit 84ff9e5

4 files changed

Lines changed: 50 additions & 2 deletions

File tree

pkg/analyzer/lib/src/dart/element/display_string_builder.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,10 +359,13 @@ class ElementDisplayStringBuilder {
359359
if (type is TypeParameterType) {
360360
referencedTypeParameters.add(type.element);
361361
} else if (type is FunctionType) {
362-
collectTypeParameters(type.returnType);
362+
for (var typeParameter in type.typeFormals) {
363+
collectTypeParameters(typeParameter.bound);
364+
}
363365
for (var parameter in type.parameters) {
364366
collectTypeParameters(parameter.type);
365367
}
368+
collectTypeParameters(type.returnType);
366369
} else if (type is InterfaceType) {
367370
for (var typeArgument in type.typeArguments) {
368371
collectTypeParameters(typeArgument);

pkg/analyzer/lib/src/dart/element/nullability_eliminator.dart

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ class NullabilityEliminator extends DartTypeVisitor<DartType> {
137137
}
138138

139139
var freshElements = List<TypeParameterElement>(elements.length);
140+
var substitutionMap = <TypeParameterElement, TypeParameterType>{};
140141
for (var i = 0; i < elements.length; i++) {
141142
// TODO (kallentu) : Clean up TypeParameterElementImpl casting once
142143
// variance is added to the interface.
@@ -145,8 +146,19 @@ class NullabilityEliminator extends DartTypeVisitor<DartType> {
145146
if (!element.isLegacyCovariant) {
146147
freshElement.variance = element.variance;
147148
}
148-
freshElement.bound = freshBounds[i];
149149
freshElements[i] = freshElement;
150+
substitutionMap[element] = freshElement.instantiate(
151+
nullabilitySuffix: NullabilitySuffix.none,
152+
);
153+
}
154+
155+
var substitution = Substitution.fromMap(substitutionMap);
156+
for (var i = 0; i < elements.length; i++) {
157+
var bound = freshBounds[i];
158+
if (bound != null) {
159+
var freshElement = freshElements[i] as TypeParameterElementImpl;
160+
freshElement.bound = substitution.substituteType(bound);
161+
}
150162
}
151163

152164
FunctionType newType = replaceTypeParameters(type, freshElements);

pkg/analyzer/test/src/dart/element/nullability_eliminator_test.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,20 @@ class NullabilityEliminatorTest with ElementsTypesMixin {
207207
);
208208
}
209209

210+
test_functionType_typeParameters_bound_other() {
211+
var T = typeParameter('T', bound: intNone);
212+
var U = typeParameter('U', bound: typeParameterTypeNone(T));
213+
214+
_verifyStr(
215+
functionTypeNone(
216+
typeFormals: [T, U],
217+
returnType: typeParameterTypeNone(T),
218+
),
219+
'T Function<T extends int, U extends T>()',
220+
'T* Function<T extends int*, U extends T*>()*',
221+
);
222+
}
223+
210224
test_functionType_typeParameters_bound_question() {
211225
var T = typeParameter('T', bound: intQuestion);
212226

pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,25 @@ class A<X extends int> {}
431431
import 'a.dart';
432432
433433
class A1<T extends Null> extends A<T> {}
434+
''');
435+
}
436+
437+
test_extends_optIn_fromOptOut_otherTypeParameter() async {
438+
newFile('/test/lib/a.dart', content: r'''
439+
void foo<T extends U, U>() {
440+
}
441+
''');
442+
443+
await assertNoErrorsInCode(r'''
444+
// @dart=2.6
445+
import 'a.dart';
446+
447+
class A {}
448+
class B extends A {}
449+
450+
main() {
451+
foo<B, A>();
452+
}
434453
''');
435454
}
436455
}

0 commit comments

Comments
 (0)