Skip to content

Commit 7e8348f

Browse files
fishythefishcommit-bot@chromium.org
authored andcommitted
[dart2js] Assume isPotentialSubtype is always true.
The current implementation of this check is incorrect and produces false negatives. Conservatively assuming that one type is always a potential subtype of another is a simple fix to get this working. The main downsides are that we may emit signatures and provide type arguments to functions even when they're not needed because we no longer statically deduce that a type check must fail. This may cause size regressions. I've added a TODO to add proper constraint solving per the local type inference spec, but this is not currently a priority since no regression is observed on large Google apps. Change-Id: Ie5065596331c33a030e06e66481f258ef937e659 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/155544 Reviewed-by: Stephen Adams <sra@google.com> Commit-Queue: Mayank Patke <fishythefish@google.com>
1 parent 5671730 commit 7e8348f

17 files changed

+89
-87
lines changed

pkg/compiler/lib/src/elements/types.dart

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,6 +1915,11 @@ abstract class DartTypes {
19151915

19161916
bool _subtypeHelper(DartType s, DartType t,
19171917
{bool allowPotentialSubtypes: false, bool assumeInstantiations: false}) {
1918+
assert(allowPotentialSubtypes || !assumeInstantiations);
1919+
1920+
// TODO(fishythefish): Add constraint solving for potential subtypes.
1921+
if (allowPotentialSubtypes) return true;
1922+
19181923
/// Based on
19191924
/// https://github.com/dart-lang/language/blob/master/resources/type-system/subtyping.md.
19201925
/// See also [_isSubtype] in `dart:_rti`.
@@ -1927,10 +1932,6 @@ abstract class DartTypes {
19271932
env.isAssumed(s, t)) return true;
19281933

19291934
if (s is AnyType) return true;
1930-
if (allowPotentialSubtypes &&
1931-
(s is TypeVariableType || t is TypeVariableType)) return true;
1932-
if (assumeInstantiations &&
1933-
(s is FunctionTypeVariable || t is FunctionTypeVariable)) return true;
19341935

19351936
// Right Top:
19361937
if (isTopType(t)) return true;
@@ -2039,10 +2040,10 @@ abstract class DartTypes {
20392040
List<FunctionTypeVariable> sTypeVariables = s.typeVariables;
20402041
List<FunctionTypeVariable> tTypeVariables = t.typeVariables;
20412042
int length = tTypeVariables.length;
2042-
if (length == sTypeVariables.length) {
2043-
env ??= _Assumptions();
2044-
env.assumePairs(sTypeVariables, tTypeVariables);
2045-
} else if (!assumeInstantiations || length > 0) return false;
2043+
if (length != sTypeVariables.length) return false;
2044+
2045+
env ??= _Assumptions();
2046+
env.assumePairs(sTypeVariables, tTypeVariables);
20462047
try {
20472048
for (int i = 0; i < length; i++) {
20482049
DartType sBound = sTypeVariables[i].bound;

pkg/compiler/test/rti/data/async_local_typed.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ main() async {
1313
// `dynamic Function(dynamic, Class<int>)`, is not a potential subtype and
1414
// therefore doesn't need its signature.
1515

16-
/*spec.needsSignature*/
16+
/*needsSignature*/
1717
local(object, Class<int> stacktrace) => null;
1818

1919
return local;

pkg/compiler/test/rti/data/closure_generic_unneeded.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
// @dart = 2.7
66

77
/*spec.class: A:direct,explicit=[A.T*],needsArgs*/
8+
/*prod.class: A:needsArgs*/
89
class A<T> {
910
@pragma('dart2js:noInline')
1011
m() {
11-
return (T t, String s) {};
12+
return /*needsSignature*/(T t, String s) {};
1213
}
1314
}
1415

pkg/compiler/test/rti/data/closure_unneeded.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,11 @@
55
// @dart = 2.7
66

77
/*spec.class: A:direct,explicit=[A.T*],needsArgs*/
8+
/*prod.class: A:needsArgs*/
89
class A<T> {
910
@pragma('dart2js:noInline')
1011
m() {
11-
return (T t, String s) {};
12+
return /*needsSignature*/(T t, String s) {};
1213
}
1314
}
1415

pkg/compiler/test/rti/data/generic_bounds.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ class Class4 {}
4141
method10<T extends Class4>() => null;
4242

4343
main() {
44-
/*spec.needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
44+
/*needsArgs,needsSignature,selectors=[Selector(call, call, arity=0, types=1)]*/
4545
method7<T extends Class1a>() => null;
4646

47-
/*spec.needsArgs,selectors=[Selector(call, call, arity=0, types=1)]*/
47+
/*needsArgs,needsSignature,selectors=[Selector(call, call, arity=0, types=1)]*/
4848
method8<T extends Class2a<num>>() => null;
4949

50-
method9<T>() => null;
50+
/*needsArgs,needsSignature,selectors=[Selector(call, call, arity=0, types=1)]*/method9<T>() => null;
5151

5252
dynamic f1 = method1;
5353
dynamic f2 = method2;

pkg/compiler/test/rti/data/instantiation3.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class B<S> {
1515
F<S> c;
1616

1717
method() {
18-
return () {
18+
return /*spec.needsSignature*/() {
1919
c = f;
2020
};
2121
}

pkg/compiler/test/rti/data/instantiation4.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class B<S> {
1515
F<S> c;
1616

1717
method() {
18-
return () {
18+
return /*spec.needsSignature*/() {
1919
c = f;
2020
};
2121
}

pkg/compiler/test/rti/data/local_function_map_literal.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import 'package:expect/expect.dart';
1313
/*spec.member: method:implicit=[method.T],indirect,needsArgs*/
1414
/*prod.member: method:needsArgs*/
1515
method<T>() {
16-
return () => <T, int>{};
16+
return /*spec.needsSignature*/() => <T, int>{};
1717
}
1818

1919
@pragma('dart2js:noInline')

pkg/compiler/test/rti/data/local_function_signature2.dart

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@ import 'package:expect/expect.dart';
88

99
class Class1 {
1010
method1() {
11-
num local<T>(num n) => null;
11+
/*needsArgs,needsSignature*/num local<T>(num n) => null;
1212
return local;
1313
}
1414

1515
method2() {
16-
num local<T>(int n) => null;
16+
/*needsArgs,needsSignature*/num local<T>(int n) => null;
1717
return local;
1818
}
1919

2020
method3() {
21-
int local<T>(num n) => null;
21+
/*needsArgs,needsSignature*/int local<T>(num n) => null;
2222
return local;
2323
}
2424
}
@@ -43,9 +43,10 @@ class Class3 {
4343
}
4444

4545
class Class4 {
46+
/*prod.member: Class4.method6:needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
4647
/*spec.member: Class4.method6:direct,explicit=[method6.T*],needsArgs,selectors=[Selector(call, method6, arity=0, types=1)]*/
4748
method6<T>() {
48-
num local(num n, T t) => null;
49+
/*needsSignature*/num local(num n, T t) => null;
4950
return local;
5051
}
5152
}
@@ -66,25 +67,26 @@ method8<T>() {
6667
}
6768

6869
/*spec.member: method9:direct,explicit=[method9.T*],needsArgs*/
70+
/*prod.member: method9:needsArgs*/
6971
method9<T>() {
70-
num local(num n, T t) => null;
72+
/*needsSignature*/num local(num n, T t) => null;
7173
return local;
7274
}
7375

7476
method10() {
75-
/*spec.direct,explicit=[local.T*],needsArgs*/
76-
num local<T>(T n) => null;
77+
/*spec.direct,explicit=[local.T*],needsArgs,needsSignature*/
78+
/*prod.needsArgs,needsSignature*/num local<T>(T n) => null;
7779
return local;
7880
}
7981

8082
method11() {
81-
T local<T>(num n) => null;
83+
/*needsArgs,needsSignature*/T local<T>(num n) => null;
8284
return local;
8385
}
8486

8587
method12() {
86-
/*spec.direct,explicit=[local.T*],needsArgs*/
87-
num local<T>(num n, T t) => null;
88+
/*spec.direct,explicit=[local.T*],needsArgs,needsSignature*/
89+
/*prod.needsArgs,needsSignature*/num local<T>(num n, T t) => null;
8890
return local;
8991
}
9092

pkg/compiler/test/rti/data/local_function_signatures.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ class Class1 {
1414
}
1515

1616
method2() {
17-
num local(int n) => null;
17+
/*needsSignature*/num local(int n) => null;
1818
return local;
1919
}
2020

2121
method3() {
22-
Object local(num n) => null;
22+
/*needsSignature*/Object local(num n) => null;
2323
return local;
2424
}
2525
}
@@ -44,9 +44,10 @@ class Class3<T> {
4444
}
4545

4646
/*spec.class: Class4:direct,explicit=[Class4.T*],needsArgs*/
47+
/*prod.class: Class4:needsArgs*/
4748
class Class4<T> {
4849
method6() {
49-
num local(num n, T t) => null;
50+
/*needsSignature*/num local(num n, T t) => null;
5051
return local;
5152
}
5253
}

0 commit comments

Comments
 (0)