Add a Type parameter to Factory and update one method

Change-Id: I7ebcd3eb8a3761d9dfe0898380bcda1e574795ab
Reviewed-on: https://dart-review.googlesource.com/60980
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
diff --git a/pkg/front_end/lib/src/fasta/kernel/factory.dart b/pkg/front_end/lib/src/fasta/kernel/factory.dart
index d04b991..64bb7a1 100644
--- a/pkg/front_end/lib/src/fasta/kernel/factory.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/factory.dart
@@ -2,6 +2,8 @@
 // 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/scanner/token.dart' show Token;
+
 import 'package:kernel/ast.dart' show Catch, DartType, FunctionType, Node;
 
 import 'package:kernel/type_algebra.dart' show Substitution;
@@ -12,9 +14,14 @@
 /// Abstract base class for factories that can construct trees of expressions,
 /// statements, initializers, and literal types based on tokens, inferred types,
 /// and invocation targets.
-abstract class Factory<Expression, Statement, Initializer> {
+abstract class Factory<Expression, Statement, Initializer, Type> {
   Expression asExpression(
-      ExpressionJudgment judgment, int fileOffset, DartType inferredType);
+      ExpressionJudgment judgment,
+      int fileOffset,
+      Expression expression,
+      Token asOperator,
+      Type type,
+      DartType inferredType);
 
   Initializer assertInitializer(InitializerJudgment judgment, int fileOffset);
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_factory.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_factory.dart
index 3199532..786f3e5 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_factory.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_factory.dart
@@ -2,6 +2,8 @@
 // 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/scanner/token.dart' show Token;
+
 import 'package:kernel/ast.dart'
     show
         Catch,
@@ -21,10 +23,16 @@
 
 /// Implementation of [Factory] that builds source code into a kernel
 /// representation.
-class KernelFactory implements Factory<Expression, Statement, Initializer> {
+class KernelFactory
+    implements Factory<Expression, Statement, Initializer, DartType> {
   @override
   Expression asExpression(
-      ExpressionJudgment judgment, int fileOffset, DartType inferredType) {
+      ExpressionJudgment judgment,
+      int fileOffset,
+      Expression expression,
+      Token asOperator,
+      DartType type,
+      DartType inferredType) {
     return judgment;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index a86bfae..5833f1e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -157,9 +157,9 @@
   ExpressionJudgment get judgment => operand;
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     inferrer.inferExpression(factory, judgment, const UnknownType(), false);
     inferredType = type;
@@ -175,8 +175,9 @@
   AssertStatementJudgment get judgment => statement;
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     inferrer.inferStatement(factory, judgment);
   }
 }
@@ -196,8 +197,9 @@
   ExpressionJudgment get messageJudgment => message;
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     var conditionJudgment = this.conditionJudgment;
     var messageJudgment = this.messageJudgment;
     var expectedType = inferrer.coreTypes.boolClass.rawType;
@@ -221,9 +223,9 @@
   ExpressionJudgment get judgment => operand;
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     if (!inferrer.typeSchemaEnvironment.isEmptyContext(typeContext)) {
       typeContext = inferrer.wrapFutureOrType(typeContext);
@@ -241,8 +243,9 @@
   ShadowBlock(List<Statement> statements) : super(statements);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     for (var statement in statements) {
       inferrer.inferStatement(factory, statement);
     }
@@ -256,9 +259,9 @@
   BoolJudgment(bool value) : super(value);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     inferredType = inferrer.coreTypes.boolClass.rawType;
     return inferredType;
@@ -271,8 +274,9 @@
   ShadowBreakStatement(LabeledStatement target) : super(target);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     // No inference needs to be done.
   }
 }
@@ -333,9 +337,9 @@
   }
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     var lhsType = inferrer.inferExpression(
         factory, variable.initializer, typeContext, true);
@@ -474,9 +478,9 @@
       '$runtimeType', 'ShadowComplexAssignment._getWriteType', -1, null);
 
   _ComplexAssignmentInferenceResult
-      _inferRhs<Expression, Statement, Initializer>(
+      _inferRhs<Expression, Statement, Initializer, Type>(
           ShadowTypeInferrer inferrer,
-          Factory<Expression, Statement, Initializer> factory,
+          Factory<Expression, Statement, Initializer, Type> factory,
           DartType readType,
           DartType writeContext) {
     assert(writeContext != null);
@@ -588,9 +592,9 @@
     return parts;
   }
 
-  DartType _inferReceiver<Expression, Statement, Initializer>(
+  DartType _inferReceiver<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+      Factory<Expression, Statement, Initializer, Type> factory) {
     if (receiver != null) {
       var receiverType = inferrer.inferExpression(
           factory, receiver, const UnknownType(), true);
@@ -616,9 +620,9 @@
       : super(condition, then, otherwise, null);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     var expectedType = inferrer.coreTypes.boolClass.rawType;
     var conditionType = inferrer.inferExpression(
@@ -670,9 +674,9 @@
       : super(target, arguments, isConst: isConst);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     var library = inferrer.engine.beingInferred[target];
     if (library != null) {
@@ -766,8 +770,9 @@
   ShadowContinueSwitchStatement(SwitchCase target) : super(target);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     // No inference needs to be done.
   }
 }
@@ -780,9 +785,9 @@
       : super(variable, body);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     // Since the variable is not used in the body we don't need to type infer
     // it.  We can just type infer the body.
@@ -796,8 +801,9 @@
       : super(body, condition);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     inferrer.inferStatement(factory, body);
     var boolType = inferrer.coreTypes.boolClass.rawType;
     var actualType = inferrer.inferExpression(
@@ -814,9 +820,9 @@
   ShadowDoubleLiteral(double value) : super(value);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     return inferrer.coreTypes.doubleClass.rawType;
   }
@@ -829,9 +835,9 @@
 
   /// Calls back to [inferrer] to perform type inference for whatever concrete
   /// type of [ExpressionJudgment] this is.
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext);
 }
 
@@ -839,8 +845,9 @@
 class EmptyStatementJudgment extends EmptyStatement
     implements StatementJudgment {
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     // No inference needs to be done.
   }
 }
@@ -851,8 +858,9 @@
   ShadowExpressionStatement(Expression expression) : super(expression);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     inferrer.inferExpression(factory, expression, const UnknownType(), false);
   }
 }
@@ -887,9 +895,9 @@
       : super(target, arguments, isConst: isConst);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     var inferredType = inferrer.inferInvocation(
         factory,
@@ -971,8 +979,9 @@
   ShadowFieldInitializer(Field field, Expression value) : super(field, value);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     var initializerType =
         inferrer.inferExpression(factory, value, field.type, true);
     inferrer.ensureAssignable(field.type, initializerType, value, fileOffset);
@@ -991,8 +1000,9 @@
       : super(variable, iterable, body, isAsync: isAsync);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     var iterableClass = isAsync
         ? inferrer.coreTypes.streamClass
         : inferrer.coreTypes.iterableClass;
@@ -1082,8 +1092,9 @@
       : super(variables, condition, updates, body);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     for (var variable in variables) {
       inferrer.inferStatement(factory, variable);
     }
@@ -1111,8 +1122,9 @@
       : super(variable, function);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     inferrer.inferMetadataKeepingHelper(factory, variable.annotations);
     inferrer.inferLocalFunction(
         factory,
@@ -1139,9 +1151,9 @@
   ShadowFunctionExpression(FunctionNode function) : super(function);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     return inferrer.inferLocalFunction(
         factory, function, typeContext, fileOffset, null);
@@ -1170,9 +1182,9 @@
   Expression get _rhs => body.then;
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     // To infer `e0 ?? e1` in context K:
     // - Infer e0 in context K to get T0
@@ -1205,8 +1217,9 @@
       : super(condition, then, otherwise);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     var expectedType = inferrer.coreTypes.boolClass.rawType;
     var conditionType = inferrer.inferExpression(
         factory, condition, expectedType, !inferrer.isTopLevel);
@@ -1228,9 +1241,9 @@
   }
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     if (write != null) {
       inferrer.inferExpression(factory, write, const UnknownType(), false);
@@ -1270,9 +1283,9 @@
   }
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     var receiverType = _inferReceiver(inferrer, factory);
     var writeMember = inferrer.findMethodInvocationMember(receiverType, write);
@@ -1338,8 +1351,9 @@
 abstract class InitializerJudgment implements Initializer {
   /// Performs type inference for whatever concrete type of [InitializerJudgment]
   /// this is.
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory);
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory);
 }
 
 /// Concrete shadow object representing an integer literal in kernel form.
@@ -1349,9 +1363,9 @@
   ShadowIntLiteral(int value) : super(value);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     return inferrer.coreTypes.intClass.rawType;
   }
@@ -1363,8 +1377,9 @@
   ShadowInvalidInitializer(VariableDeclaration variable) : super(variable);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     inferrer.inferExpression(
         factory, variable.initializer, const UnknownType(), false);
   }
@@ -1377,9 +1392,9 @@
   ShadowIsExpression(Expression operand, DartType type) : super(operand, type);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     inferrer.inferExpression(factory, operand, const UnknownType(), false);
     return inferrer.coreTypes.boolClass.rawType;
@@ -1394,9 +1409,9 @@
       : super(new IsExpression(operand, type)..fileOffset = charOffset);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     IsExpression isExpression = this.operand;
     inferrer.inferExpression(
@@ -1413,8 +1428,9 @@
   StatementJudgment get judgment => body;
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     inferrer.inferStatement(factory, judgment);
   }
 }
@@ -1433,9 +1449,9 @@
             isConst: isConst);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     var listClass = inferrer.coreTypes.listClass;
     var listType = listClass.thisType;
@@ -1500,9 +1516,9 @@
       : super(left, operator, right);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     var boolType = inferrer.coreTypes.boolClass.rawType;
     var leftType =
@@ -1525,8 +1541,9 @@
   ShadowLoopAssignmentStatement(Expression expression) : super(expression);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {}
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {}
 }
 
 /// Shadow object for [MapLiteral].
@@ -1546,9 +1563,9 @@
             isConst: isConst);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     var mapClass = inferrer.coreTypes.mapClass;
     var mapType = mapClass.thisType;
@@ -1658,9 +1675,9 @@
         super(receiver, name, arguments, interfaceTarget);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     return inferrer.inferMethodInvocation(
         factory, this, receiver, fileOffset, _isImplicitCall, typeContext,
@@ -1684,9 +1701,9 @@
       : super(variable, new VariableGet(variable));
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     var inferredType = inferrer.inferExpression(
         factory, variable.initializer, typeContext, true);
@@ -1702,9 +1719,9 @@
   ShadowNot(Expression operand) : super(operand);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     // First infer the receiver so we can look up the method that was invoked.
     var boolType = inferrer.coreTypes.boolClass.rawType;
@@ -1734,9 +1751,9 @@
   MethodInvocation get _desugaredInvocation => body.otherwise;
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     var inferredType = inferrer.inferMethodInvocation(
         factory, this, variable.initializer, fileOffset, false, typeContext,
@@ -1767,9 +1784,9 @@
   PropertyGet get _desugaredGet => body.otherwise;
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     var inferredType = inferrer.inferPropertyGet(
         factory, this, variable.initializer, fileOffset, typeContext,
@@ -1786,9 +1803,9 @@
   DartType inferredType;
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     return inferrer.coreTypes.nullClass.rawType;
   }
@@ -1856,9 +1873,9 @@
   }
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     var receiverType = _inferReceiver(inferrer, factory);
 
@@ -1898,9 +1915,9 @@
       : super.byReference(receiver, name, interfaceTargetReference);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     return inferrer.inferPropertyGet(
         factory, this, receiver, fileOffset, typeContext,
@@ -1916,8 +1933,8 @@
       : super(target, arguments);
 
   @override
-  infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  infer<Expression, Statement, Initializer, Type>(ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     List<TypeParameter> classTypeParameters =
         target.enclosingClass.typeParameters;
     List<DartType> typeArguments =
@@ -1938,9 +1955,9 @@
   DartType inferredType;
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     return const BottomType();
   }
@@ -1952,8 +1969,9 @@
   ShadowReturnStatement([Expression expression]) : super(expression);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     var closureContext = inferrer.closureContext;
     var typeContext = !closureContext.isGenerator
         ? closureContext.returnOrYieldContext
@@ -1976,8 +1994,9 @@
 abstract class StatementJudgment extends Statement {
   /// Calls back to [inferrer] to perform type inference for whatever concrete
   /// type of [StatementJudgment] this is.
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> statement);
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> statement);
 }
 
 /// Concrete shadow object representing an assignment to a static variable.
@@ -1991,9 +2010,9 @@
   }
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     DartType readType = const DynamicType(); // Only used in error recovery
     var read = this.read;
@@ -2026,9 +2045,9 @@
   ShadowStaticGet(Member target) : super(target);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     var target = this.target;
     if (target is ShadowField && target.inferenceNode != null) {
@@ -2053,9 +2072,9 @@
       : super(target, arguments, isConst: isConst);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     var calleeType = target.function.functionType;
     return inferrer.inferInvocation(factory, typeContext, fileOffset,
@@ -2071,9 +2090,9 @@
   ShadowStringConcatenation(List<Expression> expressions) : super(expressions);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     if (!inferrer.isTopLevel) {
       for (kernel.Expression expression in expressions) {
@@ -2092,9 +2111,9 @@
   ShadowStringLiteral(String value) : super(value);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     return inferrer.coreTypes.stringClass.rawType;
   }
@@ -2107,8 +2126,9 @@
       : super(target, arguments);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     var substitution = Substitution.fromSupertype(inferrer.classHierarchy
         .getClassAsInstanceOf(
             inferrer.thisType.classNode, target.enclosingClass));
@@ -2134,9 +2154,9 @@
       : super(name, arguments, interfaceTarget);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     if (interfaceTarget != null) {
       inferrer.instrumentation?.record(inferrer.uri, fileOffset, 'target',
@@ -2159,9 +2179,9 @@
       : super(name, interfaceTarget);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     if (interfaceTarget != null) {
       inferrer.instrumentation?.record(inferrer.uri, fileOffset, 'target',
@@ -2180,8 +2200,9 @@
       : super(expression, cases);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     var expressionType = inferrer.inferExpression(
         factory, expression, const UnknownType(), true);
     for (var switchCase in cases) {
@@ -2201,9 +2222,9 @@
   ShadowSymbolLiteral(String value) : super(value);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     return inferrer.coreTypes.symbolClass.rawType;
   }
@@ -2230,9 +2251,9 @@
   }
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     _replaceWithDesugared();
     return const DynamicType();
@@ -2281,9 +2302,9 @@
   DartType inferredType;
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     return (inferrer.thisType ?? const DynamicType());
   }
@@ -2297,9 +2318,9 @@
   ThrowJudgment(Expression expression) : super(expression);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     inferrer.inferExpression(factory, judgment, const UnknownType(), false);
     return inferredType = const BottomType();
@@ -2311,8 +2332,9 @@
   ShadowTryCatch(Statement body, List<Catch> catches) : super(body, catches);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     inferrer.inferStatement(factory, body);
     for (var catch_ in catches) {
       inferrer.inferStatement(factory, catch_.body);
@@ -2326,8 +2348,9 @@
       : super(body, finalizer);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     inferrer.inferStatement(factory, body);
     inferrer.inferStatement(factory, finalizer);
   }
@@ -2379,8 +2402,8 @@
   }
 
   @override
-  DartType inferExpression<Expression, Statement, Initializer>(
-      Factory<Expression, Statement, Initializer> factory,
+  DartType inferExpression<Expression, Statement, Initializer, Type>(
+      Factory<Expression, Statement, Initializer, Type> factory,
       kernel.Expression expression,
       DartType typeContext,
       bool typeNeeded) {
@@ -2420,8 +2443,8 @@
   }
 
   @override
-  DartType inferFieldTopLevel<Expression, Statement, Initializer>(
-      Factory<Expression, Statement, Initializer> factory,
+  DartType inferFieldTopLevel<Expression, Statement, Initializer, Type>(
+      Factory<Expression, Statement, Initializer, Type> factory,
       ShadowField field,
       bool typeNeeded) {
     if (field.initializer == null) return const DynamicType();
@@ -2430,9 +2453,9 @@
   }
 
   @override
-  void inferInitializer<Expression, Statement, Initializer>(
+  void inferInitializer<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       kernel.Initializer initializer) {
     assert(initializer is InitializerJudgment);
     this.helper = helper;
@@ -2447,8 +2470,8 @@
   }
 
   @override
-  void inferStatement<Expression, Statement, Initializer>(
-      Factory<Expression, Statement, Initializer> factory,
+  void inferStatement<Expression, Statement, Initializer, Type>(
+      Factory<Expression, Statement, Initializer, Type> factory,
       Statement statement) {
     // For full (non-top level) inference, we need access to the
     // ExpressionGeneratorHelper so that we can perform error recovery.
@@ -2476,9 +2499,9 @@
   TypeLiteralJudgment(DartType type) : super(type);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     return inferredType = inferrer.coreTypes.typeClass.rawType;
   }
@@ -2563,9 +2586,9 @@
   }
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     DartType readType;
     var read = this.read;
@@ -2630,8 +2653,9 @@
         super.forValue(initializer);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     if (annotations.isNotEmpty) {
       inferrer.inferMetadataKeepingHelper(factory, annotations);
 
@@ -2707,9 +2731,9 @@
       : super(variable);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     ShadowVariableDeclaration variable = this.variable;
     bool mutatedInClosure = variable._mutatedInClosure;
@@ -2736,8 +2760,9 @@
       : super(condition, body);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     var expectedType = inferrer.coreTypes.boolClass.rawType;
     var actualType = inferrer.inferExpression(
         factory, condition, expectedType, !inferrer.isTopLevel);
@@ -2753,8 +2778,9 @@
       : super(expression, isYieldStar: isYieldStar);
 
   @override
-  void infer<Expression, Statement, Initializer>(ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory) {
+  void infer<Expression, Statement, Initializer, Type>(
+      ShadowTypeInferrer inferrer,
+      Factory<Expression, Statement, Initializer, Type> factory) {
     var closureContext = inferrer.closureContext;
     DartType inferredType;
     if (closureContext.isGenerator) {
@@ -2784,9 +2810,9 @@
   LoadLibraryJudgment(LibraryDependency import) : super(import);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     return inferredType = super.getStaticType(inferrer.typeSchemaEnvironment);
   }
@@ -2800,9 +2826,9 @@
   CheckLibraryIsLoadedJudgment(LibraryDependency import) : super(import);
 
   @override
-  DartType infer<Expression, Statement, Initializer>(
+  DartType infer<Expression, Statement, Initializer, Type>(
       ShadowTypeInferrer inferrer,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext) {
     return inferredType = super.getStaticType(inferrer.typeSchemaEnvironment);
   }
diff --git a/pkg/front_end/lib/src/fasta/kernel/toplevel_inference_factory.dart b/pkg/front_end/lib/src/fasta/kernel/toplevel_inference_factory.dart
index bb1bcc2..c154aec 100644
--- a/pkg/front_end/lib/src/fasta/kernel/toplevel_inference_factory.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/toplevel_inference_factory.dart
@@ -2,6 +2,8 @@
 // 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/scanner/token.dart' show Token;
+
 import 'package:kernel/ast.dart' show Catch, DartType, FunctionType, Node;
 
 import 'package:kernel/type_algebra.dart' show Substitution;
@@ -14,12 +16,12 @@
 /// Implementation of [Factory] for use during top level type inference, when
 /// no representation of the code semantics needs to be created (only the type
 /// needs to be inferred).
-class ToplevelInferenceFactory implements Factory<void, void, void> {
+class ToplevelInferenceFactory implements Factory<void, void, void, void> {
   const ToplevelInferenceFactory();
 
   @override
-  void asExpression(
-      ExpressionJudgment judgment, int fileOffset, DartType inferredType) {}
+  void asExpression(ExpressionJudgment judgment, int fileOffset,
+      void expression, Token asOperator, void type, DartType inferredType) {}
 
   @override
   void assertInitializer(InitializerJudgment judgment, int fileOffset) {}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 57c646f..d3184ec 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -325,43 +325,43 @@
   Uri get uri;
 
   /// Performs full type inference on the given field initializer.
-  void inferFieldInitializer<Expression, Statement, Initializer>(
+  void inferFieldInitializer<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType declaredType,
       kernel.Expression initializer);
 
   /// Performs type inference on the given function body.
-  void inferFunctionBody<Expression, Statement, Initializer>(
+  void inferFunctionBody<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType returnType,
       AsyncMarker asyncMarker,
       Statement body);
 
   /// Performs type inference on the given constructor initializer.
-  void inferInitializer<Expression, Statement, Initializer>(
+  void inferInitializer<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       kernel.Initializer initializer);
 
   /// Performs type inference on the given metadata annotations.
-  void inferMetadata<Expression, Statement, Initializer>(
+  void inferMetadata<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       List<kernel.Expression> annotations);
 
   /// Performs type inference on the given metadata annotations keeping the
   /// existing helper if possible.
-  void inferMetadataKeepingHelper<Expression, Statement, Initializer>(
-      Factory<Expression, Statement, Initializer> factory,
+  void inferMetadataKeepingHelper<Expression, Statement, Initializer, Type>(
+      Factory<Expression, Statement, Initializer, Type> factory,
       List<kernel.Expression> annotations);
 
   /// Performs type inference on the given function parameter initializer
   /// expression.
-  void inferParameterInitializer<Expression, Statement, Initializer>(
+  void inferParameterInitializer<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       kernel.Expression initializer,
       DartType declaredType);
 }
@@ -383,41 +383,41 @@
   Uri get uri => null;
 
   @override
-  void inferFieldInitializer<Expression, Statement, Initializer>(
+  void inferFieldInitializer<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType declaredType,
       kernel.Expression initializer) {}
 
   @override
-  void inferFunctionBody<Expression, Statement, Initializer>(
+  void inferFunctionBody<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
-      Factory<Expression, Statement, Initializer> statementFactory,
+      Factory<Expression, Statement, Initializer, Type> statementFactory,
       DartType returnType,
       AsyncMarker asyncMarker,
       Statement body) {}
 
   @override
-  void inferInitializer<Expression, Statement, Initializer>(
+  void inferInitializer<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       kernel.Initializer initializer) {}
 
   @override
-  void inferMetadata<Expression, Statement, Initializer>(
+  void inferMetadata<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       List<kernel.Expression> annotations) {}
 
   @override
-  void inferMetadataKeepingHelper<Expression, Statement, Initializer>(
-      Factory<Expression, Statement, Initializer> factory,
+  void inferMetadataKeepingHelper<Expression, Statement, Initializer, Type>(
+      Factory<Expression, Statement, Initializer, Type> factory,
       List<kernel.Expression> annotations) {}
 
   @override
-  void inferParameterInitializer<Expression, Statement, Initializer>(
+  void inferParameterInitializer<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       kernel.Expression initializer,
       DartType declaredType) {}
 }
@@ -998,16 +998,16 @@
   ///
   /// Derived classes should override this method with logic that dispatches on
   /// the expression type and calls the appropriate specialized "infer" method.
-  DartType inferExpression<Expression, Statement, Initializer>(
-      Factory<Expression, Statement, Initializer> factory,
+  DartType inferExpression<Expression, Statement, Initializer, Type>(
+      Factory<Expression, Statement, Initializer, Type> factory,
       kernel.Expression expression,
       DartType typeContext,
       bool typeNeeded);
 
   @override
-  void inferFieldInitializer<Expression, Statement, Initializer>(
+  void inferFieldInitializer<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType declaredType,
       kernel.Expression initializer) {
     assert(closureContext == null);
@@ -1025,15 +1025,15 @@
   ///
   /// Derived classes should provide an implementation that calls
   /// [inferExpression] for the given [field]'s initializer expression.
-  DartType inferFieldTopLevel<Expression, Statement, Initializer>(
-      Factory<Expression, Statement, Initializer> factory,
+  DartType inferFieldTopLevel<Expression, Statement, Initializer, Type>(
+      Factory<Expression, Statement, Initializer, Type> factory,
       ShadowField field,
       bool typeNeeded);
 
   @override
-  void inferFunctionBody<Expression, Statement, Initializer>(
+  void inferFunctionBody<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType returnType,
       AsyncMarker asyncMarker,
       Statement body) {
@@ -1048,8 +1048,8 @@
 
   /// Performs the type inference steps that are shared by all kinds of
   /// invocations (constructors, instance methods, and static methods).
-  DartType inferInvocation<Expression, Statement, Initializer>(
-      Factory<Expression, Statement, Initializer> factory,
+  DartType inferInvocation<Expression, Statement, Initializer, Type>(
+      Factory<Expression, Statement, Initializer, Type> factory,
       DartType typeContext,
       int offset,
       FunctionType calleeType,
@@ -1185,8 +1185,8 @@
     return inferredType;
   }
 
-  DartType inferLocalFunction<Expression, Statement, Initializer>(
-      Factory<Expression, Statement, Initializer> factory,
+  DartType inferLocalFunction<Expression, Statement, Initializer, Type>(
+      Factory<Expression, Statement, Initializer, Type> factory,
       FunctionNode function,
       DartType typeContext,
       int fileOffset,
@@ -1339,9 +1339,9 @@
   }
 
   @override
-  void inferMetadata<Expression, Statement, Initializer>(
+  void inferMetadata<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       List<kernel.Expression> annotations) {
     if (annotations != null) {
       this.helper = helper;
@@ -1351,8 +1351,8 @@
   }
 
   @override
-  void inferMetadataKeepingHelper<Expression, Statement, Initializer>(
-      Factory<Expression, Statement, Initializer> factory,
+  void inferMetadataKeepingHelper<Expression, Statement, Initializer, Type>(
+      Factory<Expression, Statement, Initializer, Type> factory,
       List<kernel.Expression> annotations) {
     if (annotations != null) {
       // Place annotations in a temporary list literal so that they will have a
@@ -1371,8 +1371,8 @@
 
   /// Performs the core type inference algorithm for method invocations (this
   /// handles both null-aware and non-null-aware method invocations).
-  DartType inferMethodInvocation<Expression, Statement, Initializer>(
-      Factory<Expression, Statement, Initializer> factory,
+  DartType inferMethodInvocation<Expression, Statement, Initializer, Type>(
+      Factory<Expression, Statement, Initializer, Type> factory,
       kernel.Expression expression,
       kernel.Expression receiver,
       int fileOffset,
@@ -1431,9 +1431,9 @@
   }
 
   @override
-  void inferParameterInitializer<Expression, Statement, Initializer>(
+  void inferParameterInitializer<Expression, Statement, Initializer, Type>(
       InferenceHelper helper,
-      Factory<Expression, Statement, Initializer> factory,
+      Factory<Expression, Statement, Initializer, Type> factory,
       kernel.Expression initializer,
       DartType declaredType) {
     assert(closureContext == null);
@@ -1447,8 +1447,8 @@
 
   /// Performs the core type inference algorithm for property gets (this handles
   /// both null-aware and non-null-aware property gets).
-  DartType inferPropertyGet<Expression, Statement, Initializer>(
-      Factory<Expression, Statement, Initializer> factory,
+  DartType inferPropertyGet<Expression, Statement, Initializer, Type>(
+      Factory<Expression, Statement, Initializer, Type> factory,
       kernel.Expression expression,
       kernel.Expression receiver,
       int fileOffset,
@@ -1504,8 +1504,9 @@
   ///
   /// Derived classes should override this method with logic that dispatches on
   /// the statement type and calls the appropriate specialized "infer" method.
-  void inferStatement<Expression, Statement, Initializer>(
-      Factory<Expression, Statement, Initializer> factory, Statement statement);
+  void inferStatement<Expression, Statement, Initializer, Type>(
+      Factory<Expression, Statement, Initializer, Type> factory,
+      Statement statement);
 
   /// Performs the type inference steps necessary to instantiate a tear-off
   /// (if necessary).