Version 2.14.0-7.0.dev

Merge commit '47acb386d7ba8fb7d888e21d222d222c2033db7b' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml b/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml
index be674c8..24c5c54 100644
--- a/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml
+++ b/pkg/_fe_analyzer_shared/analysis_options_no_lints.yaml
@@ -17,4 +17,5 @@
     - test/flow_analysis/type_promotion/data/**
     - test/flow_analysis/why_not_promoted/data/**
     - test/inference/inferred_type_arguments/data/**
+    - test/inference/inferred_variable_types/data/**
     - test/inheritance/data/**
diff --git a/pkg/_fe_analyzer_shared/test/inference/inferred_type_arguments/data/bounded.dart b/pkg/_fe_analyzer_shared/test/inference/inferred_type_arguments/data/bounded.dart
new file mode 100644
index 0000000..47650a3
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/inference/inferred_type_arguments/data/bounded.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// 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.
+
+class Bound {}
+
+class BoundedGenericClass<A extends Bound?, B extends Bound> {}
+
+A boundedGenericA<A extends Bound?>() => throw '';
+B boundedGenericB<B extends Bound>() => throw '';
+
+class GenericClass<X extends Bound?, Y extends Bound> {
+  method() {
+    new BoundedGenericClass/*<Bound?,Bound>*/();
+    BoundedGenericClass<X, Y> class1a = new BoundedGenericClass/*<Never,Y>*/();
+    BoundedGenericClass<Y, Y> class1b = new BoundedGenericClass/*<Y,Y>*/();
+    BoundedGenericClass<Bound?, Bound> class1c =
+        new BoundedGenericClass/*<Bound?,Bound>*/();
+    BoundedGenericClass<Bound, Bound> class1d =
+        new BoundedGenericClass/*<Bound,Bound>*/();
+
+    boundedGenericA/*<Bound?>*/();
+    X x1 = boundedGenericA/*<Never>*/();
+    Y y1 = boundedGenericA/*<Y>*/();
+    Bound b1 = boundedGenericA/*<Bound>*/();
+    Bound? b2 = boundedGenericA/*<Bound?>*/();
+
+    boundedGenericB/*<Bound>*/();
+    Y y2 = boundedGenericB/*<Y>*/();
+    Bound b3 = boundedGenericB/*<Bound>*/();
+  }
+}
+
+genericMethod<X extends Bound?, Y extends Bound>() {
+  new BoundedGenericClass/*<Bound?,Bound>*/();
+  BoundedGenericClass<X, Y> class1a = new BoundedGenericClass/*<Never,Y>*/();
+  BoundedGenericClass<Y, Y> class1b = new BoundedGenericClass/*<Y,Y>*/();
+  BoundedGenericClass<Bound?, Bound> class1c =
+      new BoundedGenericClass/*<Bound?,Bound>*/();
+  BoundedGenericClass<Bound, Bound> class1d =
+      new BoundedGenericClass/*<Bound,Bound>*/();
+
+  boundedGenericA/*<Bound?>*/();
+  X x1 = boundedGenericA/*<Never>*/();
+  Y y1 = boundedGenericA/*<Y>*/();
+  Bound b1 = boundedGenericA/*<Bound>*/();
+  Bound? b2 = boundedGenericA/*<Bound?>*/();
+
+  boundedGenericB/*<Bound>*/();
+  Y y2 = boundedGenericB/*<Y>*/();
+  Bound b3 = boundedGenericB/*<Bound>*/();
+}
diff --git a/pkg/_fe_analyzer_shared/test/inference/inferred_type_arguments/data/collections.dart b/pkg/_fe_analyzer_shared/test/inference/inferred_type_arguments/data/collections.dart
new file mode 100644
index 0000000..ddac4f1
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/inference/inferred_type_arguments/data/collections.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// 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.
+
+num n = 0;
+int i = 1;
+double d = 2.5;
+String s = "";
+
+use(e) {}
+
+listLiteral() {
+  /*<dynamic>*/ [];
+  /*<num>*/ [n];
+  /*<num>*/ [n, i];
+  /*<num>*/ [n, i, d];
+  /*<String>*/ [s];
+  /*<Object>*/ [n, i, d, s];
+}
+
+setLiteral() {
+  use(/*<dynamic,dynamic>*/ {});
+  use(/*<num>*/ {n});
+  use(/*<num>*/ {n, i});
+  use(/*<num>*/ {n, i, d});
+  use(/*<String>*/ {s});
+  use(/*<Object>*/ {n, i, d, s});
+}
+
+mapLiteral() {
+  use(/*<dynamic,dynamic>*/ {});
+  use(/*<num,num>*/ {n: n});
+  use(/*<num,num>*/ {n: n, i: n});
+  use(/*<num,int>*/ {n: i, i: i});
+  use(/*<num,num>*/ {n: n, i: i, d: d});
+  use(/*<String,String>*/ {s: s});
+  use(/*<Object,Object>*/ {n: s, i: d, d: i, s: n});
+}
diff --git a/pkg/_fe_analyzer_shared/test/inference/inferred_variable_types/data/from_initializer.dart b/pkg/_fe_analyzer_shared/test/inference/inferred_variable_types/data/from_initializer.dart
new file mode 100644
index 0000000..40751d7
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/inference/inferred_variable_types/data/from_initializer.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// 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.
+
+String method() => '';
+T genericMethod<T>() => throw '';
+T boundedGenericMethod<T extends num>() => throw '';
+
+test() {
+  var /*dynamic*/ noInitializer;
+  var /*int*/ intLiteral = 0;
+  var /*String*/ methodCall = method();
+  var /*dynamic*/ genericMethodCall1 = genericMethod();
+  var /*int*/ genericMethodCall2 = genericMethod<int>();
+  var /*num*/ genericMethodCall3 = boundedGenericMethod();
+  var /*int*/ genericMethodCall4 = boundedGenericMethod<int>();
+}
diff --git a/pkg/_fe_analyzer_shared/test/inference/inferred_variable_types/data/local_functions.dart b/pkg/_fe_analyzer_shared/test/inference/inferred_variable_types/data/local_functions.dart
new file mode 100644
index 0000000..b95e4e0
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/inference/inferred_variable_types/data/local_functions.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// 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.
+
+localFunctions() {
+  /*Null*/ unrestrictedLocalFunction1(/*dynamic*/ o) {}
+  var /*Null Function(dynamic)*/ unrestrictedLocalFunction2 =
+      /*Null*/ (/*dynamic*/ o) {};
+
+  /*dynamic*/ arrowReturn1(/*dynamic*/ o) => o;
+  var /*dynamic Function(dynamic)*/ arrowReturn2 =
+      /*dynamic*/ (/*dynamic*/ o) => o;
+
+  /*dynamic*/ singleReturn1(/*dynamic*/ o) {
+    return o;
+  }
+
+  var /*dynamic Function(dynamic)*/ singleReturn2 =
+      /*dynamic*/ (/*dynamic*/ o) {
+    return o;
+  };
+
+  /*int*/ typedArrowReturn1() => 1;
+  var /*int Function()*/ typedArrowReturn2 = /*int*/ () => 1;
+
+  /*int*/ singleTypedReturn1() {
+    return 1;
+  }
+
+  var /*int Function()*/ singleTypedReturn2 = /*int*/ () {
+    return 1;
+  };
+
+  /*int?*/ multipleTypedReturns1(bool condition) {
+    if (condition) {
+      return 1;
+    } else {
+      return null;
+    }
+  }
+
+  var /*int? Function(bool)*/ multipleTypedReturns2 = /*int?*/ (bool
+      condition) {
+    if (condition) {
+      return 1;
+    } else {
+      return null;
+    }
+  };
+
+  int Function(String) inferredFromContext = /*int*/ (/*String*/ condition) =>
+      condition.length;
+}
diff --git a/pkg/_fe_analyzer_shared/test/inference/inferred_variable_types/data/marker.options b/pkg/_fe_analyzer_shared/test/inference/inferred_variable_types/data/marker.options
new file mode 100644
index 0000000..5669a4b
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/inference/inferred_variable_types/data/marker.options
@@ -0,0 +1 @@
+cfe=pkg/front_end/test/id_tests/inferred_variable_types_test.dart
\ No newline at end of file
diff --git a/pkg/_fe_analyzer_shared/test/inference/inferred_variable_types/data/promoted.dart b/pkg/_fe_analyzer_shared/test/inference/inferred_variable_types/data/promoted.dart
new file mode 100644
index 0000000..3e40f0e
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/inference/inferred_variable_types/data/promoted.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// 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.
+
+promoted<T, S extends num>(dynamic d, num n, T t, S s) {
+  var /*dynamic*/ unpromotedDynamic = d;
+  var /*num*/ unpromotedNum = n;
+  var /*T*/ unpromotedUnboundedTypeVariable = t;
+  var /*S*/ unpromotedBoundedTypeVariable = s;
+  if (d is int) {
+    var /*int*/ promotedDynamic = d;
+  }
+  if (n is int) {
+    var /*int*/ promotedInt = n;
+  }
+  if (t is int) {
+    var /*T*/ promotedUnboundedTypeVariable = t;
+  }
+  if (s is int) {
+    var /*S*/ unpromotedBoundedTypeVariable = s;
+  }
+  if (t is S) {
+    var /*T*/ promotedUnboundedTypeVariable = t;
+  }
+}
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index eed8576..a17ef22 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -554,9 +554,6 @@
         case ModularNameKind.operatorIsType:
           name.value = namer.operatorIsType(name.data);
           break;
-        case ModularNameKind.substitution:
-          name.value = namer.substitutionName(name.data);
-          break;
         case ModularNameKind.instanceMethod:
           name.value = namer.instanceMethodName(name.data);
           break;
@@ -630,7 +627,6 @@
   methodProperty,
   operatorIs,
   operatorIsType,
-  substitution,
   instanceMethod,
   instanceField,
   invocation,
@@ -666,7 +662,6 @@
       case ModularNameKind.runtimeTypeName:
       case ModularNameKind.className:
       case ModularNameKind.operatorIs:
-      case ModularNameKind.substitution:
       case ModularNameKind.globalPropertyNameForClass:
         data = source.readClass();
         break;
@@ -713,7 +708,6 @@
       case ModularNameKind.runtimeTypeName:
       case ModularNameKind.className:
       case ModularNameKind.operatorIs:
-      case ModularNameKind.substitution:
       case ModularNameKind.globalPropertyNameForClass:
         sink.writeClass(data);
         break;
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 4b1e667..82b1481 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -1201,10 +1201,10 @@
     return new StringBackedName(candidate);
   }
 
-  /// Returns a variant of [name] that cannot clash with the annotated
-  /// version of another name, that is, the resulting name can never be returned
-  /// by [deriveGetterName], [deriveSetterName], [deriveCallMethodName],
-  /// [operatorIs], or [substitutionName].
+  /// Returns a variant of [name] that cannot clash with the annotated version
+  /// of another name, that is, the resulting name can never be returned by
+  /// [deriveGetterName], [deriveSetterName], [deriveCallMethodName], or
+  /// [operatorIs].
   ///
   /// For example, a name `get$x` would be converted to `$get$x` to ensure it
   /// cannot clash with the getter for `x`.
@@ -1539,14 +1539,6 @@
   }
 
   @override
-  jsAst.Name substitutionName(ClassEntity element) {
-    return new CompoundName([
-      new StringBackedName(fixedNames.operatorAsPrefix),
-      runtimeTypeName(element)
-    ]);
-  }
-
-  @override
   jsAst.Name asName(String name) {
     if (name.startsWith(fixedNames.getterPrefix) &&
         name.length > fixedNames.getterPrefix.length) {
@@ -2262,7 +2254,6 @@
   String get defaultValuesField => r'$defaultValues';
   String get deferredAction => r'$deferredAction';
   String get operatorIsPrefix => r'$is';
-  String get operatorAsPrefix => r'$as';
   String get operatorSignature => r'$signature';
   String get requiredParameterField => r'$requiredArgCount';
   String get rtiName => r'$ti';
@@ -2283,8 +2274,6 @@
   @override
   String get operatorIsPrefix => r'$i';
   @override
-  String get operatorAsPrefix => r'$a';
-  @override
   String get callCatchAllName => r'$C';
   @override
   String get requiredParameterField => r'$R';
@@ -2408,9 +2397,8 @@
   /// for the given type.
   ///
   /// The result is not always safe as a property name unless prefixing
-  /// [operatorIsPrefix] or [operatorAsPrefix]. If this is a function type,
-  /// then by convention, an underscore must also separate [operatorIsPrefix]
-  /// from the type name.
+  /// [operatorIsPrefix]. If this is a function type, then by convention, an
+  /// underscore must also separate [operatorIsPrefix] from the type name.
   jsAst.Name runtimeTypeName(Entity element);
 
   /// Property name in which to store the given static or instance [method].
@@ -2428,10 +2416,6 @@
   /// Return the name of the `isX` property for classes that implement [type].
   jsAst.Name operatorIsType(DartType type);
 
-  /// Returns the name of the `asX` function for classes that implement the
-  /// generic class [element].
-  jsAst.Name substitutionName(ClassEntity element);
-
   /// Returns the name of the lazy initializer for the static field [element].
   jsAst.Name lazyInitializerName(FieldEntity element);
 
@@ -2563,8 +2547,6 @@
         return asName(fixedNames.callNameField);
       case JsGetName.DEFERRED_ACTION_PROPERTY:
         return asName(fixedNames.deferredAction);
-      case JsGetName.OPERATOR_AS_PREFIX:
-        return asName(fixedNames.operatorAsPrefix);
       case JsGetName.OPERATOR_IS_PREFIX:
         return asName(fixedNames.operatorIsPrefix);
       case JsGetName.SIGNATURE_NAME:
@@ -2775,12 +2757,4 @@
     _registry.registerModularName(name);
     return name;
   }
-
-  @override
-  jsAst.Name substitutionName(ClassEntity element) {
-    jsAst.Name name =
-        new ModularName(ModularNameKind.substitution, data: element);
-    _registry.registerModularName(name);
-    return name;
-  }
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index d17ce83..6bf25ce 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -1161,7 +1161,7 @@
     return const StatementInferenceResult();
   }
 
-  DartType visitFunctionNode(FunctionNode node, DartType typeContext,
+  FunctionType visitFunctionNode(FunctionNode node, DartType typeContext,
       DartType returnContext, int returnTypeInstrumentationOffset) {
     return inferrer.inferLocalFunction(
         node, typeContext, returnTypeInstrumentationOffset, returnContext);
@@ -1176,8 +1176,12 @@
         node.variable, node.variable.annotations);
     DartType returnContext =
         node.hasImplicitReturnType ? null : node.function.returnType;
-    DartType inferredType =
+    FunctionType inferredType =
         visitFunctionNode(node.function, null, returnContext, node.fileOffset);
+    if (inferrer.dataForTesting != null && node.hasImplicitReturnType) {
+      inferrer.dataForTesting.typeInferenceResult.inferredVariableTypes[node] =
+          inferredType.returnType;
+    }
     inferrer.library.checkBoundsInFunctionNode(node.function,
         inferrer.typeSchemaEnvironment, inferrer.library.fileUri);
     node.variable.type = inferredType;
@@ -1189,8 +1193,12 @@
   ExpressionInferenceResult visitFunctionExpression(
       FunctionExpression node, DartType typeContext) {
     inferrer.flowAnalysis.functionExpression_begin(node);
-    DartType inferredType =
+    FunctionType inferredType =
         visitFunctionNode(node.function, typeContext, null, node.fileOffset);
+    if (inferrer.dataForTesting != null) {
+      inferrer.dataForTesting.typeInferenceResult.inferredVariableTypes[node] =
+          inferredType.returnType;
+    }
     // In anonymous functions the return type isn't declared, so
     // it shouldn't be checked.
     inferrer.library.checkBoundsInFunctionNode(
@@ -1817,6 +1825,10 @@
           inferrer.library.library,
           isConst: node.isConst);
       inferredTypeArgument = inferredTypes[0];
+      if (inferrer.dataForTesting != null) {
+        inferrer.dataForTesting.typeInferenceResult
+            .inferredTypeArguments[node] = inferredTypes;
+      }
     } else {
       inferredTypeArgument = node.typeArgument;
     }
@@ -2492,6 +2504,10 @@
           isConst: node.isConst);
       inferredKeyType = inferredTypes[0];
       inferredValueType = inferredTypes[1];
+      if (inferrer.dataForTesting != null) {
+        inferrer.dataForTesting.typeInferenceResult
+            .inferredTypeArguments[node] = inferredTypes;
+      }
     } else {
       inferredKeyType = node.keyType;
       inferredValueType = node.valueType;
@@ -5952,6 +5968,10 @@
           inferrer.library.library,
           isConst: node.isConst);
       inferredTypeArgument = inferredTypes[0];
+      if (inferrer.dataForTesting != null) {
+        inferrer.dataForTesting.typeInferenceResult
+            .inferredTypeArguments[node] = inferredTypes;
+      }
     } else {
       inferredTypeArgument = node.typeArgument;
     }
@@ -6524,6 +6544,10 @@
           node.fileOffset,
           'type',
           new InstrumentationValueForType(inferredType));
+      if (inferrer.dataForTesting != null) {
+        inferrer.dataForTesting.typeInferenceResult
+            .inferredVariableTypes[node] = inferredType;
+      }
       node.type = inferredType;
     }
     if (initializerResult != null) {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index 1fbb4ea..d410f6e 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -324,5 +324,6 @@
 
 /// Type inference results used for testing.
 class TypeInferenceResultForTesting {
-  final Map<Arguments, List<DartType>> inferredTypeArguments = {};
+  final Map<TreeNode, List<DartType>> inferredTypeArguments = {};
+  final Map<TreeNode, DartType> inferredVariableTypes = {};
 }
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 150f0ba..c756ee0 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
@@ -2467,7 +2467,7 @@
     return new SuccessfulInferenceResult(inferredType, calleeType);
   }
 
-  DartType inferLocalFunction(FunctionNode function, DartType typeContext,
+  FunctionType inferLocalFunction(FunctionNode function, DartType typeContext,
       int fileOffset, DartType returnContext) {
     bool hasImplicitReturnType = false;
     if (returnContext == null) {
@@ -2579,6 +2579,10 @@
         instrumentation?.record(uriForInstrumentation, formal.fileOffset,
             'type', new InstrumentationValueForType(inferredType));
         formal.type = demoteTypeInLibrary(inferredType, library.library);
+        if (dataForTesting != null) {
+          dataForTesting.typeInferenceResult.inferredVariableTypes[formal] =
+              formal.type;
+        }
       }
 
       if (isNonNullableByDefault) {
diff --git a/pkg/front_end/test/id_tests/inferred_type_arguments_test.dart b/pkg/front_end/test/id_tests/inferred_type_arguments_test.dart
index 890e84b..58473d5 100644
--- a/pkg/front_end/test/id_tests/inferred_type_arguments_test.dart
+++ b/pkg/front_end/test/id_tests/inferred_type_arguments_test.dart
@@ -65,7 +65,10 @@
 
   @override
   List<DartType> computeNodeValue(Id id, TreeNode node) {
-    if (node is Arguments) {
+    if (node is Arguments ||
+        node is ListLiteral ||
+        node is SetLiteral ||
+        node is MapLiteral) {
       return typeInferenceResult.inferredTypeArguments[node];
     }
     return null;
diff --git a/pkg/front_end/test/id_tests/inferred_variable_types_test.dart b/pkg/front_end/test/id_tests/inferred_variable_types_test.dart
new file mode 100644
index 0000000..ab812ed
--- /dev/null
+++ b/pkg/front_end/test/id_tests/inferred_variable_types_test.dart
@@ -0,0 +1,95 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// 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.
+
+// @dart = 2.9
+
+import 'dart:io' show Directory, Platform;
+import 'package:_fe_analyzer_shared/src/testing/id.dart' show ActualData, Id;
+import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'
+    show DataInterpreter, runTests;
+import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
+import 'package:front_end/src/fasta/builder/member_builder.dart';
+import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
+import 'package:front_end/src/testing/id_testing_helper.dart';
+import 'package:front_end/src/testing/id_testing_utils.dart';
+import 'package:kernel/ast.dart' hide Variance;
+
+main(List<String> args) async {
+  Directory dataDir = new Directory.fromUri(
+      Platform.script.resolve('../../../_fe_analyzer_shared/test/'
+          'inference/inferred_variable_types/data'));
+  await runTests<DartType>(dataDir,
+      args: args,
+      createUriForFileName: createUriForFileName,
+      onFailure: onFailure,
+      runTest: runTestFor(const InferredVariableTypesDataComputer(),
+          [cfeNonNullableOnlyConfig]));
+}
+
+class InferredVariableTypesDataComputer extends DataComputer<DartType> {
+  const InferredVariableTypesDataComputer();
+
+  @override
+  DataInterpreter<DartType> get dataValidator =>
+      const _InferredVariableTypesDataInterpreter();
+
+  @override
+  bool get supportsErrors => true;
+
+  /// Function that computes a data mapping for [member].
+  ///
+  /// Fills [actualMap] with the data.
+  void computeMemberData(
+      TestConfig config,
+      InternalCompilerResult compilerResult,
+      Member member,
+      Map<Id, ActualData<DartType>> actualMap,
+      {bool verbose}) {
+    MemberBuilderImpl memberBuilder =
+        lookupMemberBuilder(compilerResult, member);
+    member.accept(new InferredTypeArgumentDataExtractor(
+        compilerResult,
+        memberBuilder.dataForTesting.inferenceData.typeInferenceResult,
+        actualMap));
+  }
+}
+
+class InferredTypeArgumentDataExtractor extends CfeDataExtractor<DartType> {
+  final TypeInferenceResultForTesting typeInferenceResult;
+
+  InferredTypeArgumentDataExtractor(InternalCompilerResult compilerResult,
+      this.typeInferenceResult, Map<Id, ActualData<DartType>> actualMap)
+      : super(compilerResult, actualMap);
+
+  @override
+  DartType computeNodeValue(Id id, TreeNode node) {
+    if (node is VariableDeclaration || node is LocalFunction) {
+      return typeInferenceResult.inferredVariableTypes[node];
+    }
+    return null;
+  }
+}
+
+class _InferredVariableTypesDataInterpreter
+    implements DataInterpreter<DartType> {
+  const _InferredVariableTypesDataInterpreter();
+
+  @override
+  String getText(DartType actualData, [String indentation]) {
+    return typeToText(
+        actualData, TypeRepresentation.analyzerNonNullableByDefault);
+  }
+
+  @override
+  String isAsExpected(DartType actualData, String expectedData) {
+    if (getText(actualData) == expectedData) {
+      return null;
+    } else {
+      return 'Expected $expectedData, got $actualData';
+    }
+  }
+
+  @override
+  bool isEmpty(DartType actualData) => actualData == null;
+}
diff --git a/pkg/js_runtime/lib/shared/embedded_names.dart b/pkg/js_runtime/lib/shared/embedded_names.dart
index e80fb6a..1df7671 100644
--- a/pkg/js_runtime/lib/shared/embedded_names.dart
+++ b/pkg/js_runtime/lib/shared/embedded_names.dart
@@ -201,9 +201,6 @@
   CALL_NAME_PROPERTY,
   DEFERRED_ACTION_PROPERTY,
 
-  /// Prefix used for generated type argument substitutions on classes.
-  OPERATOR_AS_PREFIX,
-
   /// Prefix used for generated type test property on classes.
   OPERATOR_IS_PREFIX,
 
diff --git a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
index e80fb6a..1df7671 100644
--- a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
+++ b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
@@ -201,9 +201,6 @@
   CALL_NAME_PROPERTY,
   DEFERRED_ACTION_PROPERTY,
 
-  /// Prefix used for generated type argument substitutions on classes.
-  OPERATOR_AS_PREFIX,
-
   /// Prefix used for generated type test property on classes.
   OPERATOR_IS_PREFIX,
 
diff --git a/tools/VERSION b/tools/VERSION
index 7c0b250..579bf54 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 6
+PRERELEASE 7
 PRERELEASE_PATCH 0
\ No newline at end of file