Skip to content

Commit d838283

Browse files
chloestefantsovaCommit Queue
authored andcommitted
[cfe] Update nullabilities after bounds change in instantiations
Closes #59663 Change-Id: Id4eb4d86c463a24ef45f81d065e322a9f688b045 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/403040 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Chloe Stefantsova <[email protected]>
1 parent 3393bef commit d838283

8 files changed

+120
-6
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
class A<X> {
6+
Function<Y extends X>(Y) foo;
7+
A(this.foo);
8+
}
9+
10+
bar<T extends num>(T t) {}
11+
12+
main() {
13+
new A(bar);
14+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class A<X extends core::Object? = dynamic> extends core::Object {
6+
covariant-by-class field <Y extends self::A::X% = dynamic>(Y%) → dynamic foo;
7+
constructor •(<Y extends self::A::X% = dynamic>(Y%) → dynamic foo) → self::A<self::A::X%>
8+
: self::A::foo = foo, super core::Object::•()
9+
;
10+
}
11+
static method bar<T extends core::num>(self::bar::T t) → dynamic {}
12+
static method main() → dynamic {
13+
new self::A::•<core::num>(#C1);
14+
}
15+
16+
constants {
17+
#C1 = static-tearoff self::bar
18+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class A<X extends core::Object? = dynamic> extends core::Object {
6+
covariant-by-class field <Y extends self::A::X% = dynamic>(Y%) → dynamic foo;
7+
constructor •(<Y extends self::A::X% = dynamic>(Y%) → dynamic foo) → self::A<self::A::X%>
8+
: self::A::foo = foo, super core::Object::•()
9+
;
10+
}
11+
static method bar<T extends core::num>(self::bar::T t) → dynamic {}
12+
static method main() → dynamic {
13+
new self::A::•<core::num>(#C1);
14+
}
15+
16+
constants {
17+
#C1 = static-tearoff self::bar
18+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class A<X extends core::Object? = dynamic> extends core::Object {
6+
covariant-by-class field <Y extends self::A::X% = dynamic>(Y%) → dynamic foo;
7+
constructor •(<Y extends self::A::X% = dynamic>(Y%) → dynamic foo) → self::A<self::A::X%>
8+
;
9+
}
10+
static method bar<T extends core::num>(self::bar::T t) → dynamic
11+
;
12+
static method main() → dynamic
13+
;
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
library;
2+
import self as self;
3+
import "dart:core" as core;
4+
5+
class A<X extends core::Object? = dynamic> extends core::Object {
6+
covariant-by-class field <Y extends self::A::X% = dynamic>(Y%) → dynamic foo;
7+
constructor •(<Y extends self::A::X% = dynamic>(Y%) → dynamic foo) → self::A<self::A::X%>
8+
: self::A::foo = foo, super core::Object::•()
9+
;
10+
}
11+
static method bar<T extends core::num>(self::bar::T t) → dynamic {}
12+
static method main() → dynamic {
13+
new self::A::•<core::num>(#C1);
14+
}
15+
16+
constants {
17+
#C1 = static-tearoff self::bar
18+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class A<X> {
2+
Function<Y extends X>(Y) foo;
3+
A(this.foo);
4+
}
5+
6+
bar<T extends num>(T t) {}
7+
8+
main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
bar<T extends num>(T t) {}
2+
3+
class A<X> {
4+
A(this.foo);
5+
Function<Y extends X>(Y) foo;
6+
}
7+
8+
main() {}

pkg/kernel/lib/type_algebra.dart

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,28 @@ FreshStructuralParameters? getFreshStructuralParametersSubstitutingBounds(
305305
parameterBoundsHaveChanged = true;
306306
}
307307

308+
freshTypeParameter.variance =
309+
typeParameter.isLegacyCovariant ? null : typeParameter.variance;
310+
// Annotations on a type parameter are specific to the declaration of the
311+
// type parameter, rather than the type parameter as such, and therefore
312+
// should not be copied here.
313+
}
314+
315+
if (parameterBoundsHaveChanged) {
316+
// Since the bounds have changed, the nullabilities of fresh structural
317+
// parameter types should be updated.
318+
freshTypeArguments = [
319+
for (int i = 0; i < freshParameters.length; i++)
320+
new StructuralParameterType.withDefaultNullability(freshParameters[i])
321+
];
322+
instantiator = FunctionTypeInstantiator.fromIterables(
323+
typeParameters, freshTypeArguments);
324+
}
325+
326+
for (int i = 0; i < typeParameters.length; ++i) {
327+
StructuralParameter typeParameter = typeParameters[i];
328+
StructuralParameter freshTypeParameter = freshParameters[i];
329+
308330
// TODO(cstefantsova): Replace the following by an assert checking that the
309331
// type parameters don't occur in the default types.
310332
DartType? defaultTypeVisitedByOuter =
@@ -317,13 +339,8 @@ FreshStructuralParameters? getFreshStructuralParametersSubstitutingBounds(
317339
if (defaultTypeVisitedByThis != null || defaultTypeVisitedByThis != null) {
318340
parameterBoundsHaveChanged = true;
319341
}
320-
321-
freshTypeParameter.variance =
322-
typeParameter.isLegacyCovariant ? null : typeParameter.variance;
323-
// Annotations on a type parameter are specific to the declaration of the
324-
// type parameter, rather than the type parameter as such, and therefore
325-
// should not be copied here.
326342
}
343+
327344
if (!parameterBoundsHaveChanged) {
328345
return null;
329346
} else {

0 commit comments

Comments
 (0)