Skip to content

Commit 6a26527

Browse files
committed
[cfe] Fix off-by-one error in type variable target resolution
Change-Id: Ia0adbd27b9f3067d754851f081a25ac4a6126a7d Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/155128 Reviewed-by: Dmitry Stefantsov <[email protected]>
1 parent 2195fe3 commit 6a26527

6 files changed

+93
-1
lines changed

pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3175,7 +3175,7 @@ class TypeInferrerImpl implements TypeInferrer {
31753175
DartType step1 = resolveOneStep(hare);
31763176
if (step1 == null) return hare;
31773177
DartType step2 = resolveOneStep(step1);
3178-
if (step2 == null) return hare;
3178+
if (step2 == null) return step1;
31793179
hare = step2;
31803180

31813181
// Tortoise takes one step

pkg/front_end/testcases/general/type_variable_bound_access.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,25 @@ class NumClass<T extends num, S extends T> {
2222
num method2() => field1 + field2.length;
2323
}
2424

25+
class Class<X5 extends X4, X4 extends X3, X3 extends X2, X2 extends X1,
26+
X1 extends X0, X0 extends int> {
27+
X0 field0;
28+
X1 field1;
29+
X2 field2;
30+
X3 field3;
31+
X4 field4;
32+
X5 field5;
33+
34+
method() {
35+
field0.isEven;
36+
field1.isEven;
37+
field2.isEven;
38+
field3.isEven;
39+
field4.isEven;
40+
field5.isEven;
41+
}
42+
}
43+
2544
main() {
2645
new DynamicClass<num, int>(0.5, 2).method();
2746
new NumClass<num, double>(2, 0.5).method1();

pkg/front_end/testcases/general/type_variable_bound_access.dart.outline.expect

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,27 @@ class NumClass<T extends core::num* = core::num*, S extends self::NumClass::T* =
4040
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
4141
abstract member-signature get runtimeType() → core::Type*;
4242
}
43+
class Class<X5 extends self::Class::X4* = core::int*, X4 extends self::Class::X3* = core::int*, X3 extends self::Class::X2* = core::int*, X2 extends self::Class::X1* = core::int*, X1 extends self::Class::X0* = core::int*, X0 extends core::int* = core::int*> extends core::Object {
44+
generic-covariant-impl field self::Class::X0* field0;
45+
generic-covariant-impl field self::Class::X1* field1;
46+
generic-covariant-impl field self::Class::X2* field2;
47+
generic-covariant-impl field self::Class::X3* field3;
48+
generic-covariant-impl field self::Class::X4* field4;
49+
generic-covariant-impl field self::Class::X5* field5;
50+
synthetic constructor •() → self::Class<self::Class::X5*, self::Class::X4*, self::Class::X3*, self::Class::X2*, self::Class::X1*, self::Class::X0*>*
51+
;
52+
method method() → dynamic
53+
;
54+
abstract member-signature get _identityHashCode() → core::int*;
55+
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
56+
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
57+
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
58+
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
59+
abstract member-signature operator ==(dynamic other) → core::bool*;
60+
abstract member-signature get hashCode() → core::int*;
61+
abstract member-signature method toString() → core::String*;
62+
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
63+
abstract member-signature get runtimeType() → core::Type*;
64+
}
4365
static method main() → dynamic
4466
;

pkg/front_end/testcases/general/type_variable_bound_access.dart.strong.expect

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,35 @@ Try correcting the name to the name of an existing getter, or defining a getter
5353
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
5454
abstract member-signature get runtimeType() → core::Type*;
5555
}
56+
class Class<X5 extends self::Class::X4* = core::int*, X4 extends self::Class::X3* = core::int*, X3 extends self::Class::X2* = core::int*, X2 extends self::Class::X1* = core::int*, X1 extends self::Class::X0* = core::int*, X0 extends core::int* = core::int*> extends core::Object {
57+
generic-covariant-impl field self::Class::X0* field0 = null;
58+
generic-covariant-impl field self::Class::X1* field1 = null;
59+
generic-covariant-impl field self::Class::X2* field2 = null;
60+
generic-covariant-impl field self::Class::X3* field3 = null;
61+
generic-covariant-impl field self::Class::X4* field4 = null;
62+
generic-covariant-impl field self::Class::X5* field5 = null;
63+
synthetic constructor •() → self::Class<self::Class::X5*, self::Class::X4*, self::Class::X3*, self::Class::X2*, self::Class::X1*, self::Class::X0*>*
64+
: super core::Object::•()
65+
;
66+
method method() → dynamic {
67+
this.{self::Class::field0}.{core::int::isEven};
68+
this.{self::Class::field1}.{core::int::isEven};
69+
this.{self::Class::field2}.{core::int::isEven};
70+
this.{self::Class::field3}.{core::int::isEven};
71+
this.{self::Class::field4}.{core::int::isEven};
72+
this.{self::Class::field5}.{core::int::isEven};
73+
}
74+
abstract member-signature get _identityHashCode() → core::int*;
75+
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
76+
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
77+
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
78+
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
79+
abstract member-signature operator ==(dynamic other) → core::bool*;
80+
abstract member-signature get hashCode() → core::int*;
81+
abstract member-signature method toString() → core::String*;
82+
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
83+
abstract member-signature get runtimeType() → core::Type*;
84+
}
5685
static method main() → dynamic {
5786
new self::DynamicClass::•<core::num*, core::int*>(0.5, 2).{self::DynamicClass::method}();
5887
new self::NumClass::•<core::num*, core::double*>(2, 0.5).{self::NumClass::method1}();

pkg/front_end/testcases/general/type_variable_bound_access.dart.textual_outline.expect

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,15 @@ class NumClass<T extends num, S extends T> {
1313
num method2() => field1 + field2.length;
1414
}
1515

16+
class Class<X5 extends X4, X4 extends X3, X3 extends X2, X2 extends X1,
17+
X1 extends X0, X0 extends int> {
18+
X0 field0;
19+
X1 field1;
20+
X2 field2;
21+
X3 field3;
22+
X4 field4;
23+
X5 field5;
24+
method() {}
25+
}
26+
1627
main() {}

pkg/front_end/testcases/general/type_variable_bound_access.dart.textual_outline_modelled.expect

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
class Class<X5 extends X4, X4 extends X3, X3 extends X2, X2 extends X1,
2+
X1 extends X0, X0 extends int> {
3+
X0 field0;
4+
X1 field1;
5+
X2 field2;
6+
X3 field3;
7+
X4 field4;
8+
X5 field5;
9+
method() {}
10+
}
11+
112
class DynamicClass<T extends dynamic, S extends T> {
213
DynamicClass(this.field1, this.field2);
314
T field1;

0 commit comments

Comments
 (0)