[cfe] Account for class Record in constraint gathering Part of https://github.com/dart-lang/sdk/issues/49713 Change-Id: Idfcc304c8da8bb1a6cd887de707ddfd060934543 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/262427 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart index 8640b82..70a1ab4 100644 --- a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart +++ b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
@@ -834,6 +834,14 @@ _protoConstraints.length = baseConstraintCount; } + // A type P is a subtype match for Record with respect to L under no + // constraints: + // + // If P is a record type or Record. + if (q == coreTypes.recordNonNullableRawType && p is RecordType) { + return true; + } + // A record type `(M0,..., Mk, {M{k+1} d{k+1}, ..., Mm dm])` is a subtype // match for a record type `(N0,..., Nk, {N{k+1} d{k+1}, ..., Nm dm])` with // respect to `L` under constraints `C0 + ... + Cm`
diff --git a/pkg/front_end/testcases/records/simple_inference.dart b/pkg/front_end/testcases/records/simple_inference.dart index 8f3c99b..8f2cb41 100644 --- a/pkg/front_end/testcases/records/simple_inference.dart +++ b/pkg/front_end/testcases/records/simple_inference.dart
@@ -38,4 +38,13 @@ foo9(A9 a) {} +class A10<X, Y> {} + +A10<(T, T), T> foo10<T>() => throw 0; + +bar10() { + A10<Record, String> r = foo10(); +} + + main() {}
diff --git a/pkg/front_end/testcases/records/simple_inference.dart.strong.expect b/pkg/front_end/testcases/records/simple_inference.dart.strong.expect index bc3c922..590c2bc 100644 --- a/pkg/front_end/testcases/records/simple_inference.dart.strong.expect +++ b/pkg/front_end/testcases/records/simple_inference.dart.strong.expect
@@ -12,6 +12,11 @@ : super core::Object::•() ; } +class A10<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object { + synthetic constructor •() → self::A10<self::A10::X%, self::A10::Y%> + : super core::Object::•() + ; +} static method foo1((core::int, core::String?) r) → dynamic { (core::int, core::String?) r2 = r; } @@ -37,4 +42,9 @@ } static method foo8(self::A8<(dynamic, core::num), core::num> a) → dynamic {} static method foo9(self::A9<(core::num, core::String?), core::num, core::String?> a) → dynamic {} +static method foo10<T extends core::Object? = dynamic>() → self::A10<(self::foo10::T%, self::foo10::T%), self::foo10::T%> + return throw 0; +static method bar10() → dynamic { + self::A10<core::Record, core::String> r = self::foo10<core::String>(); +} static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/records/simple_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/records/simple_inference.dart.strong.transformed.expect index 60d1614..8ad5496 100644 --- a/pkg/front_end/testcases/records/simple_inference.dart.strong.transformed.expect +++ b/pkg/front_end/testcases/records/simple_inference.dart.strong.transformed.expect
@@ -12,6 +12,11 @@ : super core::Object::•() ; } +class A10<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object { + synthetic constructor •() → self::A10<self::A10::X%, self::A10::Y%> + : super core::Object::•() + ; +} static method foo1((core::int, core::String?) r) → dynamic { (core::int, core::String?) r2 = r; } @@ -37,6 +42,11 @@ } static method foo8(self::A8<(dynamic, core::num), core::num> a) → dynamic {} static method foo9(self::A9<(core::num, core::String?), core::num, core::String?> a) → dynamic {} +static method foo10<T extends core::Object? = dynamic>() → self::A10<(self::foo10::T%, self::foo10::T%), self::foo10::T%> + return throw 0; +static method bar10() → dynamic { + self::A10<core::Record, core::String> r = self::foo10<core::String>(); +} static method main() → dynamic {} @@ -45,4 +55,4 @@ Evaluated: VariableGetImpl @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5)) Evaluated: VariableGet @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5)) Evaluated: RecordLiteral @ org-dartlang-testcase:///simple_inference.dart:18:18 -> RecordConstant(const (3, 3.5)) -Extra constant evaluation: evaluated: 25, effectively constant: 4 +Extra constant evaluation: evaluated: 27, effectively constant: 4
diff --git a/pkg/front_end/testcases/records/simple_inference.dart.textual_outline.expect b/pkg/front_end/testcases/records/simple_inference.dart.textual_outline.expect index 167158a..d214e2e 100644 --- a/pkg/front_end/testcases/records/simple_inference.dart.textual_outline.expect +++ b/pkg/front_end/testcases/records/simple_inference.dart.textual_outline.expect
@@ -9,4 +9,7 @@ foo8(A8 a) {} class A9<X extends (Y, Z), Y extends num, Z extends String?> {} foo9(A9 a) {} +class A10<X, Y> {} +A10<(T, T), T> foo10<T>() => throw 0; +bar10() {} main() {}
diff --git a/pkg/front_end/testcases/records/simple_inference.dart.weak.expect b/pkg/front_end/testcases/records/simple_inference.dart.weak.expect index bc3c922..590c2bc 100644 --- a/pkg/front_end/testcases/records/simple_inference.dart.weak.expect +++ b/pkg/front_end/testcases/records/simple_inference.dart.weak.expect
@@ -12,6 +12,11 @@ : super core::Object::•() ; } +class A10<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object { + synthetic constructor •() → self::A10<self::A10::X%, self::A10::Y%> + : super core::Object::•() + ; +} static method foo1((core::int, core::String?) r) → dynamic { (core::int, core::String?) r2 = r; } @@ -37,4 +42,9 @@ } static method foo8(self::A8<(dynamic, core::num), core::num> a) → dynamic {} static method foo9(self::A9<(core::num, core::String?), core::num, core::String?> a) → dynamic {} +static method foo10<T extends core::Object? = dynamic>() → self::A10<(self::foo10::T%, self::foo10::T%), self::foo10::T%> + return throw 0; +static method bar10() → dynamic { + self::A10<core::Record, core::String> r = self::foo10<core::String>(); +} static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/records/simple_inference.dart.weak.modular.expect b/pkg/front_end/testcases/records/simple_inference.dart.weak.modular.expect index bc3c922..590c2bc 100644 --- a/pkg/front_end/testcases/records/simple_inference.dart.weak.modular.expect +++ b/pkg/front_end/testcases/records/simple_inference.dart.weak.modular.expect
@@ -12,6 +12,11 @@ : super core::Object::•() ; } +class A10<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object { + synthetic constructor •() → self::A10<self::A10::X%, self::A10::Y%> + : super core::Object::•() + ; +} static method foo1((core::int, core::String?) r) → dynamic { (core::int, core::String?) r2 = r; } @@ -37,4 +42,9 @@ } static method foo8(self::A8<(dynamic, core::num), core::num> a) → dynamic {} static method foo9(self::A9<(core::num, core::String?), core::num, core::String?> a) → dynamic {} +static method foo10<T extends core::Object? = dynamic>() → self::A10<(self::foo10::T%, self::foo10::T%), self::foo10::T%> + return throw 0; +static method bar10() → dynamic { + self::A10<core::Record, core::String> r = self::foo10<core::String>(); +} static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/records/simple_inference.dart.weak.outline.expect b/pkg/front_end/testcases/records/simple_inference.dart.weak.outline.expect index 2630b16..6f27431 100644 --- a/pkg/front_end/testcases/records/simple_inference.dart.weak.outline.expect +++ b/pkg/front_end/testcases/records/simple_inference.dart.weak.outline.expect
@@ -10,6 +10,10 @@ synthetic constructor •() → self::A9<self::A9::X, self::A9::Y, self::A9::Z%> ; } +class A10<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object { + synthetic constructor •() → self::A10<self::A10::X%, self::A10::Y%> + ; +} static method foo1((core::int, core::String?) r) → dynamic ; static method foo2((core::int, core::String?) r, <X extends core::Object? = dynamic>() → X% f) → dynamic @@ -28,5 +32,9 @@ ; static method foo9(self::A9<(core::num, core::String?), core::num, core::String?> a) → dynamic ; +static method foo10<T extends core::Object? = dynamic>() → self::A10<(self::foo10::T%, self::foo10::T%), self::foo10::T%> + ; +static method bar10() → dynamic + ; static method main() → dynamic ;
diff --git a/pkg/front_end/testcases/records/simple_inference.dart.weak.transformed.expect b/pkg/front_end/testcases/records/simple_inference.dart.weak.transformed.expect index 60d1614..8ad5496 100644 --- a/pkg/front_end/testcases/records/simple_inference.dart.weak.transformed.expect +++ b/pkg/front_end/testcases/records/simple_inference.dart.weak.transformed.expect
@@ -12,6 +12,11 @@ : super core::Object::•() ; } +class A10<X extends core::Object? = dynamic, Y extends core::Object? = dynamic> extends core::Object { + synthetic constructor •() → self::A10<self::A10::X%, self::A10::Y%> + : super core::Object::•() + ; +} static method foo1((core::int, core::String?) r) → dynamic { (core::int, core::String?) r2 = r; } @@ -37,6 +42,11 @@ } static method foo8(self::A8<(dynamic, core::num), core::num> a) → dynamic {} static method foo9(self::A9<(core::num, core::String?), core::num, core::String?> a) → dynamic {} +static method foo10<T extends core::Object? = dynamic>() → self::A10<(self::foo10::T%, self::foo10::T%), self::foo10::T%> + return throw 0; +static method bar10() → dynamic { + self::A10<core::Record, core::String> r = self::foo10<core::String>(); +} static method main() → dynamic {} @@ -45,4 +55,4 @@ Evaluated: VariableGetImpl @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5)) Evaluated: VariableGet @ org-dartlang-testcase:///simple_inference.dart:14:18 -> RecordConstant(const (3, 3.5)) Evaluated: RecordLiteral @ org-dartlang-testcase:///simple_inference.dart:18:18 -> RecordConstant(const (3, 3.5)) -Extra constant evaluation: evaluated: 25, effectively constant: 4 +Extra constant evaluation: evaluated: 27, effectively constant: 4