[cfe] Thread OperationsCfe through and use it in constraint gatherer

This is the CFE counterpart to the similar update in the Analyzer:
https://dart-review.googlesource.com/c/sdk/+/343781

Change-Id: Ie0c177958d1e6cad9367456017aaf8848c4f1d29
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/346360
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/mixin_inferrer.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/mixin_inferrer.dart
index 10a8563..45d804e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/mixin_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/mixin_inferrer.dart
@@ -20,6 +20,7 @@
     show TypeSchemaStandardBounds;
 import '../../type_inference/type_constraint_gatherer.dart'
     show TypeConstraintGatherer;
+import '../../type_inference/type_inference_engine.dart';
 import '../../type_inference/type_schema.dart';
 import '../../type_inference/type_schema_environment.dart' show TypeConstraint;
 import 'hierarchy_builder.dart';
@@ -498,9 +499,11 @@
 
   TypeBuilderConstraintGatherer(
       this.hierarchy, Iterable<StructuralParameter> typeParameters,
-      {required bool isNonNullableByDefault})
+      {required bool isNonNullableByDefault,
+      required OperationsCfe typeOperations})
       : super.subclassing(typeParameters,
-            isNonNullableByDefault: isNonNullableByDefault);
+            isNonNullableByDefault: isNonNullableByDefault,
+            typeOperations: typeOperations);
 
   @override
   CoreTypes get coreTypes => hierarchy.coreTypes;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
index 297a0e7..f16cfb1 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
@@ -2625,7 +2625,8 @@
       gatherer = typeSchemaEnvironment.setupGenericTypeInference(
           listType, typeParametersToInfer, typeContext,
           isNonNullableByDefault: isNonNullableByDefault,
-          isConst: node.isConst);
+          isConst: node.isConst,
+          typeOperations: operations);
       inferredTypes = typeSchemaEnvironment.choosePreliminaryTypes(
           gatherer, typeParametersToInfer, null,
           isNonNullableByDefault: isNonNullableByDefault);
@@ -4637,7 +4638,8 @@
       gatherer = typeSchemaEnvironment.setupGenericTypeInference(
           mapType, typeParametersToInfer, typeContext,
           isNonNullableByDefault: isNonNullableByDefault,
-          isConst: node.isConst);
+          isConst: node.isConst,
+          typeOperations: operations);
       inferredTypes = typeSchemaEnvironment.choosePreliminaryTypes(
           gatherer, typeParametersToInfer, null,
           isNonNullableByDefault: isNonNullableByDefault);
@@ -4712,7 +4714,8 @@
             typeSchemaEnvironment.setupGenericTypeInference(
                 setType, typeParametersToInfer, typeContext,
                 isNonNullableByDefault: isNonNullableByDefault,
-                isConst: node.isConst);
+                isConst: node.isConst,
+                typeOperations: operations);
         List<DartType> inferredTypesForSet = typeSchemaEnvironment
             .choosePreliminaryTypes(gatherer, typeParametersToInfer, null,
                 isNonNullableByDefault: isNonNullableByDefault);
@@ -7946,7 +7949,8 @@
       gatherer = typeSchemaEnvironment.setupGenericTypeInference(
           setType, typeParametersToInfer, typeContext,
           isNonNullableByDefault: isNonNullableByDefault,
-          isConst: node.isConst);
+          isConst: node.isConst,
+          typeOperations: operations);
       inferredTypes = typeSchemaEnvironment.choosePreliminaryTypes(
           gatherer, typeParametersToInfer, null,
           isNonNullableByDefault: isNonNullableByDefault);
@@ -10948,7 +10952,8 @@
     TypeConstraintGatherer gatherer =
         typeSchemaEnvironment.setupGenericTypeInference(
             declaredType, typeParametersToInfer, contextType,
-            isNonNullableByDefault: isNonNullableByDefault);
+            isNonNullableByDefault: isNonNullableByDefault,
+            typeOperations: operations);
     return typeSchemaEnvironment.chooseFinalTypes(
         gatherer, typeParametersToInfer, null,
         isNonNullableByDefault: isNonNullableByDefault);
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart
index 6732ac6..dca0d58 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart
@@ -1011,7 +1011,8 @@
         new List<DartType>.filled(typeParameters.length, const UnknownType());
     TypeConstraintGatherer gatherer = typeSchemaEnvironment
         .setupGenericTypeInference(null, typeParameters, null,
-            isNonNullableByDefault: libraryBuilder.isNonNullableByDefault);
+            isNonNullableByDefault: libraryBuilder.isNonNullableByDefault,
+            typeOperations: cfeOperations);
     gatherer.constrainArguments([onType], [receiverType]);
     inferredTypes = typeSchemaEnvironment.chooseFinalTypes(
         gatherer, typeParameters, inferredTypes,
@@ -1755,7 +1756,8 @@
               : legacyErasure(calleeType.returnType),
           calleeTypeParameters,
           typeContext,
-          isNonNullableByDefault: isNonNullableByDefault);
+          isNonNullableByDefault: isNonNullableByDefault,
+          typeOperations: cfeOperations);
       inferredTypes = typeSchemaEnvironment.choosePreliminaryTypes(
           gatherer, calleeTypeParameters, null,
           isNonNullableByDefault: isNonNullableByDefault);
@@ -3608,7 +3610,8 @@
         TypeConstraintGatherer gatherer =
             typeSchemaEnvironment.setupGenericTypeInference(
                 instantiatedType, typeParameters, context,
-                isNonNullableByDefault: isNonNullableByDefault);
+                isNonNullableByDefault: isNonNullableByDefault,
+                typeOperations: cfeOperations);
         inferredTypes = typeSchemaEnvironment.chooseFinalTypes(
             gatherer, typeParameters, inferredTypes,
             isNonNullableByDefault: isNonNullableByDefault);
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 d60a750..911154c 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
@@ -12,6 +12,8 @@
 
 import '../names.dart' show callName;
 
+import 'type_inference_engine.dart';
+
 import 'type_schema.dart';
 
 import 'type_schema_environment.dart';
@@ -25,18 +27,24 @@
 
   final bool isNonNullableByDefault;
 
+  final OperationsCfe _typeOperations;
+
   /// Creates a [TypeConstraintGatherer] which is prepared to gather type
   /// constraints for the given [typeParameters].
   TypeConstraintGatherer.subclassing(
       Iterable<StructuralParameter> typeParameters,
-      {required this.isNonNullableByDefault})
-      : _parametersToConstrain = typeParameters.toList();
+      {required this.isNonNullableByDefault,
+      required OperationsCfe typeOperations})
+      : _parametersToConstrain = typeParameters.toList(),
+        _typeOperations = typeOperations;
 
   factory TypeConstraintGatherer(TypeSchemaEnvironment environment,
       Iterable<StructuralParameter> typeParameters,
-      {required bool isNonNullableByDefault}) {
+      {required bool isNonNullableByDefault,
+      required OperationsCfe typeOperations}) {
     return new TypeSchemaConstraintGatherer(environment, typeParameters,
-        isNonNullableByDefault: isNonNullableByDefault);
+        isNonNullableByDefault: isNonNullableByDefault,
+        typeOperations: typeOperations);
   }
 
   CoreTypes get coreTypes;
@@ -419,10 +427,10 @@
     if (p is InvalidType || q is InvalidType) return false;
 
     // If P is _ then the match holds with no constraints.
-    if (p is UnknownType) return true;
+    if (_typeOperations.isUnknownType(p)) return true;
 
     // If Q is _ then the match holds with no constraints.
-    if (q is UnknownType) return true;
+    if (_typeOperations.isUnknownType(q)) return true;
 
     // If P is a type variable X in L, then the match holds:
     //
@@ -1178,9 +1186,11 @@
 
   TypeSchemaConstraintGatherer(
       this.environment, Iterable<StructuralParameter> typeParameters,
-      {required bool isNonNullableByDefault})
+      {required bool isNonNullableByDefault,
+      required OperationsCfe typeOperations})
       : super.subclassing(typeParameters,
-            isNonNullableByDefault: isNonNullableByDefault);
+            isNonNullableByDefault: isNonNullableByDefault,
+            typeOperations: typeOperations);
 
   @override
   CoreTypes get coreTypes => environment.coreTypes;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
index 306943c..15e2625f 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
@@ -23,6 +23,8 @@
 
 import 'type_demotion.dart';
 
+import 'type_inference_engine.dart';
+
 import 'type_schema.dart' show UnknownType, typeSchemaToString, isKnown;
 
 import 'type_schema_elimination.dart' show greatestClosure, leastClosure;
@@ -375,7 +377,8 @@
       List<StructuralParameter> typeParametersToInfer,
       DartType? returnContextType,
       {required bool isNonNullableByDefault,
-      bool isConst = false}) {
+      bool isConst = false,
+      required OperationsCfe typeOperations}) {
     assert(typeParametersToInfer.isNotEmpty);
 
     // Create a TypeConstraintGatherer that will allow certain type parameters
@@ -384,7 +387,8 @@
     // are implied by this.
     TypeConstraintGatherer gatherer = new TypeConstraintGatherer(
         this, typeParametersToInfer,
-        isNonNullableByDefault: isNonNullableByDefault);
+        isNonNullableByDefault: isNonNullableByDefault,
+        typeOperations: typeOperations);
 
     if (!isEmptyContext(returnContextType)) {
       if (isConst) {
diff --git a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart
index acc786f..4c34bf6 100644
--- a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_nnbd_test.dart
@@ -2,7 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:front_end/src/fasta/source/source_library_builder.dart';
 import 'package:front_end/src/fasta/type_inference/type_constraint_gatherer.dart';
+import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
 import 'package:front_end/src/fasta/type_inference/type_schema.dart';
 import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
 import 'package:kernel/ast.dart';
@@ -392,7 +394,14 @@
         coreTypes, new ClassHierarchy(component, coreTypes));
     var typeConstraintGatherer = new TypeConstraintGatherer(
         typeSchemaEnvironment, typeParameterNodesToConstrain,
-        isNonNullableByDefault: testLibrary.isNonNullableByDefault);
+        isNonNullableByDefault: testLibrary.isNonNullableByDefault,
+        typeOperations: new OperationsCfe(typeSchemaEnvironment,
+            nullability: Nullability.nonNullable,
+            fieldNonPromotabilityInfo: new FieldNonPromotabilityInfo(
+                fieldNameInfo: {}, individualPropertyReasons: {}),
+            typeCacheNonNullable: {},
+            typeCacheNullable: {},
+            typeCacheLegacy: {}));
     var constraints = tryConstrain(typeConstraintGatherer, a, b)
         ? typeConstraintGatherer.computeConstraints(
             isNonNullableByDefault: clientLibrary.isNonNullableByDefault)
diff --git a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
index 3573e07..89e5eb7 100644
--- a/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_constraint_gatherer_test.dart
@@ -2,7 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:front_end/src/fasta/source/source_library_builder.dart';
 import 'package:front_end/src/fasta/type_inference/type_constraint_gatherer.dart';
+import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
 import 'package:front_end/src/fasta/type_inference/type_schema.dart';
 import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
 import 'package:kernel/ast.dart';
@@ -300,7 +302,14 @@
         coreTypes, new ClassHierarchy(component, coreTypes));
     var typeConstraintGatherer = new TypeConstraintGatherer(
         typeSchemaEnvironment, typeParameterNodesToConstrain,
-        isNonNullableByDefault: testLibrary.isNonNullableByDefault);
+        isNonNullableByDefault: testLibrary.isNonNullableByDefault,
+        typeOperations: new OperationsCfe(typeSchemaEnvironment,
+            nullability: Nullability.nonNullable,
+            fieldNonPromotabilityInfo: new FieldNonPromotabilityInfo(
+                fieldNameInfo: {}, individualPropertyReasons: {}),
+            typeCacheNonNullable: {},
+            typeCacheNullable: {},
+            typeCacheLegacy: {}));
     var constraints = tryConstrain(typeConstraintGatherer, a, b)
         ? typeConstraintGatherer.computeConstraints(
             isNonNullableByDefault: clientLibrary.isNonNullableByDefault)
diff --git a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test_base.dart b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test_base.dart
index ae0bba9..e36fdda 100644
--- a/pkg/front_end/test/fasta/type_inference/type_schema_environment_test_base.dart
+++ b/pkg/front_end/test/fasta/type_inference/type_schema_environment_test_base.dart
@@ -2,9 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
 import 'package:front_end/src/fasta/type_inference/type_constraint_gatherer.dart';
 import 'package:front_end/src/fasta/type_inference/type_schema.dart';
 import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
+import 'package:front_end/src/fasta/source/source_library_builder.dart';
 import 'package:kernel/ast.dart';
 import 'package:kernel/core_types.dart';
 import 'package:kernel/class_hierarchy.dart';
@@ -169,7 +171,14 @@
               declaredReturnTypeNode,
               typeParameterNodesToInfer,
               returnContextTypeNode,
-              isNonNullableByDefault: isNonNullableByDefault);
+              isNonNullableByDefault: isNonNullableByDefault,
+              typeOperations: new OperationsCfe(typeSchemaEnvironment,
+                  nullability: Nullability.nullable,
+                  fieldNonPromotabilityInfo: new FieldNonPromotabilityInfo(
+                      fieldNameInfo: {}, individualPropertyReasons: {}),
+                  typeCacheNonNullable: {},
+                  typeCacheNullable: {},
+                  typeCacheLegacy: {}));
       if (formalTypeNodes == null) {
         inferredTypeNodes = typeSchemaEnvironment.choosePreliminaryTypes(
             gatherer, typeParameterNodesToInfer, inferredTypeNodes,