Skip to content

Commit 83ab0a5

Browse files
stereotype441commit-bot@chromium.org
authored andcommitted
Migration: handle an assignment from a type parameter's bound to its type.
Change-Id: Iceda253691735fa3b8104f76f14b596aa4bd621a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/112145 Reviewed-by: Dan Rubel <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent 7912216 commit 83ab0a5

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

pkg/nnbd_migration/lib/src/edge_builder.dart

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,6 +1438,8 @@ $stackTrace''');
14381438
mixin _AssignmentChecker {
14391439
DecoratedClassHierarchy get _decoratedClassHierarchy;
14401440

1441+
NullabilityGraph get _graph;
1442+
14411443
TypeSystem get _typeSystem;
14421444

14431445
/// Creates the necessary constraint(s) for an assignment from [source] to
@@ -1470,6 +1472,14 @@ mixin _AssignmentChecker {
14701472
hard: false);
14711473
return;
14721474
}
1475+
} else if (destinationType is TypeParameterType) {
1476+
// Effectively this is a downcast assignment from the source type to the
1477+
// type parameter's bound.
1478+
_checkAssignment(origin,
1479+
source: source,
1480+
destination:
1481+
_getTypeParameterTypeBound(destination).withNode(_graph.always),
1482+
hard: false);
14731483
} else if (sourceType is InterfaceType &&
14741484
destinationType is InterfaceType) {
14751485
if (_typeSystem.isSubtypeOf(sourceType, destinationType)) {

pkg/nnbd_migration/test/edge_builder_test.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,19 @@ class AssignmentCheckerTest extends Object with EdgeTester {
134134
assertEdge(never, t.node, hard: false);
135135
}
136136

137+
void test_complex_to_typeParam() {
138+
var bound = list(object());
139+
var t = TypeParameterElementImpl.synthetic('T')..bound = bound.type;
140+
checker.bounds[t] = bound;
141+
var t1 = list(object());
142+
var t2 = typeParameterType(t);
143+
assign(t1, t2, hard: true);
144+
assertEdge(t1.node, t2.node, hard: true);
145+
assertNoEdge(t1.node, bound.node);
146+
assertEdge(t1.typeArguments[0].node, bound.typeArguments[0].node,
147+
hard: false);
148+
}
149+
137150
void test_dynamic_to_dynamic() {
138151
assign(dynamic_, dynamic_);
139152
// Note: no assertions to do; just need to make sure there wasn't a crash.
@@ -411,6 +424,22 @@ void f(int i) {
411424
assertEdge(decoratedTypeAnnotation('int i').node, never, hard: true);
412425
}
413426

427+
test_assign_bound_to_type_parameter() async {
428+
await analyze('''
429+
class C<T extends List<int>> {
430+
T f(List<int> x) => x;
431+
}
432+
''');
433+
var boundType = decoratedTypeAnnotation('List<int>>');
434+
var parameterType = decoratedTypeAnnotation('List<int> x');
435+
var tType = decoratedTypeAnnotation('T f');
436+
assertEdge(parameterType.node, tType.node, hard: true);
437+
assertNoEdge(parameterType.node, boundType.node);
438+
assertEdge(
439+
parameterType.typeArguments[0].node, boundType.typeArguments[0].node,
440+
hard: false);
441+
}
442+
414443
test_assign_null_to_generic_type() async {
415444
await analyze('''
416445
main() {

0 commit comments

Comments
 (0)