[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