Skip to content

Commit 66fa0e2

Browse files
fishythefishCommit Queue
authored andcommitted
[dart2js] Clean up nullability adjustments in interface sufficiency test
Now that #60076 has been addressed, we no longer need to widen the nullability ourselves. Change-Id: I4bc5a1767d9e2d98bcf0ca4c24171482e0f600ac Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/409162 Commit-Queue: Mayank Patke <[email protected]> Reviewed-by: Stephen Adams <[email protected]>
1 parent 23cac7c commit 66fa0e2

File tree

2 files changed

+106
-11
lines changed

2 files changed

+106
-11
lines changed

pkg/compiler/lib/src/ssa/builder.dart

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7740,26 +7740,18 @@ class KernelSsaGraphBuilder extends ir.VisitorDefault<void>
77407740
final sufficiency = closedWorld.elementMap.typeEnvironment
77417741
.computeTypeShapeCheckSufficiency(
77427742
expressionStaticType: operandType,
7743-
// Add `?` in case operand is nullable:
7744-
checkTargetType: checkedType.withDeclaredNullability(
7745-
ir.Nullability.nullable,
7746-
),
7743+
checkTargetType: checkedType,
77477744
subtypeCheckMode: ir.SubtypeCheckMode.withNullabilities,
77487745
);
77497746

77507747
// If `true` the caller only needs to check nullabillity and the actual
77517748
// concrete class, no need to check [testedAgainstType] arguments.
77527749
if (sufficiency == ir.TypeShapeCheckSufficiency.interfaceShape) {
7753-
return ir.InterfaceType(
7750+
return closedWorld.elementMap.coreTypes.rawType(
77547751
checkedType.classNode,
7755-
(operandType is ir.InterfaceType &&
7756-
operandType.nullability == ir.Nullability.nonNullable)
7752+
operandType.nullability == ir.Nullability.nonNullable
77577753
? ir.Nullability.nonNullable
77587754
: checkedType.nullability,
7759-
[
7760-
for (final parameter in checkedType.classNode.typeParameters)
7761-
parameter.defaultType,
7762-
],
77637755
);
77647756
}
77657757
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
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+
// `is` tests against some parameterized interface types are equivalent to a
6+
// weaker test for just the interace. The weaker test is usually more efficient,
7+
// sometimes being compiled to `instanceof`.
8+
9+
class Base<T extends num> {
10+
/*member: Base.test1:function(other) {
11+
if (other instanceof A.D1)
12+
return other.foo$0();
13+
return "other";
14+
}*/
15+
@pragma('dart2js:parameter:trust')
16+
String test1(Base<T> other) {
17+
if (other is D1<T>) return other.foo();
18+
return 'other';
19+
}
20+
21+
/*member: Base.test1qn:function(other) {
22+
if (other instanceof A.D1)
23+
return other.foo$0();
24+
return "other";
25+
}*/
26+
@pragma('dart2js:parameter:trust')
27+
String test1qn(Base<T>? other) {
28+
if (other is D1<T>) return other.foo();
29+
return 'other';
30+
}
31+
32+
/*member: Base.test1nq:function(other) {
33+
if (other instanceof A.D1)
34+
return other.method$0();
35+
return "other";
36+
}*/
37+
@pragma('dart2js:parameter:trust')
38+
String? test1nq(Base<T> other) {
39+
if (other is D1<T>?) return other.method(); // No promotion, so can't foo().
40+
return 'other';
41+
}
42+
43+
/*member: Base.test1qq:function(other) {
44+
var t1;
45+
if (type$.nullable_D1_dynamic._is(other)) {
46+
t1 = other.foo$0();
47+
return t1;
48+
}
49+
return "other";
50+
}*/
51+
@pragma('dart2js:parameter:trust')
52+
String? test1qq(Base<T>? other) {
53+
if (other is D1<T>?) return other?.foo();
54+
return 'other';
55+
}
56+
57+
/*member: Base.test2:function(other) {
58+
if (other instanceof A.D2)
59+
return other.bar$0();
60+
return "other";
61+
}*/
62+
@pragma('dart2js:parameter:trust')
63+
String test2(Base<T> other) {
64+
if (other is D2<T>) return other.bar();
65+
return 'other';
66+
}
67+
68+
@pragma('dart2js:never-inline')
69+
/*member: Base.method:ignore*/
70+
String method() => 'Base.method';
71+
}
72+
73+
class D1<T extends num> extends Base<T> {
74+
@pragma('dart2js:never-inline')
75+
/*member: D1.foo:ignore*/
76+
String foo() => 'D1<$T>.foo';
77+
}
78+
79+
class D2<T extends num> extends D1<T> {
80+
@pragma('dart2js:never-inline')
81+
/*member: D2.bar:ignore*/
82+
String bar() => 'D2.bar';
83+
}
84+
85+
/*member: main:ignore*/
86+
main() {
87+
final items = [Base<int>(), D1<int>(), D2<int>()];
88+
89+
for (final item in items) {
90+
print(item.test1(items.first));
91+
print(item.test1(item));
92+
93+
print(item.test1qn(items.first));
94+
print(item.test1qn(item));
95+
print(item.test1nq(items.first));
96+
print(item.test1nq(item));
97+
print(item.test1qq(items.first));
98+
print(item.test1qq(item));
99+
100+
print(item.test2(items.first));
101+
print(item.test2(item));
102+
}
103+
}

0 commit comments

Comments
 (0)