Version 2.17.0-248.0.dev

Merge commit 'c2c1cdc153374ca2405895ebdd221c23005a3067' into 'dev'
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/_fe_analyzer_shared/lib/src/util/dependency_walker.dart
similarity index 100%
rename from pkg/analyzer/lib/src/summary/link.dart
rename to pkg/_fe_analyzer_shared/lib/src/util/dependency_walker.dart
diff --git a/pkg/analyzer/test/src/summary/dependency_walker_test.dart b/pkg/_fe_analyzer_shared/test/util/dependency_walker_test.dart
similarity index 72%
rename from pkg/analyzer/test/src/summary/dependency_walker_test.dart
rename to pkg/_fe_analyzer_shared/test/util/dependency_walker_test.dart
index 6165430..5ca34a6 100644
--- a/pkg/analyzer/test/src/summary/dependency_walker_test.dart
+++ b/pkg/_fe_analyzer_shared/test/util/dependency_walker_test.dart
@@ -2,27 +2,14 @@
 // 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:analyzer/src/summary/link.dart';
+import 'package:_fe_analyzer_shared/src/util/dependency_walker.dart';
 import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(DependencyWalkerTest);
+  late Map<String, TestNode> nodes;
+  setUp(() {
+    nodes = {};
   });
-}
-
-@reflectiveTest
-class DependencyWalkerTest {
-  final nodes = <String, TestNode>{};
-
-  void checkGraph(Map<String, List<String>> graph, String startingNodeName,
-      List<List<String>> expectedEvaluations, List<bool> expectedSccFlags) {
-    makeGraph(graph);
-    var walker = walk(startingNodeName);
-    expect(walker._evaluations, expectedEvaluations.map((x) => x.toSet()));
-    expect(walker._sccFlags, expectedSccFlags);
-  }
 
   TestNode getNode(String name) =>
       nodes.putIfAbsent(name, () => TestNode(name));
@@ -36,7 +23,18 @@
     });
   }
 
-  void test_complex_graph() {
+  TestWalker walk(String startingNodeName) =>
+      TestWalker()..walk(getNode(startingNodeName));
+
+  void checkGraph(Map<String, List<String>> graph, String startingNodeName,
+      List<List<String>> expectedEvaluations, List<bool> expectedSccFlags) {
+    makeGraph(graph);
+    var walker = walk(startingNodeName);
+    expect(walker._evaluations, expectedEvaluations.map((x) => x.toSet()));
+    expect(walker._sccFlags, expectedSccFlags);
+  }
+
+  test('Complex graph', () {
     checkGraph(
         {
           'a': ['b', 'c'],
@@ -53,9 +51,9 @@
           ['a']
         ],
         [false, true, false]);
-  }
+  });
 
-  void test_diamond() {
+  test('Diamond', () {
     checkGraph(
         {
           'a': ['b', 'c'],
@@ -71,9 +69,9 @@
           ['a']
         ],
         [false, false, false, false]);
-  }
+  });
 
-  void test_singleNode() {
+  test('Single node', () {
     checkGraph(
         {'a': []},
         'a',
@@ -81,9 +79,9 @@
           ['a']
         ],
         [false]);
-  }
+  });
 
-  void test_singleNodeWithTrivialCycle() {
+  test('Single node with trivial cycle', () {
     checkGraph(
         {
           'a': ['a']
@@ -93,9 +91,9 @@
           ['a']
         ],
         [true]);
-  }
+  });
 
-  void test_threeNodesWithCircularDependency() {
+  test('Three nodes with circular dependency', () {
     checkGraph(
         {
           'a': ['b'],
@@ -107,43 +105,45 @@
           ['a', 'b', 'c']
         ],
         [true]);
-  }
+  });
 
-  test_twoBacklinksEarlierFirst() {
-    // Test a graph A->B->C->D, where D points back to B and then C.
-    checkGraph(
-        {
-          'a': ['b'],
-          'b': ['c'],
-          'c': ['d'],
-          'd': ['b', 'c']
-        },
-        'a',
-        [
-          ['b', 'c', 'd'],
-          ['a']
-        ],
-        [true, false]);
-  }
+  group('Two backlinks:', () {
+    test('earlier first', () {
+      // Test a graph A->B->C->D, where D points back to B and then C.
+      checkGraph(
+          {
+            'a': ['b'],
+            'b': ['c'],
+            'c': ['d'],
+            'd': ['b', 'c']
+          },
+          'a',
+          [
+            ['b', 'c', 'd'],
+            ['a']
+          ],
+          [true, false]);
+    });
 
-  test_twoBacklinksLaterFirst() {
-    // Test a graph A->B->C->D, where D points back to C and then B.
-    checkGraph(
-        {
-          'a': ['b'],
-          'b': ['c'],
-          'c': ['d'],
-          'd': ['c', 'b']
-        },
-        'a',
-        [
-          ['b', 'c', 'd'],
-          ['a']
-        ],
-        [true, false]);
-  }
+    test('later first', () {
+      // Test a graph A->B->C->D, where D points back to C and then B.
+      checkGraph(
+          {
+            'a': ['b'],
+            'b': ['c'],
+            'c': ['d'],
+            'd': ['c', 'b']
+          },
+          'a',
+          [
+            ['b', 'c', 'd'],
+            ['a']
+          ],
+          [true, false]);
+    });
+  });
 
-  void test_twoNodesWithCircularDependency() {
+  test('Two nodes with circular dependency', () {
     checkGraph(
         {
           'a': ['b'],
@@ -154,9 +154,9 @@
           ['a', 'b']
         ],
         [true]);
-  }
+  });
 
-  void test_twoNodesWithSimpleDependency() {
+  test('Two nodes with simple dependency', () {
     checkGraph(
         {
           'a': ['b'],
@@ -168,10 +168,7 @@
           ['a']
         ],
         [false, false]);
-  }
-
-  TestWalker walk(String startingNodeName) =>
-      TestWalker()..walk(getNode(startingNodeName));
+  });
 }
 
 class TestNode extends Node<TestNode> {
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_graph.dart b/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
index cd96133..1a4ed51 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_graph.dart
@@ -4,10 +4,10 @@
 
 import 'dart:typed_data';
 
+import 'package:_fe_analyzer_shared/src/util/dependency_walker.dart' as graph
+    show DependencyWalker, Node;
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/summary/api_signature.dart';
-import 'package:analyzer/src/summary/link.dart' as graph
-    show DependencyWalker, Node;
 import 'package:collection/collection.dart';
 
 /// Ensure that the [FileState.libraryCycle] for the [file] and anything it
diff --git a/pkg/analyzer/lib/src/dart/constant/compute.dart b/pkg/analyzer/lib/src/dart/constant/compute.dart
index b2b67c8..51188fe 100644
--- a/pkg/analyzer/lib/src/dart/constant/compute.dart
+++ b/pkg/analyzer/lib/src/dart/constant/compute.dart
@@ -2,12 +2,12 @@
 // 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:_fe_analyzer_shared/src/util/dependency_walker.dart' as graph
+    show DependencyWalker, Node;
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/src/dart/constant/evaluation.dart';
 import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/summary/link.dart' as graph
-    show DependencyWalker, Node;
 
 /// Compute values of the given [constants] with correct ordering.
 void computeConstants(DeclaredVariables declaredVariables,
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index ce6edd3..d58d6bb 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -6,6 +6,8 @@
 import 'dart:typed_data';
 
 import 'package:_fe_analyzer_shared/src/scanner/token_impl.dart';
+import 'package:_fe_analyzer_shared/src/util/dependency_walker.dart' as graph
+    show DependencyWalker, Node;
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
@@ -24,8 +26,6 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/api_signature.dart';
-import 'package:analyzer/src/summary/link.dart' as graph
-    show DependencyWalker, Node;
 import 'package:analyzer/src/summary2/data_reader.dart';
 import 'package:analyzer/src/summary2/data_writer.dart';
 import 'package:analyzer/src/summary2/informative_data.dart';
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
index e7c009f..b41bafc 100644
--- a/pkg/analyzer/lib/src/services/available_declarations.dart
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -5,6 +5,8 @@
 import 'dart:async';
 import 'dart:collection';
 
+import 'package:_fe_analyzer_shared/src/util/dependency_walker.dart' as graph
+    show DependencyWalker, Node;
 import 'package:analyzer/dart/analysis/analysis_context.dart';
 import 'package:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/utilities.dart';
@@ -22,8 +24,6 @@
 import 'package:analyzer/src/summary/api_signature.dart';
 import 'package:analyzer/src/summary/format.dart' as idl;
 import 'package:analyzer/src/summary/idl.dart' as idl;
-import 'package:analyzer/src/summary/link.dart' as graph
-    show DependencyWalker, Node;
 import 'package:analyzer/src/util/comment.dart';
 import 'package:analyzer/src/util/file_paths.dart' as file_paths;
 import 'package:collection/collection.dart';
diff --git a/pkg/analyzer/lib/src/summary2/simply_bounded.dart b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
index 0fe77da..4a153a5 100644
--- a/pkg/analyzer/lib/src/summary2/simply_bounded.dart
+++ b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
@@ -2,11 +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:_fe_analyzer_shared/src/util/dependency_walker.dart' as graph
+    show DependencyWalker, Node;
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/summary/link.dart' as graph
-    show DependencyWalker, Node;
 import 'package:analyzer/src/summary2/link.dart';
 
 /// Compute simple-boundedness for all classes and generic types aliases in
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 82cba35..45b2edb 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.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:_fe_analyzer_shared/src/util/dependency_walker.dart' as graph
+    show DependencyWalker, Node;
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -13,8 +15,6 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
 import 'package:analyzer/src/dart/element/type_system.dart';
-import 'package:analyzer/src/summary/link.dart' as graph
-    show DependencyWalker, Node;
 import 'package:analyzer/src/summary2/ast_resolver.dart';
 import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/linking_node_scope.dart';
diff --git a/pkg/analyzer/test/src/summary/test_all.dart b/pkg/analyzer/test/src/summary/test_all.dart
index f944535..41786a1 100644
--- a/pkg/analyzer/test/src/summary/test_all.dart
+++ b/pkg/analyzer/test/src/summary/test_all.dart
@@ -5,7 +5,6 @@
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'api_signature_test.dart' as api_signature;
-import 'dependency_walker_test.dart' as dependency_walker;
 import 'elements_test.dart' as elements;
 import 'flat_buffers_test.dart' as flat_buffers;
 import 'in_summary_source_test.dart' as in_summary_source;
@@ -15,7 +14,6 @@
 main() {
   defineReflectiveSuite(() {
     api_signature.main();
-    dependency_walker.main();
     elements.main();
     flat_buffers.main();
     in_summary_source.main();
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 305edab..ff5247a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1294,6 +1294,10 @@
           body);
       body = inferredFunctionBody.body;
       builder.function.futureValueType = inferredFunctionBody.futureValueType;
+      assert(
+          !(builder.function.asyncMarker == AsyncMarker.Async &&
+              builder.function.futureValueType == null),
+          "No future value type computed.");
       libraryBuilder.loader.transformPostInference(body, transformSetLiterals,
           transformCollections, libraryBuilder.library);
     }
diff --git a/pkg/front_end/lib/src/fasta/type_inference/closure_context.dart b/pkg/front_end/lib/src/fasta/type_inference/closure_context.dart
index b6e0288..4d46072 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/closure_context.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/closure_context.dart
@@ -65,8 +65,12 @@
               computeFutureValueType(inferrer.coreTypes, declaredReturnType);
         }
       } else {
-        returnContext = inferrer.wrapFutureOrType(
-            inferrer.typeSchemaEnvironment.flatten(returnContext));
+        DartType flattenedType =
+            inferrer.typeSchemaEnvironment.flatten(returnContext);
+        returnContext = inferrer.wrapFutureOrType(flattenedType);
+        if (!needToInferReturnType) {
+          futureValueType = flattenedType;
+        }
       }
       return new _AsyncClosureContext(returnContext, declaredReturnType,
           needToInferReturnType, futureValueType);
@@ -815,6 +819,8 @@
     if (inferrer.isNonNullableByDefault) {
       futureValueType =
           computeFutureValueType(inferrer.coreTypes, inferredType);
+    } else {
+      futureValueType = inferrer.typeSchemaEnvironment.flatten(inferredType);
     }
     if (!inferrer.isTopLevel) {
       for (int i = 0; i < _returnStatements!.length; ++i) {
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 69e3778..1f1f6b2 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
@@ -2105,10 +2105,7 @@
     result =
         closureContext!.handleImplicitReturn(this, body, result, fileOffset);
     DartType? futureValueType = closureContext!.futureValueType;
-    assert(
-        !(isNonNullableByDefault &&
-            asyncMarker == AsyncMarker.Async &&
-            futureValueType == null),
+    assert(!(asyncMarker == AsyncMarker.Async && futureValueType == null),
         "No future value type computed.");
     closureContext = null;
     this.helper = null;
@@ -2863,8 +2860,7 @@
         this, function.body!, bodyResult, fileOffset);
     function.futureValueType = closureContext.futureValueType;
     assert(
-        !(isNonNullableByDefault &&
-            function.asyncMarker == AsyncMarker.Async &&
+        !(function.asyncMarker == AsyncMarker.Async &&
             function.futureValueType == null),
         "No future value type computed.");
 
diff --git a/pkg/front_end/test/macros/incremental/data/tests/user_macro/main.0.dart.expect b/pkg/front_end/test/macros/incremental/data/tests/user_macro/main.0.dart.expect
index 977e49e..9872609 100644
--- a/pkg/front_end/test/macros/incremental/data/tests/user_macro/main.0.dart.expect
+++ b/pkg/front_end/test/macros/incremental/data/tests/user_macro/main.0.dart.expect
@@ -36,7 +36,7 @@
     : super core::Object::•()
     ;
   @#C2
-  method buildDeclarationsForClass(api::ClassDeclaration clazz, api::ClassMemberDeclarationBuilder builder) → FutureOr<void> async {}
+  method buildDeclarationsForClass(api::ClassDeclaration clazz, api::ClassMemberDeclarationBuilder builder) → FutureOr<void> async /* futureValueType= void */ {}
 }
 
 library /*isNonNullableByDefault*/;
diff --git a/pkg/front_end/test/macros/incremental/data/tests/user_macro/main.1.dart.expect b/pkg/front_end/test/macros/incremental/data/tests/user_macro/main.1.dart.expect
index 88b94c0..c7ffa1c 100644
--- a/pkg/front_end/test/macros/incremental/data/tests/user_macro/main.1.dart.expect
+++ b/pkg/front_end/test/macros/incremental/data/tests/user_macro/main.1.dart.expect
@@ -33,7 +33,7 @@
     : super core::Object::•()
     ;
   @#C2
-  method buildDeclarationsForClass(api::ClassDeclaration clazz, api::ClassMemberDeclarationBuilder builder) → FutureOr<void> async {
+  method buildDeclarationsForClass(api::ClassDeclaration clazz, api::ClassMemberDeclarationBuilder builder) → FutureOr<void> async /* futureValueType= void */ {
     builder.{api::ClassMemberDeclarationBuilder::declareInClass}(new api::DeclarationCode::fromString(mac2::generateBody())){(api::DeclarationCode) → void};
   }
 }
diff --git a/pkg/front_end/test/macros/incremental/data/tests/user_macro/main.2.dart.expect b/pkg/front_end/test/macros/incremental/data/tests/user_macro/main.2.dart.expect
index 39bdd89..26e4a4d 100644
--- a/pkg/front_end/test/macros/incremental/data/tests/user_macro/main.2.dart.expect
+++ b/pkg/front_end/test/macros/incremental/data/tests/user_macro/main.2.dart.expect
@@ -35,7 +35,7 @@
     : super core::Object::•()
     ;
   @#C2
-  method buildDeclarationsForClass(api::ClassDeclaration clazz, api::ClassMemberDeclarationBuilder builder) → FutureOr<void> async {
+  method buildDeclarationsForClass(api::ClassDeclaration clazz, api::ClassMemberDeclarationBuilder builder) → FutureOr<void> async /* futureValueType= void */ {
     builder.{api::ClassMemberDeclarationBuilder::declareInClass}(new api::DeclarationCode::fromString(mac2::generateBody())){(api::DeclarationCode) → void};
   }
 }
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 9c7b439..5b21bf7 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -27,6 +27,7 @@
 adi
 advantage
 affecting
+affords
 afterwards
 agree
 agreeing
@@ -143,6 +144,7 @@
 brevity
 brianwilkerson
 bridge
+bridges
 bs
 bsd
 bslash
@@ -278,6 +280,7 @@
 customized
 cut
 cwd
+cyclical
 cyclically
 d
 dace
@@ -317,6 +320,7 @@
 demangle
 demangled
 dep
+dependency's
 deps
 dereferencing
 deregister
@@ -338,6 +342,7 @@
 dictates
 diff
 differs
+difficult
 diffs
 digest
 digests
@@ -432,6 +437,7 @@
 expense
 experimentation
 explaining
+explore
 exportable
 exportee
 exportees
@@ -494,6 +500,7 @@
 fourth
 framework
 freely
+freshly
 frontend
 frontends
 fs
@@ -671,6 +678,7 @@
 kallentu
 kb
 kernel's
+kick
 kill
 klass
 kmillikin
@@ -808,6 +816,7 @@
 nominality
 nonexistent
 nonimplementation
+nonzero
 norm
 normalization
 notifier
@@ -1110,6 +1119,7 @@
 say
 sb
 sc
+scc
 scheglov
 scoped
 scoping
@@ -1280,6 +1290,8 @@
 taking
 talk
 talks
+tarjan
+tarjan's
 tb
 team
 tearoff
@@ -1452,6 +1464,8 @@
 vtab
 w
 waiting
+walker
+walking
 wanting
 wants
 waste
diff --git a/pkg/front_end/test/static_types/data/for_in.dart b/pkg/front_end/test/static_types/data/for_in.dart
index 922bee5..6974c3c 100644
--- a/pkg/front_end/test/static_types/data/for_in.dart
+++ b/pkg/front_end/test/static_types/data/for_in.dart
@@ -48,7 +48,7 @@
   }
 }
 
-/*cfe:nnbd.member: asyncForInDynamicStream:futureValueType=dynamic*/
+/*member: asyncForInDynamicStream:futureValueType=dynamic*/
 asyncForInDynamicStream(dynamic stream) async {
   /*current: dynamic*/
   await for (var e in
@@ -59,7 +59,7 @@
   }
 }
 
-/*cfe:nnbd.member: asyncForInDynamic:futureValueType=dynamic*/
+/*member: asyncForInDynamic:futureValueType=dynamic*/
 asyncForInDynamic(Stream<dynamic> stream) async {
   /*current: dynamic*/
   await for (var e in
@@ -70,7 +70,7 @@
   }
 }
 
-/*cfe:nnbd.member: asyncForInInt:futureValueType=dynamic*/
+/*member: asyncForInInt:futureValueType=dynamic*/
 asyncForInInt(Stream<int> stream) async {
   /*cfe.current: int*/
   /*cfe:nnbd.current: int!*/
@@ -84,7 +84,7 @@
   }
 }
 
-/*cfe:nnbd.member: asyncForInIntToNum:futureValueType=dynamic*/
+/*member: asyncForInIntToNum:futureValueType=dynamic*/
 asyncForInIntToNum(Stream<int> stream) async {
   /*cfe.current: int*/
   /*cfe:nnbd.current: int!*/
@@ -119,7 +119,7 @@
   Iterator<int> get iterator;
 }
 
-/*cfe:nnbd.member: customStream:futureValueType=dynamic*/
+/*member: customStream:futureValueType=dynamic*/
 customStream(CustomStream stream) async {
   /*cfe.current: num*/
   /*cfe:nnbd.current: num!*/
@@ -158,7 +158,7 @@
   CustomIterator get iterator;
 }
 
-/*cfe:nnbd.member: customStreamIterator:futureValueType=dynamic*/
+/*member: customStreamIterator:futureValueType=dynamic*/
 customStreamIterator(StreamWithCustomIterator stream) async {
   /*cfe.current: num*/
   /*cfe:nnbd.current: num!*/
@@ -183,7 +183,7 @@
   }
 }
 
-/*cfe:nnbd.member: genericStream:futureValueType=void*/
+/*member: genericStream:futureValueType=void*/
 void genericStream<T extends Stream<T>>(T x) async {
   /*cfe.current: T*/
   /*cfe:nnbd.current: T!*/
diff --git a/pkg/front_end/test/static_types/data/future_value_type.dart b/pkg/front_end/test/static_types/data/future_value_type.dart
index f9ba684..ca6cc92 100644
--- a/pkg/front_end/test/static_types/data/future_value_type.dart
+++ b/pkg/front_end/test/static_types/data/future_value_type.dart
@@ -9,50 +9,53 @@
 import 'dart:async';
 
 /*cfe:nnbd.member: declaredFutureInt:futureValueType=int!*/
+/*cfe.member: declaredFutureInt:futureValueType=int*/
 Future<int> declaredFutureInt() async {
   return
       /*cfe.int*/ /*cfe:nnbd.int!*/ 0;
 }
 
 /*cfe:nnbd.member: declaredFutureOrInt:futureValueType=int!*/
+/*cfe.member: declaredFutureOrInt:futureValueType=int*/
 FutureOr<int> declaredFutureOrInt() async {
   return
       /*cfe.int*/ /*cfe:nnbd.int!*/ 0;
 }
 
 /*cfe:nnbd.member: declaredObject:futureValueType=Object?*/
+/*cfe.member: declaredObject:futureValueType=Object*/
 Object declaredObject() async {
   return
       /*cfe.int*/ /*cfe:nnbd.int!*/ 0;
 }
 
-/*cfe:nnbd.member: omitted:futureValueType=dynamic*/
+/*member: omitted:futureValueType=dynamic*/
 omitted() async {}
 
-/*cfe:nnbd.member: method:futureValueType=dynamic*/
+/*member: method:futureValueType=dynamic*/
 method() async {
   /*cfe:nnbd.futureValueType=int!*/
-  Future<int> declaredLocalFutureInt() async {
+  /*cfe.futureValueType=int*/Future<int> declaredLocalFutureInt() async {
     return
         /*cfe.int*/ /*cfe:nnbd.int!*/ 0;
   }
 
   /*cfe:nnbd.futureValueType=int!*/
-  FutureOr<int> declaredLocalFutureOrInt() async {
+  /*cfe.futureValueType=int*/FutureOr<int> declaredLocalFutureOrInt() async {
     return
         /*cfe.int*/ /*cfe:nnbd.int!*/ 0;
   }
 
   /*cfe:nnbd.futureValueType=Object?*/
-  Object declaredLocalObject() async {
+  /*cfe.futureValueType=Object*/Object declaredLocalObject() async {
     return
         /*cfe.int*/ /*cfe:nnbd.int!*/ 0;
   }
 
-  /*cfe:nnbd.futureValueType=Null*/ omittedLocal() async {}
+  /*futureValueType=Null*/omittedLocal() async {}
 
   Future<int> inferredCalledFutureInt =
-      /*cfe.Future<int> Function()*/
+      /*cfe.Future<int> Function(),futureValueType=int*/
       /*cfe:nnbd.Future<int!>! Function()!,futureValueType=int!*/
       () async {
     return
@@ -63,7 +66,7 @@
           ();
 
   FutureOr<int> inferredCalledFutureOrInt =
-      /*cfe.Future<int> Function()*/
+      /*cfe.Future<int> Function(),futureValueType=int*/
       /*cfe:nnbd.Future<int!>! Function()!,futureValueType=int!*/
       () async {
     return
@@ -74,7 +77,7 @@
           ();
 
   Future<int> Function() inferredFutureInt =
-      /*cfe.Future<int> Function()*/
+      /*cfe.Future<int> Function(),futureValueType=int*/
       /*cfe:nnbd.Future<int!>! Function()!,futureValueType=int!*/
       () async {
     return
@@ -82,7 +85,7 @@
   };
 
   FutureOr<int> Function() inferredFutureOrInt =
-      /*cfe.Future<int> Function()*/
+      /*cfe.Future<int> Function(),futureValueType=int*/
       /*cfe:nnbd.Future<int!>! Function()!,futureValueType=int!*/
       () async {
     return
@@ -90,7 +93,7 @@
   };
 
   Object Function() inferredInt =
-      /*cfe.Future<int> Function()*/
+      /*cfe.Future<int> Function(),futureValueType=int*/
       /*cfe:nnbd.Future<int!>! Function()!,futureValueType=int!*/
       () async {
     return
@@ -98,7 +101,7 @@
   };
 
   Object Function() inferredNull =
-      /*cfe.Future<Null> Function()*/
+      /*cfe.Future<Null> Function(),futureValueType=Null*/
       /*cfe:nnbd.Future<Null>! Function()!,futureValueType=Null*/
       () async {
     return
@@ -106,7 +109,7 @@
   };
 
   Object Function() inferredEmpty =
-      /*cfe.Future<Null> Function()*/
+      /*cfe.Future<Null> Function(),futureValueType=Null*/
       /*cfe:nnbd.Future<Null>! Function()!,futureValueType=Null*/
       () async {};
 }
diff --git a/pkg/front_end/testcases/extensions/async_extensions.dart.weak.expect b/pkg/front_end/testcases/extensions/async_extensions.dart.weak.expect
index f053e58..1cd81f5 100644
--- a/pkg/front_end/testcases/extensions/async_extensions.dart.weak.expect
+++ b/pkg/front_end/testcases/extensions/async_extensions.dart.weak.expect
@@ -13,7 +13,7 @@
 static method Extension|syncStarMethod(lowered final core::int* #this) → dynamic sync* {}
 static method Extension|get#syncStarMethod(lowered final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|syncStarMethod(#this);
-static method Extension|asyncMethod(lowered final core::int* #this) → dynamic async {}
+static method Extension|asyncMethod(lowered final core::int* #this) → dynamic async /* futureValueType= dynamic */ {}
 static method Extension|get#asyncMethod(lowered final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|asyncMethod(#this);
 static method Extension|asyncStarMethod(lowered final core::int* #this) → dynamic async* {}
diff --git a/pkg/front_end/testcases/extensions/async_extensions.dart.weak.modular.expect b/pkg/front_end/testcases/extensions/async_extensions.dart.weak.modular.expect
index f053e58..1cd81f5 100644
--- a/pkg/front_end/testcases/extensions/async_extensions.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/extensions/async_extensions.dart.weak.modular.expect
@@ -13,7 +13,7 @@
 static method Extension|syncStarMethod(lowered final core::int* #this) → dynamic sync* {}
 static method Extension|get#syncStarMethod(lowered final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|syncStarMethod(#this);
-static method Extension|asyncMethod(lowered final core::int* #this) → dynamic async {}
+static method Extension|asyncMethod(lowered final core::int* #this) → dynamic async /* futureValueType= dynamic */ {}
 static method Extension|get#asyncMethod(lowered final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|asyncMethod(#this);
 static method Extension|asyncStarMethod(lowered final core::int* #this) → dynamic async* {}
diff --git a/pkg/front_end/testcases/extensions/async_extensions.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/async_extensions.dart.weak.transformed.expect
index 739da7f..c9d8f91 100644
--- a/pkg/front_end/testcases/extensions/async_extensions.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extensions/async_extensions.dart.weak.transformed.expect
@@ -25,7 +25,7 @@
 }
 static method Extension|get#syncStarMethod(lowered final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|syncStarMethod(#this);
-static method Extension|asyncMethod(lowered final core::int* #this) → dynamic /* originally async */ {
+static method Extension|asyncMethod(lowered final core::int* #this) → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.weak.expect b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.weak.expect
index a3e0d9a..e5d181d 100644
--- a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.weak.expect
+++ b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.weak.expect
@@ -13,7 +13,7 @@
 
 import "org-dartlang-testcase:///deferred_explicit_access_lib.dart" deferred as prefix;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await LoadLibrary(prefix);
   self::expect(0, let final dynamic #t1 = CheckLibraryIsLoaded(prefix) in def::Extension|staticField);
   self::expect(0, let final dynamic #t2 = CheckLibraryIsLoaded(prefix) in def::Extension|get#property(0));
diff --git a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.weak.modular.expect b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.weak.modular.expect
index a3e0d9a..e5d181d 100644
--- a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.weak.modular.expect
@@ -13,7 +13,7 @@
 
 import "org-dartlang-testcase:///deferred_explicit_access_lib.dart" deferred as prefix;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await LoadLibrary(prefix);
   self::expect(0, let final dynamic #t1 = CheckLibraryIsLoaded(prefix) in def::Extension|staticField);
   self::expect(0, let final dynamic #t2 = CheckLibraryIsLoaded(prefix) in def::Extension|get#property(0));
diff --git a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.weak.transformed.expect
index 2aa57c8..612662d 100644
--- a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.weak.transformed.expect
@@ -14,7 +14,7 @@
 
 import "org-dartlang-testcase:///deferred_explicit_access_lib.dart" deferred as prefix;
 
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.weak.expect b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.weak.expect
index ddd41d6..0b080b3 100644
--- a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.weak.expect
+++ b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.weak.expect
@@ -5,7 +5,7 @@
 
 import "org-dartlang-testcase:///deferred_explicit_access_lib.dart" deferred as prefix hide Extension;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await LoadLibrary(prefix);
   self::expect(0, let final dynamic #t1 = CheckLibraryIsLoaded(prefix) in def::topLevelField);
   self::expect(42, let final dynamic #t2 = CheckLibraryIsLoaded(prefix) in def::topLevelField = 42);
diff --git a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.weak.modular.expect b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.weak.modular.expect
index ddd41d6..0b080b3 100644
--- a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.weak.modular.expect
@@ -5,7 +5,7 @@
 
 import "org-dartlang-testcase:///deferred_explicit_access_lib.dart" deferred as prefix hide Extension;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await LoadLibrary(prefix);
   self::expect(0, let final dynamic #t1 = CheckLibraryIsLoaded(prefix) in def::topLevelField);
   self::expect(42, let final dynamic #t2 = CheckLibraryIsLoaded(prefix) in def::topLevelField = 42);
diff --git a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.weak.transformed.expect b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.weak.transformed.expect
index f4d6fd7..bc5853f 100644
--- a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.weak.transformed.expect
@@ -6,7 +6,7 @@
 
 import "org-dartlang-testcase:///deferred_explicit_access_lib.dart" deferred as prefix hide Extension;
 
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/async_function.dart.weak.expect b/pkg/front_end/testcases/general/async_function.dart.weak.expect
index 5e81b91..2bedd98e 100644
--- a/pkg/front_end/testcases/general/async_function.dart.weak.expect
+++ b/pkg/front_end/testcases/general/async_function.dart.weak.expect
@@ -6,10 +6,10 @@
 import "dart:async";
 
 static field core::List<core::String> stringList = <core::String>["bar"];
-static method asyncString() → asy::Future<core::String> async {
+static method asyncString() → asy::Future<core::String> async /* futureValueType= core::String */ {
   return "foo";
 }
-static method asyncString2() → asy::Future<core::String> async {
+static method asyncString2() → asy::Future<core::String> async /* futureValueType= core::String */ {
   return self::asyncString();
 }
 static method syncStarString() → core::Iterable<core::String> sync* {
@@ -28,6 +28,6 @@
 static method asyncStarString2() → asy::Stream<core::String> async* {
   yield "bar";
 }
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   core::String str = await self::asyncString();
 }
diff --git a/pkg/front_end/testcases/general/async_function.dart.weak.modular.expect b/pkg/front_end/testcases/general/async_function.dart.weak.modular.expect
index 5e81b91..2bedd98e 100644
--- a/pkg/front_end/testcases/general/async_function.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/async_function.dart.weak.modular.expect
@@ -6,10 +6,10 @@
 import "dart:async";
 
 static field core::List<core::String> stringList = <core::String>["bar"];
-static method asyncString() → asy::Future<core::String> async {
+static method asyncString() → asy::Future<core::String> async /* futureValueType= core::String */ {
   return "foo";
 }
-static method asyncString2() → asy::Future<core::String> async {
+static method asyncString2() → asy::Future<core::String> async /* futureValueType= core::String */ {
   return self::asyncString();
 }
 static method syncStarString() → core::Iterable<core::String> sync* {
@@ -28,6 +28,6 @@
 static method asyncStarString2() → asy::Stream<core::String> async* {
   yield "bar";
 }
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   core::String str = await self::asyncString();
 }
diff --git a/pkg/front_end/testcases/general/async_function.dart.weak.transformed.expect b/pkg/front_end/testcases/general/async_function.dart.weak.transformed.expect
index cd8de28..373a8d8 100644
--- a/pkg/front_end/testcases/general/async_function.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/async_function.dart.weak.transformed.expect
@@ -7,7 +7,7 @@
 import "dart:async";
 
 static field core::List<core::String> stringList = core::_GrowableList::_literal1<core::String>("bar");
-static method asyncString() → asy::Future<core::String> /* originally async */ {
+static method asyncString() → asy::Future<core::String> /* futureValueType= core::String */ /* originally async */ {
   final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
   core::bool* :is_sync = false;
   core::String? :return_value;
@@ -34,7 +34,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method asyncString2() → asy::Future<core::String> /* originally async */ {
+static method asyncString2() → asy::Future<core::String> /* futureValueType= core::String */ /* originally async */ {
   final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
   core::bool* :is_sync = false;
   FutureOr<core::String>? :return_value;
@@ -178,7 +178,7 @@
   :controller_stream = :controller.{asy::_AsyncStarStreamController::stream}{asy::Stream<core::String>};
   return :controller_stream;
 }
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/async_function_returns_future_or.dart.weak.expect b/pkg/front_end/testcases/general/async_function_returns_future_or.dart.weak.expect
index 6f8e4d4..46f8ed8 100644
--- a/pkg/front_end/testcases/general/async_function_returns_future_or.dart.weak.expect
+++ b/pkg/front_end/testcases/general/async_function_returns_future_or.dart.weak.expect
@@ -5,7 +5,7 @@
 
 import "dart:async";
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await self::returnsString();
   await self::returnsFutureOrString();
   await self::returnsAwaitFutureOrString();
@@ -17,27 +17,27 @@
   await self::returnsFutureObject();
   await self::returnsAwaitFutureObject();
 }
-static method returnsString() → asy::Future<core::String> async 
+static method returnsString() → asy::Future<core::String> async /* futureValueType= core::String */ 
   return "a";
-static method returnsFutureOrString() → asy::Future<core::String> async 
+static method returnsFutureOrString() → asy::Future<core::String> async /* futureValueType= core::String */ 
   return self::getFutureOr<core::String>("a");
-static method returnsAwaitFutureOrString() → asy::Future<core::String> async 
+static method returnsAwaitFutureOrString() → asy::Future<core::String> async /* futureValueType= core::String */ 
   return await self::getFutureOr<core::String>("a");
-static method returnsFutureString() → asy::Future<core::String> async 
+static method returnsFutureString() → asy::Future<core::String> async /* futureValueType= core::String */ 
   return self::getFuture<core::String>("a");
-static method returnsAwaitFutureString() → FutureOr<core::String> async 
+static method returnsAwaitFutureString() → FutureOr<core::String> async /* futureValueType= core::String */ 
   return await self::getFuture<core::String>("a");
-static method returnsObject() → asy::Future<core::Object> async 
+static method returnsObject() → asy::Future<core::Object> async /* futureValueType= core::Object */ 
   return new core::Object::•();
-static method returnsFutureOrObject() → asy::Future<core::Object> async 
+static method returnsFutureOrObject() → asy::Future<core::Object> async /* futureValueType= core::Object */ 
   return self::getFutureOr<core::Object>(new core::Object::•());
-static method returnsAwaitFutureOrObject() → asy::Future<core::Object> async 
+static method returnsAwaitFutureOrObject() → asy::Future<core::Object> async /* futureValueType= core::Object */ 
   return await self::getFutureOr<core::Object>(new core::Object::•());
-static method returnsFutureObject() → asy::Future<core::Object> async 
+static method returnsFutureObject() → asy::Future<core::Object> async /* futureValueType= core::Object */ 
   return self::getFuture<core::Object>(new core::Object::•());
-static method returnsAwaitFutureObject() → FutureOr<core::Object> async 
+static method returnsAwaitFutureObject() → FutureOr<core::Object> async /* futureValueType= core::Object */ 
   return await self::getFuture<core::Object>(new core::Object::•());
-static method getFutureOr<T extends core::Object? = dynamic>(self::getFutureOr::T% v) → FutureOr<self::getFutureOr::T%> async 
+static method getFutureOr<T extends core::Object? = dynamic>(self::getFutureOr::T% v) → FutureOr<self::getFutureOr::T%> async /* futureValueType= self::getFutureOr::T% */ 
   return v;
-static method getFuture<T extends core::Object? = dynamic>(self::getFuture::T% v) → asy::Future<self::getFuture::T%> async 
+static method getFuture<T extends core::Object? = dynamic>(self::getFuture::T% v) → asy::Future<self::getFuture::T%> async /* futureValueType= self::getFuture::T% */ 
   return v;
diff --git a/pkg/front_end/testcases/general/async_function_returns_future_or.dart.weak.modular.expect b/pkg/front_end/testcases/general/async_function_returns_future_or.dart.weak.modular.expect
index 6f8e4d4..46f8ed8 100644
--- a/pkg/front_end/testcases/general/async_function_returns_future_or.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/async_function_returns_future_or.dart.weak.modular.expect
@@ -5,7 +5,7 @@
 
 import "dart:async";
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await self::returnsString();
   await self::returnsFutureOrString();
   await self::returnsAwaitFutureOrString();
@@ -17,27 +17,27 @@
   await self::returnsFutureObject();
   await self::returnsAwaitFutureObject();
 }
-static method returnsString() → asy::Future<core::String> async 
+static method returnsString() → asy::Future<core::String> async /* futureValueType= core::String */ 
   return "a";
-static method returnsFutureOrString() → asy::Future<core::String> async 
+static method returnsFutureOrString() → asy::Future<core::String> async /* futureValueType= core::String */ 
   return self::getFutureOr<core::String>("a");
-static method returnsAwaitFutureOrString() → asy::Future<core::String> async 
+static method returnsAwaitFutureOrString() → asy::Future<core::String> async /* futureValueType= core::String */ 
   return await self::getFutureOr<core::String>("a");
-static method returnsFutureString() → asy::Future<core::String> async 
+static method returnsFutureString() → asy::Future<core::String> async /* futureValueType= core::String */ 
   return self::getFuture<core::String>("a");
-static method returnsAwaitFutureString() → FutureOr<core::String> async 
+static method returnsAwaitFutureString() → FutureOr<core::String> async /* futureValueType= core::String */ 
   return await self::getFuture<core::String>("a");
-static method returnsObject() → asy::Future<core::Object> async 
+static method returnsObject() → asy::Future<core::Object> async /* futureValueType= core::Object */ 
   return new core::Object::•();
-static method returnsFutureOrObject() → asy::Future<core::Object> async 
+static method returnsFutureOrObject() → asy::Future<core::Object> async /* futureValueType= core::Object */ 
   return self::getFutureOr<core::Object>(new core::Object::•());
-static method returnsAwaitFutureOrObject() → asy::Future<core::Object> async 
+static method returnsAwaitFutureOrObject() → asy::Future<core::Object> async /* futureValueType= core::Object */ 
   return await self::getFutureOr<core::Object>(new core::Object::•());
-static method returnsFutureObject() → asy::Future<core::Object> async 
+static method returnsFutureObject() → asy::Future<core::Object> async /* futureValueType= core::Object */ 
   return self::getFuture<core::Object>(new core::Object::•());
-static method returnsAwaitFutureObject() → FutureOr<core::Object> async 
+static method returnsAwaitFutureObject() → FutureOr<core::Object> async /* futureValueType= core::Object */ 
   return await self::getFuture<core::Object>(new core::Object::•());
-static method getFutureOr<T extends core::Object? = dynamic>(self::getFutureOr::T% v) → FutureOr<self::getFutureOr::T%> async 
+static method getFutureOr<T extends core::Object? = dynamic>(self::getFutureOr::T% v) → FutureOr<self::getFutureOr::T%> async /* futureValueType= self::getFutureOr::T% */ 
   return v;
-static method getFuture<T extends core::Object? = dynamic>(self::getFuture::T% v) → asy::Future<self::getFuture::T%> async 
+static method getFuture<T extends core::Object? = dynamic>(self::getFuture::T% v) → asy::Future<self::getFuture::T%> async /* futureValueType= self::getFuture::T% */ 
   return v;
diff --git a/pkg/front_end/testcases/general/async_function_returns_future_or.dart.weak.transformed.expect b/pkg/front_end/testcases/general/async_function_returns_future_or.dart.weak.transformed.expect
index 2ccc693..f6fb0b0 100644
--- a/pkg/front_end/testcases/general/async_function_returns_future_or.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/async_function_returns_future_or.dart.weak.transformed.expect
@@ -6,7 +6,7 @@
 
 import "dart:async";
 
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -52,7 +52,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnsString() → asy::Future<core::String> /* originally async */ {
+static method returnsString() → asy::Future<core::String> /* futureValueType= core::String */ /* originally async */ {
   final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
   core::bool* :is_sync = false;
   core::String? :return_value;
@@ -79,7 +79,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnsFutureOrString() → asy::Future<core::String> /* originally async */ {
+static method returnsFutureOrString() → asy::Future<core::String> /* futureValueType= core::String */ /* originally async */ {
   final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
   core::bool* :is_sync = false;
   FutureOr<core::String>? :return_value;
@@ -106,7 +106,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnsAwaitFutureOrString() → asy::Future<core::String> /* originally async */ {
+static method returnsAwaitFutureOrString() → asy::Future<core::String> /* futureValueType= core::String */ /* originally async */ {
   final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
   core::bool* :is_sync = false;
   core::String? :return_value;
@@ -135,7 +135,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnsFutureString() → asy::Future<core::String> /* originally async */ {
+static method returnsFutureString() → asy::Future<core::String> /* futureValueType= core::String */ /* originally async */ {
   final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
   core::bool* :is_sync = false;
   FutureOr<core::String>? :return_value;
@@ -162,7 +162,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnsAwaitFutureString() → FutureOr<core::String> /* originally async */ {
+static method returnsAwaitFutureString() → FutureOr<core::String> /* futureValueType= core::String */ /* originally async */ {
   final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
   core::bool* :is_sync = false;
   core::String? :return_value;
@@ -191,7 +191,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnsObject() → asy::Future<core::Object> /* originally async */ {
+static method returnsObject() → asy::Future<core::Object> /* futureValueType= core::Object */ /* originally async */ {
   final asy::_Future<core::Object> :async_future = new asy::_Future::•<core::Object>();
   core::bool* :is_sync = false;
   FutureOr<core::Object>? :return_value;
@@ -218,7 +218,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnsFutureOrObject() → asy::Future<core::Object> /* originally async */ {
+static method returnsFutureOrObject() → asy::Future<core::Object> /* futureValueType= core::Object */ /* originally async */ {
   final asy::_Future<core::Object> :async_future = new asy::_Future::•<core::Object>();
   core::bool* :is_sync = false;
   FutureOr<core::Object>? :return_value;
@@ -245,7 +245,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnsAwaitFutureOrObject() → asy::Future<core::Object> /* originally async */ {
+static method returnsAwaitFutureOrObject() → asy::Future<core::Object> /* futureValueType= core::Object */ /* originally async */ {
   final asy::_Future<core::Object> :async_future = new asy::_Future::•<core::Object>();
   core::bool* :is_sync = false;
   FutureOr<core::Object>? :return_value;
@@ -274,7 +274,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnsFutureObject() → asy::Future<core::Object> /* originally async */ {
+static method returnsFutureObject() → asy::Future<core::Object> /* futureValueType= core::Object */ /* originally async */ {
   final asy::_Future<core::Object> :async_future = new asy::_Future::•<core::Object>();
   core::bool* :is_sync = false;
   FutureOr<core::Object>? :return_value;
@@ -301,7 +301,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnsAwaitFutureObject() → FutureOr<core::Object> /* originally async */ {
+static method returnsAwaitFutureObject() → FutureOr<core::Object> /* futureValueType= core::Object */ /* originally async */ {
   final asy::_Future<core::Object> :async_future = new asy::_Future::•<core::Object>();
   core::bool* :is_sync = false;
   FutureOr<core::Object>? :return_value;
@@ -330,7 +330,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method getFutureOr<T extends core::Object? = dynamic>(self::getFutureOr::T% v) → FutureOr<self::getFutureOr::T%> /* originally async */ {
+static method getFutureOr<T extends core::Object? = dynamic>(self::getFutureOr::T% v) → FutureOr<self::getFutureOr::T%> /* futureValueType= self::getFutureOr::T% */ /* originally async */ {
   final asy::_Future<self::getFutureOr::T%> :async_future = new asy::_Future::•<self::getFutureOr::T%>();
   core::bool* :is_sync = false;
   FutureOr<self::getFutureOr::T%>? :return_value;
@@ -357,7 +357,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method getFuture<T extends core::Object? = dynamic>(self::getFuture::T% v) → asy::Future<self::getFuture::T%> /* originally async */ {
+static method getFuture<T extends core::Object? = dynamic>(self::getFuture::T% v) → asy::Future<self::getFuture::T%> /* futureValueType= self::getFuture::T% */ /* originally async */ {
   final asy::_Future<self::getFuture::T%> :async_future = new asy::_Future::•<self::getFuture::T%>();
   core::bool* :is_sync = false;
   FutureOr<self::getFuture::T%>? :return_value;
diff --git a/pkg/front_end/testcases/general/async_method_with_invalid_type.dart.weak.expect b/pkg/front_end/testcases/general/async_method_with_invalid_type.dart.weak.expect
index 05a55b2..ccacb73 100644
--- a/pkg/front_end/testcases/general/async_method_with_invalid_type.dart.weak.expect
+++ b/pkg/front_end/testcases/general/async_method_with_invalid_type.dart.weak.expect
@@ -8,7 +8,7 @@
 //
 import self as self;
 
-static method foo() → dynamic async {
+static method foo() → dynamic async /* futureValueType= dynamic */ {
   invalid-type x;
   for (dynamic y in x{<invalid>}.z) {
   }
diff --git a/pkg/front_end/testcases/general/async_method_with_invalid_type.dart.weak.modular.expect b/pkg/front_end/testcases/general/async_method_with_invalid_type.dart.weak.modular.expect
index 05a55b2..ccacb73 100644
--- a/pkg/front_end/testcases/general/async_method_with_invalid_type.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/async_method_with_invalid_type.dart.weak.modular.expect
@@ -8,7 +8,7 @@
 //
 import self as self;
 
-static method foo() → dynamic async {
+static method foo() → dynamic async /* futureValueType= dynamic */ {
   invalid-type x;
   for (dynamic y in x{<invalid>}.z) {
   }
diff --git a/pkg/front_end/testcases/general/async_method_with_invalid_type.dart.weak.transformed.expect b/pkg/front_end/testcases/general/async_method_with_invalid_type.dart.weak.transformed.expect
index 5a6c5a5..eaa793aa 100644
--- a/pkg/front_end/testcases/general/async_method_with_invalid_type.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/async_method_with_invalid_type.dart.weak.transformed.expect
@@ -10,7 +10,7 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
-static method foo() → dynamic /* originally async */ {
+static method foo() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/async_nested.dart.weak.expect b/pkg/front_end/testcases/general/async_nested.dart.weak.expect
index f7a0987..57176c1 100644
--- a/pkg/front_end/testcases/general/async_nested.dart.weak.expect
+++ b/pkg/front_end/testcases/general/async_nested.dart.weak.expect
@@ -17,7 +17,7 @@
     return "${this.{self::Node::name}{core::String}} ${let final core::Iterable<dynamic>? #t3 = tmp in #t3 == null ?{core::String?} null : #t3{core::Iterable<dynamic>}.{core::Iterable::join}(" "){([core::String]) → core::String}}".{core::String::trim}(){() → core::String};
   }
 }
-static method main() → void async {
+static method main() → void async /* futureValueType= void */ {
   core::String expected = "1 2 3 4 5 6 7 8 9 10";
   self::Node node = new self::Node::•("1", <self::Node>[new self::Node::•("2", <self::Node>[]), await asy::Future::value<self::Node>(new self::Node::•("3", <self::Node>[await asy::Future::value<self::Node>(new self::Node::•("4", <self::Node>[new self::Node::•("5", <self::Node>[await asy::Future::value<self::Node>(new self::Node::•("6", <self::Node>[await asy::Future::value<self::Node>(new self::Node::•("7", <self::Node>[]))])), await asy::Future::value<self::Node>(new self::Node::•("8", <self::Node>[])), await asy::Future::value<self::Node>(new self::Node::•("9", <self::Node>[]))])]))])), await asy::Future::value<self::Node>(new self::Node::•("10", <self::Node>[]))]);
   core::String actual = node.{self::Node::toSimpleString}(){() → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
diff --git a/pkg/front_end/testcases/general/async_nested.dart.weak.modular.expect b/pkg/front_end/testcases/general/async_nested.dart.weak.modular.expect
index f7a0987..57176c1 100644
--- a/pkg/front_end/testcases/general/async_nested.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/async_nested.dart.weak.modular.expect
@@ -17,7 +17,7 @@
     return "${this.{self::Node::name}{core::String}} ${let final core::Iterable<dynamic>? #t3 = tmp in #t3 == null ?{core::String?} null : #t3{core::Iterable<dynamic>}.{core::Iterable::join}(" "){([core::String]) → core::String}}".{core::String::trim}(){() → core::String};
   }
 }
-static method main() → void async {
+static method main() → void async /* futureValueType= void */ {
   core::String expected = "1 2 3 4 5 6 7 8 9 10";
   self::Node node = new self::Node::•("1", <self::Node>[new self::Node::•("2", <self::Node>[]), await asy::Future::value<self::Node>(new self::Node::•("3", <self::Node>[await asy::Future::value<self::Node>(new self::Node::•("4", <self::Node>[new self::Node::•("5", <self::Node>[await asy::Future::value<self::Node>(new self::Node::•("6", <self::Node>[await asy::Future::value<self::Node>(new self::Node::•("7", <self::Node>[]))])), await asy::Future::value<self::Node>(new self::Node::•("8", <self::Node>[])), await asy::Future::value<self::Node>(new self::Node::•("9", <self::Node>[]))])]))])), await asy::Future::value<self::Node>(new self::Node::•("10", <self::Node>[]))]);
   core::String actual = node.{self::Node::toSimpleString}(){() → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::String;
diff --git a/pkg/front_end/testcases/general/async_nested.dart.weak.transformed.expect b/pkg/front_end/testcases/general/async_nested.dart.weak.transformed.expect
index 9082a3a..e7662de 100644
--- a/pkg/front_end/testcases/general/async_nested.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/async_nested.dart.weak.transformed.expect
@@ -18,7 +18,7 @@
     return "${this.{self::Node::name}{core::String}} ${let final core::Iterable<dynamic>? #t3 = tmp in #t3 == null ?{core::String?} null : #t3{core::Iterable<dynamic>}.{core::Iterable::join}(" "){([core::String]) → core::String}}".{core::String::trim}(){() → core::String};
   }
 }
-static method main() → void /* originally async */ {
+static method main() → void /* futureValueType= void */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/await.dart.weak.expect b/pkg/front_end/testcases/general/await.dart.weak.expect
index e1be515..c9c78d7 100644
--- a/pkg/front_end/testcases/general/await.dart.weak.expect
+++ b/pkg/front_end/testcases/general/await.dart.weak.expect
@@ -2,6 +2,6 @@
 import self as self;
 import "dart:core" as core;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   core::print(await "Hello, World!");
 }
diff --git a/pkg/front_end/testcases/general/await.dart.weak.modular.expect b/pkg/front_end/testcases/general/await.dart.weak.modular.expect
index e1be515..c9c78d7 100644
--- a/pkg/front_end/testcases/general/await.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/await.dart.weak.modular.expect
@@ -2,6 +2,6 @@
 import self as self;
 import "dart:core" as core;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   core::print(await "Hello, World!");
 }
diff --git a/pkg/front_end/testcases/general/await.dart.weak.transformed.expect b/pkg/front_end/testcases/general/await.dart.weak.transformed.expect
index 245023e..8d16530 100644
--- a/pkg/front_end/testcases/general/await.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/await.dart.weak.transformed.expect
@@ -4,7 +4,7 @@
 import "dart:core" as core;
 import "dart:_internal" as _in;
 
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/await_complex.dart.weak.expect b/pkg/front_end/testcases/general/await_complex.dart.weak.expect
index 280661a..18e4d6a 100644
--- a/pkg/front_end/testcases/general/await_complex.dart.weak.expect
+++ b/pkg/front_end/testcases/general/await_complex.dart.weak.expect
@@ -53,7 +53,7 @@
 }
 static method dummy() → dynamic
   return 1;
-static method staticMembers() → dynamic async {
+static method staticMembers() → dynamic async /* futureValueType= dynamic */ {
   core::num a = self::C::staticField.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
   self::expect(2, a);
   core::num f = (self::C::staticField = 1).{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
@@ -67,7 +67,7 @@
   core::num e = self::C::staticField.{core::num::+}(self::C::staticGetter){(core::num) → core::int}.{core::num::+}(self::C::staticSetter = 1){(core::num) → core::int}.{core::num::+}(self::C::staticFoo(1)){(core::num) → core::int}.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
   self::expect(5, e);
 }
-static method topLevelMembers() → dynamic async {
+static method topLevelMembers() → dynamic async /* futureValueType= dynamic */ {
   core::num a = self::globalVariable.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
   self::expect(2, a);
   core::num b = self::topLevelGetter.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
@@ -79,7 +79,7 @@
   core::num e = self::globalVariable.{core::num::+}(self::topLevelGetter){(core::num) → core::int}.{core::num::+}(self::topLevelSetter = 1){(core::num) → core::int}.{core::num::+}(self::topLevelFoo(1)){(core::num) → core::int}.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
   self::expect(5, e);
 }
-static method instanceMembers() → dynamic async {
+static method instanceMembers() → dynamic async /* futureValueType= dynamic */ {
   self::C inst = new self::C::•();
   core::num a = inst.{self::C::field}{core::int}.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
   self::expect(2, a);
@@ -92,7 +92,7 @@
   core::num e = inst.{self::C::field}{core::int}.{core::num::+}(inst.{self::C::getter}{core::int}){(core::num) → core::int}.{core::num::+}(inst.{self::C::setter} = 1){(core::num) → core::int}.{core::num::+}(inst.{self::C::foo}(1){(core::int) → core::int}){(core::num) → core::int}.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
   self::expect(5, e);
 }
-static method others() → dynamic async {
+static method others() → dynamic async /* futureValueType= dynamic */ {
   core::String a = "${self::globalVariable} ${await self::dummy()} ".{core::String::+}(await "someString"){(core::String) → core::String};
   self::expect("1 1 someString", a);
   self::C c = new self::C::•();
@@ -104,7 +104,7 @@
   core::num e = b.{core::List::[]}(0){(core::int) → core::int}.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
   self::expect(2, e);
 }
-static method conditionals() → dynamic async {
+static method conditionals() → dynamic async /* futureValueType= dynamic */ {
   core::bool a = false;
   core::bool b = true;
   core::bool c = a || b || await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
@@ -119,7 +119,7 @@
   on core::Object catch(final core::Object e) {
   }
 }
-static method asserts() → dynamic async {
+static method asserts() → dynamic async /* futureValueType= dynamic */ {
   for (final <T extends core::Object? = dynamic>(T%) → FutureOr<T%>func in <<T extends core::Object? = dynamic>(T%) → FutureOr<T%>>[#C1, #C2]) {
     assert(await func<core::bool>(true){(core::bool) → FutureOr<core::bool>});
     assert(invalid-expression "pkg/front_end/testcases/general/await_complex.dart:120:12: Error: A value of type 'FutureOr<bool>' can't be assigned to a variable of type 'bool'.
@@ -136,7 +136,7 @@
     }
   }
 }
-static method controlFlow() → dynamic async {
+static method controlFlow() → dynamic async /* futureValueType= dynamic */ {
   for (final <T extends core::Object? = dynamic>(T%) → FutureOr<T%>func in <<T extends core::Object? = dynamic>(T%) → FutureOr<T%>>[#C1, #C2]) {
     core::int c = 0;
     for (core::int i = await func<core::int>(0){(core::int) → FutureOr<core::int>}; await func<core::bool>(i.{core::num::<}(5){(core::num) → core::bool}){(core::bool) → FutureOr<core::bool>}; await func<core::int>(let final core::int #t1 = i in let final core::int #t2 = i = #t1.{core::num::+}(1){(core::num) → core::int} in #t1){(core::int) → FutureOr<core::int>}) {
@@ -204,10 +204,10 @@
           throw "unreachable";
         }
     }
-    self::expect(42, await(() → asy::Future<core::int> async {
+    self::expect(42, await(() → asy::Future<core::int> async /* futureValueType= core::int */ {
       return await func<core::int>(42){(core::int) → FutureOr<core::int>};
     })(){() → asy::Future<core::int>});
-    self::expect(42, await(() → asy::Future<core::int> async {
+    self::expect(42, await(() → asy::Future<core::int> async /* futureValueType= core::int */ {
       return func<core::int>(42){(core::int) → FutureOr<core::int>};
     })(){() → asy::Future<core::int>});
     function testStream1() → asy::Stream<core::int> async* {
@@ -220,14 +220,14 @@
     self::expectList(<dynamic>[42], await testStream2(){() → asy::Stream<core::int>}.{asy::Stream::toList}(){() → asy::Future<core::List<core::int>>});
   }
 }
-static method future<T extends core::Object? = dynamic>(self::future::T% value) → FutureOr<self::future::T%> async 
+static method future<T extends core::Object? = dynamic>(self::future::T% value) → FutureOr<self::future::T%> async /* futureValueType= self::future::T% */ 
   return value;
 static method id<T extends core::Object? = dynamic>(self::id::T% value) → FutureOr<self::id::T%>
   return value;
 static method intStream() → asy::Stream<core::int> async* {
   yield 42;
 }
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   for (core::int i = 0; i.{core::num::<}(11){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
     await self::staticMembers();
     await self::topLevelMembers();
diff --git a/pkg/front_end/testcases/general/await_complex.dart.weak.modular.expect b/pkg/front_end/testcases/general/await_complex.dart.weak.modular.expect
index 280661a..18e4d6a 100644
--- a/pkg/front_end/testcases/general/await_complex.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/await_complex.dart.weak.modular.expect
@@ -53,7 +53,7 @@
 }
 static method dummy() → dynamic
   return 1;
-static method staticMembers() → dynamic async {
+static method staticMembers() → dynamic async /* futureValueType= dynamic */ {
   core::num a = self::C::staticField.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
   self::expect(2, a);
   core::num f = (self::C::staticField = 1).{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
@@ -67,7 +67,7 @@
   core::num e = self::C::staticField.{core::num::+}(self::C::staticGetter){(core::num) → core::int}.{core::num::+}(self::C::staticSetter = 1){(core::num) → core::int}.{core::num::+}(self::C::staticFoo(1)){(core::num) → core::int}.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
   self::expect(5, e);
 }
-static method topLevelMembers() → dynamic async {
+static method topLevelMembers() → dynamic async /* futureValueType= dynamic */ {
   core::num a = self::globalVariable.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
   self::expect(2, a);
   core::num b = self::topLevelGetter.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
@@ -79,7 +79,7 @@
   core::num e = self::globalVariable.{core::num::+}(self::topLevelGetter){(core::num) → core::int}.{core::num::+}(self::topLevelSetter = 1){(core::num) → core::int}.{core::num::+}(self::topLevelFoo(1)){(core::num) → core::int}.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
   self::expect(5, e);
 }
-static method instanceMembers() → dynamic async {
+static method instanceMembers() → dynamic async /* futureValueType= dynamic */ {
   self::C inst = new self::C::•();
   core::num a = inst.{self::C::field}{core::int}.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
   self::expect(2, a);
@@ -92,7 +92,7 @@
   core::num e = inst.{self::C::field}{core::int}.{core::num::+}(inst.{self::C::getter}{core::int}){(core::num) → core::int}.{core::num::+}(inst.{self::C::setter} = 1){(core::num) → core::int}.{core::num::+}(inst.{self::C::foo}(1){(core::int) → core::int}){(core::num) → core::int}.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
   self::expect(5, e);
 }
-static method others() → dynamic async {
+static method others() → dynamic async /* futureValueType= dynamic */ {
   core::String a = "${self::globalVariable} ${await self::dummy()} ".{core::String::+}(await "someString"){(core::String) → core::String};
   self::expect("1 1 someString", a);
   self::C c = new self::C::•();
@@ -104,7 +104,7 @@
   core::num e = b.{core::List::[]}(0){(core::int) → core::int}.{core::num::+}(await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::num){(core::num) → core::num};
   self::expect(2, e);
 }
-static method conditionals() → dynamic async {
+static method conditionals() → dynamic async /* futureValueType= dynamic */ {
   core::bool a = false;
   core::bool b = true;
   core::bool c = a || b || await self::dummy() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
@@ -119,7 +119,7 @@
   on core::Object catch(final core::Object e) {
   }
 }
-static method asserts() → dynamic async {
+static method asserts() → dynamic async /* futureValueType= dynamic */ {
   for (final <T extends core::Object? = dynamic>(T%) → FutureOr<T%>func in <<T extends core::Object? = dynamic>(T%) → FutureOr<T%>>[#C1, #C2]) {
     assert(await func<core::bool>(true){(core::bool) → FutureOr<core::bool>});
     assert(invalid-expression "pkg/front_end/testcases/general/await_complex.dart:120:12: Error: A value of type 'FutureOr<bool>' can't be assigned to a variable of type 'bool'.
@@ -136,7 +136,7 @@
     }
   }
 }
-static method controlFlow() → dynamic async {
+static method controlFlow() → dynamic async /* futureValueType= dynamic */ {
   for (final <T extends core::Object? = dynamic>(T%) → FutureOr<T%>func in <<T extends core::Object? = dynamic>(T%) → FutureOr<T%>>[#C1, #C2]) {
     core::int c = 0;
     for (core::int i = await func<core::int>(0){(core::int) → FutureOr<core::int>}; await func<core::bool>(i.{core::num::<}(5){(core::num) → core::bool}){(core::bool) → FutureOr<core::bool>}; await func<core::int>(let final core::int #t1 = i in let final core::int #t2 = i = #t1.{core::num::+}(1){(core::num) → core::int} in #t1){(core::int) → FutureOr<core::int>}) {
@@ -204,10 +204,10 @@
           throw "unreachable";
         }
     }
-    self::expect(42, await(() → asy::Future<core::int> async {
+    self::expect(42, await(() → asy::Future<core::int> async /* futureValueType= core::int */ {
       return await func<core::int>(42){(core::int) → FutureOr<core::int>};
     })(){() → asy::Future<core::int>});
-    self::expect(42, await(() → asy::Future<core::int> async {
+    self::expect(42, await(() → asy::Future<core::int> async /* futureValueType= core::int */ {
       return func<core::int>(42){(core::int) → FutureOr<core::int>};
     })(){() → asy::Future<core::int>});
     function testStream1() → asy::Stream<core::int> async* {
@@ -220,14 +220,14 @@
     self::expectList(<dynamic>[42], await testStream2(){() → asy::Stream<core::int>}.{asy::Stream::toList}(){() → asy::Future<core::List<core::int>>});
   }
 }
-static method future<T extends core::Object? = dynamic>(self::future::T% value) → FutureOr<self::future::T%> async 
+static method future<T extends core::Object? = dynamic>(self::future::T% value) → FutureOr<self::future::T%> async /* futureValueType= self::future::T% */ 
   return value;
 static method id<T extends core::Object? = dynamic>(self::id::T% value) → FutureOr<self::id::T%>
   return value;
 static method intStream() → asy::Stream<core::int> async* {
   yield 42;
 }
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   for (core::int i = 0; i.{core::num::<}(11){(core::num) → core::bool}; i = i.{core::num::+}(1){(core::num) → core::int}) {
     await self::staticMembers();
     await self::topLevelMembers();
diff --git a/pkg/front_end/testcases/general/await_complex.dart.weak.transformed.expect b/pkg/front_end/testcases/general/await_complex.dart.weak.transformed.expect
index e4c6804..21decd4 100644
--- a/pkg/front_end/testcases/general/await_complex.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/await_complex.dart.weak.transformed.expect
@@ -53,7 +53,7 @@
 }
 static method dummy() → dynamic
   return 1;
-static method staticMembers() → dynamic /* originally async */ {
+static method staticMembers() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -109,7 +109,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method topLevelMembers() → dynamic /* originally async */ {
+static method topLevelMembers() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -160,7 +160,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method instanceMembers() → dynamic /* originally async */ {
+static method instanceMembers() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -212,7 +212,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method others() → dynamic /* originally async */ {
+static method others() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -264,7 +264,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method conditionals() → dynamic /* originally async */ {
+static method conditionals() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -336,7 +336,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method asserts() → dynamic /* originally async */ {
+static method asserts() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -410,7 +410,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method controlFlow() → dynamic /* originally async */ {
+static method controlFlow() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -542,7 +542,7 @@
                     }
                 }
               }
-              [yield] let dynamic #t50 = asy::_awaitHelper((() → asy::Future<core::int> /* originally async */ {
+              [yield] let dynamic #t50 = asy::_awaitHelper((() → asy::Future<core::int> /* futureValueType= core::int */ /* originally async */ {
                 final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
                 core::bool* :is_sync = false;
                 core::int? :return_value;
@@ -572,7 +572,7 @@
                 return :async_future;
               })(){() → asy::Future<core::int>}, :async_op_then, :async_op_error) in null;
               self::expect(42, _in::unsafeCast<core::int>(:result_or_exception));
-              [yield] let dynamic #t52 = asy::_awaitHelper((() → asy::Future<core::int> /* originally async */ {
+              [yield] let dynamic #t52 = asy::_awaitHelper((() → asy::Future<core::int> /* futureValueType= core::int */ /* originally async */ {
                 final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
                 core::bool* :is_sync = false;
                 FutureOr<core::int>? :return_value;
@@ -690,7 +690,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method future<T extends core::Object? = dynamic>(self::future::T% value) → FutureOr<self::future::T%> /* originally async */ {
+static method future<T extends core::Object? = dynamic>(self::future::T% value) → FutureOr<self::future::T%> /* futureValueType= self::future::T% */ /* originally async */ {
   final asy::_Future<self::future::T%> :async_future = new asy::_Future::•<self::future::T%>();
   core::bool* :is_sync = false;
   FutureOr<self::future::T%>? :return_value;
@@ -752,7 +752,7 @@
   :controller_stream = :controller.{asy::_AsyncStarStreamController::stream}{asy::Stream<core::int>};
   return :controller_stream;
 }
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/await_in_cascade.dart.weak.expect b/pkg/front_end/testcases/general/await_in_cascade.dart.weak.expect
index b0ffd22..45117a7 100644
--- a/pkg/front_end/testcases/general/await_in_cascade.dart.weak.expect
+++ b/pkg/front_end/testcases/general/await_in_cascade.dart.weak.expect
@@ -9,14 +9,14 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-  method m() → asy::Future<core::List<core::int>> async 
+  method m() → asy::Future<core::List<core::int>> async /* futureValueType= core::List<core::int> */ 
     return let final core::List<core::int> #t1 = <core::int>[] in block {
       #t1.{core::List::add}(await this.{self::C::_m}(){() → asy::Future<core::int>}){(core::int) → void};
     } =>#t1;
-  method _m() → asy::Future<core::int> async 
+  method _m() → asy::Future<core::int> async /* futureValueType= core::int */ 
     return 42;
 }
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   self::expect(42, (await new self::C::•().{self::C::m}(){() → asy::Future<core::List<core::int>>}).{core::Iterable::first}{core::int});
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
diff --git a/pkg/front_end/testcases/general/await_in_cascade.dart.weak.modular.expect b/pkg/front_end/testcases/general/await_in_cascade.dart.weak.modular.expect
index b0ffd22..45117a7 100644
--- a/pkg/front_end/testcases/general/await_in_cascade.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/await_in_cascade.dart.weak.modular.expect
@@ -9,14 +9,14 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-  method m() → asy::Future<core::List<core::int>> async 
+  method m() → asy::Future<core::List<core::int>> async /* futureValueType= core::List<core::int> */ 
     return let final core::List<core::int> #t1 = <core::int>[] in block {
       #t1.{core::List::add}(await this.{self::C::_m}(){() → asy::Future<core::int>}){(core::int) → void};
     } =>#t1;
-  method _m() → asy::Future<core::int> async 
+  method _m() → asy::Future<core::int> async /* futureValueType= core::int */ 
     return 42;
 }
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   self::expect(42, (await new self::C::•().{self::C::m}(){() → asy::Future<core::List<core::int>>}).{core::Iterable::first}{core::int});
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
diff --git a/pkg/front_end/testcases/general/await_in_cascade.dart.weak.transformed.expect b/pkg/front_end/testcases/general/await_in_cascade.dart.weak.transformed.expect
index 652b3a2..4b57e71 100644
--- a/pkg/front_end/testcases/general/await_in_cascade.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/await_in_cascade.dart.weak.transformed.expect
@@ -10,7 +10,7 @@
   synthetic constructor •() → self::C
     : super core::Object::•()
     ;
-  method m() → asy::Future<core::List<core::int>> /* originally async */ {
+  method m() → asy::Future<core::List<core::int>> /* futureValueType= core::List<core::int> */ /* originally async */ {
     final asy::_Future<core::List<core::int>> :async_future = new asy::_Future::•<core::List<core::int>>();
     core::bool* :is_sync = false;
     core::List<core::int>? :return_value;
@@ -41,7 +41,7 @@
     :is_sync = true;
     return :async_future;
   }
-  method _m() → asy::Future<core::int> /* originally async */ {
+  method _m() → asy::Future<core::int> /* futureValueType= core::int */ /* originally async */ {
     final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -69,7 +69,7 @@
     return :async_future;
   }
 }
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/bug33196.dart.weak.expect b/pkg/front_end/testcases/general/bug33196.dart.weak.expect
index d94db31..61269a2 100644
--- a/pkg/front_end/testcases/general/bug33196.dart.weak.expect
+++ b/pkg/front_end/testcases/general/bug33196.dart.weak.expect
@@ -8,6 +8,6 @@
   FutureOr<core::String>result = self::returnsString();
   core::print(result.{core::Object::runtimeType}{core::Type});
 }
-static method returnsString() → FutureOr<core::String> async {
+static method returnsString() → FutureOr<core::String> async /* futureValueType= core::String */ {
   return "oh no";
 }
diff --git a/pkg/front_end/testcases/general/bug33196.dart.weak.modular.expect b/pkg/front_end/testcases/general/bug33196.dart.weak.modular.expect
index d94db31..61269a2 100644
--- a/pkg/front_end/testcases/general/bug33196.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/bug33196.dart.weak.modular.expect
@@ -8,6 +8,6 @@
   FutureOr<core::String>result = self::returnsString();
   core::print(result.{core::Object::runtimeType}{core::Type});
 }
-static method returnsString() → FutureOr<core::String> async {
+static method returnsString() → FutureOr<core::String> async /* futureValueType= core::String */ {
   return "oh no";
 }
diff --git a/pkg/front_end/testcases/general/bug33196.dart.weak.transformed.expect b/pkg/front_end/testcases/general/bug33196.dart.weak.transformed.expect
index b7ed807..25f1e40 100644
--- a/pkg/front_end/testcases/general/bug33196.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/bug33196.dart.weak.transformed.expect
@@ -9,7 +9,7 @@
   FutureOr<core::String>result = self::returnsString();
   core::print(result.{core::Object::runtimeType}{core::Type});
 }
-static method returnsString() → FutureOr<core::String> /* originally async */ {
+static method returnsString() → FutureOr<core::String> /* futureValueType= core::String */ /* originally async */ {
   final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
   core::bool* :is_sync = false;
   core::String? :return_value;
diff --git a/pkg/front_end/testcases/general/bug33206.dart.weak.expect b/pkg/front_end/testcases/general/bug33206.dart.weak.expect
index 3ea6567..3249453 100644
--- a/pkg/front_end/testcases/general/bug33206.dart.weak.expect
+++ b/pkg/front_end/testcases/general/bug33206.dart.weak.expect
@@ -20,20 +20,20 @@
     ;
   method f(dynamic _) → dynamic {}
 }
-static method f1() → asy::Future<core::List<core::Object>> async {
+static method f1() → asy::Future<core::List<core::Object>> async /* futureValueType= core::List<core::Object> */ {
   return <core::Object>[1];
 }
 static method f2() → core::List<core::Object>
   return <core::Object>[2];
-static method f3() → asy::Future<core::Object> async {
+static method f3() → asy::Future<core::Object> async /* futureValueType= core::Object */ {
   return 3;
 }
-static method foo() → asy::Future<self::X> async {
+static method foo() → asy::Future<self::X> async /* futureValueType= self::X */ {
   return new self::X::•(let final self::Y #t1 = new self::Y::•() in block {
     #t1.{self::Y::f}(await self::f1()){(dynamic) → dynamic};
     #t1.{self::Y::f}(self::f2()){(dynamic) → dynamic};
   } =>#t1, await self::f3());
 }
-static method main() → asy::Future<void> async {
+static method main() → asy::Future<void> async /* futureValueType= void */ {
   core::print(await self::foo());
 }
diff --git a/pkg/front_end/testcases/general/bug33206.dart.weak.modular.expect b/pkg/front_end/testcases/general/bug33206.dart.weak.modular.expect
index 3ea6567..3249453 100644
--- a/pkg/front_end/testcases/general/bug33206.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/bug33206.dart.weak.modular.expect
@@ -20,20 +20,20 @@
     ;
   method f(dynamic _) → dynamic {}
 }
-static method f1() → asy::Future<core::List<core::Object>> async {
+static method f1() → asy::Future<core::List<core::Object>> async /* futureValueType= core::List<core::Object> */ {
   return <core::Object>[1];
 }
 static method f2() → core::List<core::Object>
   return <core::Object>[2];
-static method f3() → asy::Future<core::Object> async {
+static method f3() → asy::Future<core::Object> async /* futureValueType= core::Object */ {
   return 3;
 }
-static method foo() → asy::Future<self::X> async {
+static method foo() → asy::Future<self::X> async /* futureValueType= self::X */ {
   return new self::X::•(let final self::Y #t1 = new self::Y::•() in block {
     #t1.{self::Y::f}(await self::f1()){(dynamic) → dynamic};
     #t1.{self::Y::f}(self::f2()){(dynamic) → dynamic};
   } =>#t1, await self::f3());
 }
-static method main() → asy::Future<void> async {
+static method main() → asy::Future<void> async /* futureValueType= void */ {
   core::print(await self::foo());
 }
diff --git a/pkg/front_end/testcases/general/bug33206.dart.weak.transformed.expect b/pkg/front_end/testcases/general/bug33206.dart.weak.transformed.expect
index ee3e7d7..f5586b6 100644
--- a/pkg/front_end/testcases/general/bug33206.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/bug33206.dart.weak.transformed.expect
@@ -21,7 +21,7 @@
     ;
   method f(dynamic _) → dynamic {}
 }
-static method f1() → asy::Future<core::List<core::Object>> /* originally async */ {
+static method f1() → asy::Future<core::List<core::Object>> /* futureValueType= core::List<core::Object> */ /* originally async */ {
   final asy::_Future<core::List<core::Object>> :async_future = new asy::_Future::•<core::List<core::Object>>();
   core::bool* :is_sync = false;
   core::List<core::Object>? :return_value;
@@ -50,7 +50,7 @@
 }
 static method f2() → core::List<core::Object>
   return core::_GrowableList::_literal1<core::Object>(2);
-static method f3() → asy::Future<core::Object> /* originally async */ {
+static method f3() → asy::Future<core::Object> /* futureValueType= core::Object */ /* originally async */ {
   final asy::_Future<core::Object> :async_future = new asy::_Future::•<core::Object>();
   core::bool* :is_sync = false;
   core::Object? :return_value;
@@ -77,7 +77,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method foo() → asy::Future<self::X> /* originally async */ {
+static method foo() → asy::Future<self::X> /* futureValueType= self::X */ /* originally async */ {
   final asy::_Future<self::X> :async_future = new asy::_Future::•<self::X>();
   core::bool* :is_sync = false;
   self::X? :return_value;
@@ -113,7 +113,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method main() → asy::Future<void> /* originally async */ {
+static method main() → asy::Future<void> /* futureValueType= void */ /* originally async */ {
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   void :return_value;
diff --git a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.weak.expect b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.weak.expect
index 562a536..0da4157 100644
--- a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.weak.expect
+++ b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.weak.expect
@@ -5,7 +5,7 @@
 import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
 
 static method main() → dynamic {}
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::m(await LoadLibrary(lib));
 }
 
diff --git a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.weak.modular.expect b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.weak.modular.expect
index 562a536..0da4157 100644
--- a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.weak.modular.expect
@@ -5,7 +5,7 @@
 import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
 
 static method main() → dynamic {}
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::m(await LoadLibrary(lib));
 }
 
diff --git a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.weak.transformed.expect b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.weak.transformed.expect
index 55724af..3517f76 100644
--- a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.weak.transformed.expect
@@ -7,7 +7,7 @@
 import "org-dartlang-testcase:///deferred_lib.dart" deferred as lib;
 
 static method main() → dynamic {}
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.expect
index d4a4508..52401e8 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.expect
@@ -1758,7 +1758,7 @@
       #t235.{core::Map::[]=}{Invariant}(i, i){(core::int*, core::int*) →* void};
   } =>#t235;
 }
-static method testForElementErrors(core::Map<core::int*, core::int*>* map, core::List<core::int*>* list) → dynamic async {
+static method testForElementErrors(core::Map<core::int*, core::int*>* map, core::List<core::int*>* list) → dynamic async /* futureValueType= dynamic */ {
   block {
     final core::List<core::int*>* #t236 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.modular.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.modular.expect
index d4a4508..52401e8 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.modular.expect
@@ -1758,7 +1758,7 @@
       #t235.{core::Map::[]=}{Invariant}(i, i){(core::int*, core::int*) →* void};
   } =>#t235;
 }
-static method testForElementErrors(core::Map<core::int*, core::int*>* map, core::List<core::int*>* list) → dynamic async {
+static method testForElementErrors(core::Map<core::int*, core::int*>* map, core::List<core::int*>* list) → dynamic async /* futureValueType= dynamic */ {
   block {
     final core::List<core::int*>* #t236 = <core::int*>[];
     for (core::int* i = 0; self::oracle<core::String*>("foo") as{TypeError,ForDynamic} core::bool*; i = i.{core::num::+}(1){(core::num*) →* core::int*})
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.transformed.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.transformed.expect
index dad114d..aa93492 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.weak.transformed.expect
@@ -1943,7 +1943,7 @@
       #t235.{core::Map::[]=}{Invariant}(i, i){(core::int*, core::int*) →* void};
   } =>#t235;
 }
-static method testForElementErrors(core::Map<core::int*, core::int*>* map, core::List<core::int*>* list) → dynamic /* originally async */ {
+static method testForElementErrors(core::Map<core::int*, core::int*>* map, core::List<core::int*>* list) → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.expect b/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.expect
index 746e6cf..2596bcd0 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.expect
@@ -1748,7 +1748,7 @@
       #t235.{core::Map::[]=}{Invariant}(i, i){(core::int, core::int) → void};
   } =>#t235;
 }
-static method testForElementErrors(core::Map<core::int, core::int> map, core::List<core::int> list) → dynamic async {
+static method testForElementErrors(core::Map<core::int, core::int> map, core::List<core::int> list) → dynamic async /* futureValueType= dynamic */ {
   block {
     final core::List<core::int> #t236 = <core::int>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.modular.expect b/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.modular.expect
index 746e6cf..2596bcd0 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.modular.expect
@@ -1748,7 +1748,7 @@
       #t235.{core::Map::[]=}{Invariant}(i, i){(core::int, core::int) → void};
   } =>#t235;
 }
-static method testForElementErrors(core::Map<core::int, core::int> map, core::List<core::int> list) → dynamic async {
+static method testForElementErrors(core::Map<core::int, core::int> map, core::List<core::int> list) → dynamic async /* futureValueType= dynamic */ {
   block {
     final core::List<core::int> #t236 = <core::int>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool; i = i.{core::num::+}(1){(core::num) → core::int})
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.transformed.expect b/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.transformed.expect
index c300adc..e2cc511 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference2.dart.weak.transformed.expect
@@ -1933,7 +1933,7 @@
       #t235.{core::Map::[]=}{Invariant}(i, i){(core::int, core::int) → void};
   } =>#t235;
 }
-static method testForElementErrors(core::Map<core::int, core::int> map, core::List<core::int> list) → dynamic /* originally async */ {
+static method testForElementErrors(core::Map<core::int, core::int> map, core::List<core::int> list) → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.weak.expect b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.weak.expect
index 7c506e3..67060c0 100644
--- a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.weak.expect
+++ b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.weak.expect
@@ -13,7 +13,7 @@
 //
 import self as self;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await for (final dynamic #t1 in invalid-expression "pkg/front_end/testcases/general/error_recovery/empty_await_for.dart:2:14: Error: This couldn't be parsed.
   await for () {}
              ^") {
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.weak.modular.expect b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.weak.modular.expect
index 7c506e3..67060c0 100644
--- a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.weak.modular.expect
@@ -13,7 +13,7 @@
 //
 import self as self;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await for (final dynamic #t1 in invalid-expression "pkg/front_end/testcases/general/error_recovery/empty_await_for.dart:2:14: Error: This couldn't be parsed.
   await for () {}
              ^") {
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.weak.transformed.expect b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.weak.transformed.expect
index 2ee9b69..ee95a19 100644
--- a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.weak.transformed.expect
@@ -16,7 +16,7 @@
 import "dart:core" as core;
 import "dart:_internal" as _in;
 
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/flutter_issue64155.dart.weak.expect b/pkg/front_end/testcases/general/flutter_issue64155.dart.weak.expect
index 5cfbd7c..b2bc5d7 100644
--- a/pkg/front_end/testcases/general/flutter_issue64155.dart.weak.expect
+++ b/pkg/front_end/testcases/general/flutter_issue64155.dart.weak.expect
@@ -4,7 +4,7 @@
 import "dart:async" as asy;
 
 abstract class TestMixin<R extends core::Object* = dynamic, T extends core::Object* = dynamic> extends core::Object /*isMixinDeclaration*/  {
-  method test(covariant-by-class asy::Future<self::TestMixin::R*>* fetch) → asy::Future<self::TestMixin::T*>* async {
+  method test(covariant-by-class asy::Future<self::TestMixin::R*>* fetch) → asy::Future<self::TestMixin::T*>* async /* futureValueType= self::TestMixin::T* */ {
     final self::TestMixin::R* response = await fetch;
     self::TestMixin::T* result;
     if(response is self::Response<dynamic>*) {
diff --git a/pkg/front_end/testcases/general/flutter_issue64155.dart.weak.modular.expect b/pkg/front_end/testcases/general/flutter_issue64155.dart.weak.modular.expect
index 5cfbd7c..b2bc5d7 100644
--- a/pkg/front_end/testcases/general/flutter_issue64155.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/flutter_issue64155.dart.weak.modular.expect
@@ -4,7 +4,7 @@
 import "dart:async" as asy;
 
 abstract class TestMixin<R extends core::Object* = dynamic, T extends core::Object* = dynamic> extends core::Object /*isMixinDeclaration*/  {
-  method test(covariant-by-class asy::Future<self::TestMixin::R*>* fetch) → asy::Future<self::TestMixin::T*>* async {
+  method test(covariant-by-class asy::Future<self::TestMixin::R*>* fetch) → asy::Future<self::TestMixin::T*>* async /* futureValueType= self::TestMixin::T* */ {
     final self::TestMixin::R* response = await fetch;
     self::TestMixin::T* result;
     if(response is self::Response<dynamic>*) {
diff --git a/pkg/front_end/testcases/general/flutter_issue64155.dart.weak.transformed.expect b/pkg/front_end/testcases/general/flutter_issue64155.dart.weak.transformed.expect
index 0dcf16e..081530b 100644
--- a/pkg/front_end/testcases/general/flutter_issue64155.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/flutter_issue64155.dart.weak.transformed.expect
@@ -5,7 +5,7 @@
 import "dart:_internal" as _in;
 
 abstract class TestMixin<R extends core::Object* = dynamic, T extends core::Object* = dynamic> extends core::Object /*isMixinDeclaration*/  {
-  method test(covariant-by-class asy::Future<self::TestMixin::R*>* fetch) → asy::Future<self::TestMixin::T*>* /* originally async */ {
+  method test(covariant-by-class asy::Future<self::TestMixin::R*>* fetch) → asy::Future<self::TestMixin::T*>* /* futureValueType= self::TestMixin::T* */ /* originally async */ {
     final asy::_Future<self::TestMixin::T*>* :async_future = new asy::_Future::•<self::TestMixin::T*>();
     core::bool* :is_sync = false;
     FutureOr<self::TestMixin::T*>* :return_value;
diff --git a/pkg/front_end/testcases/general/future_or_test.dart.weak.expect b/pkg/front_end/testcases/general/future_or_test.dart.weak.expect
index cc061fb..2aa86e0 100644
--- a/pkg/front_end/testcases/general/future_or_test.dart.weak.expect
+++ b/pkg/front_end/testcases/general/future_or_test.dart.weak.expect
@@ -27,7 +27,7 @@
   synthetic constructor •() → self::B*
     : super core::Object::•()
     ;
-  method bar() → asy::Future<dynamic>* async 
+  method bar() → asy::Future<dynamic>* async /* futureValueType= dynamic */ 
     return this.{self::B::a}{self::A*}.{self::A::foo}(){() →* dynamic};
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
@@ -45,7 +45,7 @@
   synthetic constructor •() → self::C*
     : super core::Object::•()
     ;
-  method baz() → asy::Future<core::int*>* async 
+  method baz() → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
     return this.{self::C::b}{self::B*}.{self::B::bar}(){() →* asy::Future<dynamic>*} as{TypeError} FutureOr<core::int*>*;
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
diff --git a/pkg/front_end/testcases/general/future_or_test.dart.weak.modular.expect b/pkg/front_end/testcases/general/future_or_test.dart.weak.modular.expect
index cc061fb..2aa86e0 100644
--- a/pkg/front_end/testcases/general/future_or_test.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/future_or_test.dart.weak.modular.expect
@@ -27,7 +27,7 @@
   synthetic constructor •() → self::B*
     : super core::Object::•()
     ;
-  method bar() → asy::Future<dynamic>* async 
+  method bar() → asy::Future<dynamic>* async /* futureValueType= dynamic */ 
     return this.{self::B::a}{self::A*}.{self::A::foo}(){() →* dynamic};
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
@@ -45,7 +45,7 @@
   synthetic constructor •() → self::C*
     : super core::Object::•()
     ;
-  method baz() → asy::Future<core::int*>* async 
+  method baz() → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
     return this.{self::C::b}{self::B*}.{self::B::bar}(){() →* asy::Future<dynamic>*} as{TypeError} FutureOr<core::int*>*;
   abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
   abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
diff --git a/pkg/front_end/testcases/general/future_or_test.dart.weak.transformed.expect b/pkg/front_end/testcases/general/future_or_test.dart.weak.transformed.expect
index f83341f..ffa2007 100644
--- a/pkg/front_end/testcases/general/future_or_test.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/future_or_test.dart.weak.transformed.expect
@@ -27,7 +27,7 @@
   synthetic constructor •() → self::B*
     : super core::Object::•()
     ;
-  method bar() → asy::Future<dynamic>* /* originally async */ {
+  method bar() → asy::Future<dynamic>* /* futureValueType= dynamic */ /* originally async */ {
     final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
@@ -70,7 +70,7 @@
   synthetic constructor •() → self::C*
     : super core::Object::•()
     ;
-  method baz() → asy::Future<core::int*>* /* originally async */ {
+  method baz() → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/general/future_return.dart.weak.expect b/pkg/front_end/testcases/general/future_return.dart.weak.expect
index 9ec0f18..bdb2a13 100644
--- a/pkg/front_end/testcases/general/future_return.dart.weak.expect
+++ b/pkg/front_end/testcases/general/future_return.dart.weak.expect
@@ -31,31 +31,31 @@
 }
 static method returnDynamic() → dynamic
   return new self::Class::•();
-static method returnClass() → self::Class async 
+static method returnClass() → self::Class async /* futureValueType= core::Object? */ 
   return new self::Class::•();
-static method returnFutureClass() → asy::Future<self::Class> async 
+static method returnFutureClass() → asy::Future<self::Class> async /* futureValueType= self::Class */ 
   return new self::Class::•();
-static method returnFutureOrClass() → FutureOr<self::Class> async 
+static method returnFutureOrClass() → FutureOr<self::Class> async /* futureValueType= self::Class */ 
   return new self::Class::•();
-static method returnClassFromDynamic() → self::Class async 
+static method returnClassFromDynamic() → self::Class async /* futureValueType= core::Object? */ 
   return self::returnDynamic();
-static method returnFutureClassDynamic() → asy::Future<self::Class> async 
+static method returnFutureClassDynamic() → asy::Future<self::Class> async /* futureValueType= self::Class */ 
   return self::returnDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<self::Class>;
-static method returnFutureOrClassDynamic() → FutureOr<self::Class> async 
+static method returnFutureOrClassDynamic() → FutureOr<self::Class> async /* futureValueType= self::Class */ 
   return self::returnDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<self::Class>;
-static method returnClassFromFutureClass() → self::Class async 
+static method returnClassFromFutureClass() → self::Class async /* futureValueType= core::Object? */ 
   return self::returnFutureClass();
-static method returnFutureClassFromFutureClass() → asy::Future<self::Class> async 
+static method returnFutureClassFromFutureClass() → asy::Future<self::Class> async /* futureValueType= self::Class */ 
   return self::returnFutureClass();
-static method returnFutureOrClassFromFutureClass() → FutureOr<self::Class> async 
+static method returnFutureOrClassFromFutureClass() → FutureOr<self::Class> async /* futureValueType= self::Class */ 
   return self::returnFutureClass();
-static method returnClassFromFutureOrClass() → self::Class async 
+static method returnClassFromFutureOrClass() → self::Class async /* futureValueType= core::Object? */ 
   return self::returnFutureOrClass();
-static method returnFutureClassFromFutureOrClass() → asy::Future<self::Class> async 
+static method returnFutureClassFromFutureOrClass() → asy::Future<self::Class> async /* futureValueType= self::Class */ 
   return self::returnFutureOrClass();
-static method returnFutureOrClassFromFutureOrClass() → FutureOr<self::Class> async 
+static method returnFutureOrClassFromFutureOrClass() → FutureOr<self::Class> async /* futureValueType= self::Class */ 
   return self::returnFutureOrClass();
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await self::returnClass();
   await self::returnFutureClass();
   await self::returnFutureOrClass();
diff --git a/pkg/front_end/testcases/general/future_return.dart.weak.modular.expect b/pkg/front_end/testcases/general/future_return.dart.weak.modular.expect
index 9ec0f18..bdb2a13 100644
--- a/pkg/front_end/testcases/general/future_return.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/future_return.dart.weak.modular.expect
@@ -31,31 +31,31 @@
 }
 static method returnDynamic() → dynamic
   return new self::Class::•();
-static method returnClass() → self::Class async 
+static method returnClass() → self::Class async /* futureValueType= core::Object? */ 
   return new self::Class::•();
-static method returnFutureClass() → asy::Future<self::Class> async 
+static method returnFutureClass() → asy::Future<self::Class> async /* futureValueType= self::Class */ 
   return new self::Class::•();
-static method returnFutureOrClass() → FutureOr<self::Class> async 
+static method returnFutureOrClass() → FutureOr<self::Class> async /* futureValueType= self::Class */ 
   return new self::Class::•();
-static method returnClassFromDynamic() → self::Class async 
+static method returnClassFromDynamic() → self::Class async /* futureValueType= core::Object? */ 
   return self::returnDynamic();
-static method returnFutureClassDynamic() → asy::Future<self::Class> async 
+static method returnFutureClassDynamic() → asy::Future<self::Class> async /* futureValueType= self::Class */ 
   return self::returnDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<self::Class>;
-static method returnFutureOrClassDynamic() → FutureOr<self::Class> async 
+static method returnFutureOrClassDynamic() → FutureOr<self::Class> async /* futureValueType= self::Class */ 
   return self::returnDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<self::Class>;
-static method returnClassFromFutureClass() → self::Class async 
+static method returnClassFromFutureClass() → self::Class async /* futureValueType= core::Object? */ 
   return self::returnFutureClass();
-static method returnFutureClassFromFutureClass() → asy::Future<self::Class> async 
+static method returnFutureClassFromFutureClass() → asy::Future<self::Class> async /* futureValueType= self::Class */ 
   return self::returnFutureClass();
-static method returnFutureOrClassFromFutureClass() → FutureOr<self::Class> async 
+static method returnFutureOrClassFromFutureClass() → FutureOr<self::Class> async /* futureValueType= self::Class */ 
   return self::returnFutureClass();
-static method returnClassFromFutureOrClass() → self::Class async 
+static method returnClassFromFutureOrClass() → self::Class async /* futureValueType= core::Object? */ 
   return self::returnFutureOrClass();
-static method returnFutureClassFromFutureOrClass() → asy::Future<self::Class> async 
+static method returnFutureClassFromFutureOrClass() → asy::Future<self::Class> async /* futureValueType= self::Class */ 
   return self::returnFutureOrClass();
-static method returnFutureOrClassFromFutureOrClass() → FutureOr<self::Class> async 
+static method returnFutureOrClassFromFutureOrClass() → FutureOr<self::Class> async /* futureValueType= self::Class */ 
   return self::returnFutureOrClass();
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await self::returnClass();
   await self::returnFutureClass();
   await self::returnFutureOrClass();
diff --git a/pkg/front_end/testcases/general/future_return.dart.weak.transformed.expect b/pkg/front_end/testcases/general/future_return.dart.weak.transformed.expect
index 4e5fa39..3614ef4 100644
--- a/pkg/front_end/testcases/general/future_return.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/future_return.dart.weak.transformed.expect
@@ -32,7 +32,7 @@
 }
 static method returnDynamic() → dynamic
   return new self::Class::•();
-static method returnClass() → self::Class /* originally async */ {
+static method returnClass() → self::Class /* futureValueType= core::Object? */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -59,7 +59,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnFutureClass() → asy::Future<self::Class> /* originally async */ {
+static method returnFutureClass() → asy::Future<self::Class> /* futureValueType= self::Class */ /* originally async */ {
   final asy::_Future<self::Class> :async_future = new asy::_Future::•<self::Class>();
   core::bool* :is_sync = false;
   self::Class? :return_value;
@@ -86,7 +86,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnFutureOrClass() → FutureOr<self::Class> /* originally async */ {
+static method returnFutureOrClass() → FutureOr<self::Class> /* futureValueType= self::Class */ /* originally async */ {
   final asy::_Future<self::Class> :async_future = new asy::_Future::•<self::Class>();
   core::bool* :is_sync = false;
   self::Class? :return_value;
@@ -113,7 +113,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnClassFromDynamic() → self::Class /* originally async */ {
+static method returnClassFromDynamic() → self::Class /* futureValueType= core::Object? */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
@@ -140,7 +140,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnFutureClassDynamic() → asy::Future<self::Class> /* originally async */ {
+static method returnFutureClassDynamic() → asy::Future<self::Class> /* futureValueType= self::Class */ /* originally async */ {
   final asy::_Future<self::Class> :async_future = new asy::_Future::•<self::Class>();
   core::bool* :is_sync = false;
   FutureOr<self::Class>? :return_value;
@@ -167,7 +167,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnFutureOrClassDynamic() → FutureOr<self::Class> /* originally async */ {
+static method returnFutureOrClassDynamic() → FutureOr<self::Class> /* futureValueType= self::Class */ /* originally async */ {
   final asy::_Future<self::Class> :async_future = new asy::_Future::•<self::Class>();
   core::bool* :is_sync = false;
   FutureOr<self::Class>? :return_value;
@@ -194,7 +194,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnClassFromFutureClass() → self::Class /* originally async */ {
+static method returnClassFromFutureClass() → self::Class /* futureValueType= core::Object? */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
@@ -221,7 +221,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnFutureClassFromFutureClass() → asy::Future<self::Class> /* originally async */ {
+static method returnFutureClassFromFutureClass() → asy::Future<self::Class> /* futureValueType= self::Class */ /* originally async */ {
   final asy::_Future<self::Class> :async_future = new asy::_Future::•<self::Class>();
   core::bool* :is_sync = false;
   FutureOr<self::Class>? :return_value;
@@ -248,7 +248,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnFutureOrClassFromFutureClass() → FutureOr<self::Class> /* originally async */ {
+static method returnFutureOrClassFromFutureClass() → FutureOr<self::Class> /* futureValueType= self::Class */ /* originally async */ {
   final asy::_Future<self::Class> :async_future = new asy::_Future::•<self::Class>();
   core::bool* :is_sync = false;
   FutureOr<self::Class>? :return_value;
@@ -275,7 +275,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnClassFromFutureOrClass() → self::Class /* originally async */ {
+static method returnClassFromFutureOrClass() → self::Class /* futureValueType= core::Object? */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
@@ -302,7 +302,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnFutureClassFromFutureOrClass() → asy::Future<self::Class> /* originally async */ {
+static method returnFutureClassFromFutureOrClass() → asy::Future<self::Class> /* futureValueType= self::Class */ /* originally async */ {
   final asy::_Future<self::Class> :async_future = new asy::_Future::•<self::Class>();
   core::bool* :is_sync = false;
   FutureOr<self::Class>? :return_value;
@@ -329,7 +329,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnFutureOrClassFromFutureOrClass() → FutureOr<self::Class> /* originally async */ {
+static method returnFutureOrClassFromFutureOrClass() → FutureOr<self::Class> /* futureValueType= self::Class */ /* originally async */ {
   final asy::_Future<self::Class> :async_future = new asy::_Future::•<self::Class>();
   core::bool* :is_sync = false;
   FutureOr<self::Class>? :return_value;
@@ -356,7 +356,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/inferred_void.dart.weak.expect b/pkg/front_end/testcases/general/inferred_void.dart.weak.expect
index c8d8b7d..dbc98d6 100644
--- a/pkg/front_end/testcases/general/inferred_void.dart.weak.expect
+++ b/pkg/front_end/testcases/general/inferred_void.dart.weak.expect
@@ -8,7 +8,7 @@
 static field core::List<void> l1 = <void>[self::method()];
 static field core::List<void> l2 = <void>[self::method()];
 static method method() → void {}
-static method test(core::Iterable<void> iterable, asy::Stream<void> stream) → dynamic async {
+static method test(core::Iterable<void> iterable, asy::Stream<void> stream) → dynamic async /* futureValueType= dynamic */ {
   void v1 = self::method();
   void v2 = self::method();
   for (void v3 in iterable) {
diff --git a/pkg/front_end/testcases/general/inferred_void.dart.weak.modular.expect b/pkg/front_end/testcases/general/inferred_void.dart.weak.modular.expect
index c8d8b7d..dbc98d6 100644
--- a/pkg/front_end/testcases/general/inferred_void.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/inferred_void.dart.weak.modular.expect
@@ -8,7 +8,7 @@
 static field core::List<void> l1 = <void>[self::method()];
 static field core::List<void> l2 = <void>[self::method()];
 static method method() → void {}
-static method test(core::Iterable<void> iterable, asy::Stream<void> stream) → dynamic async {
+static method test(core::Iterable<void> iterable, asy::Stream<void> stream) → dynamic async /* futureValueType= dynamic */ {
   void v1 = self::method();
   void v2 = self::method();
   for (void v3 in iterable) {
diff --git a/pkg/front_end/testcases/general/inferred_void.dart.weak.transformed.expect b/pkg/front_end/testcases/general/inferred_void.dart.weak.transformed.expect
index dc58e3d..cc36db2 100644
--- a/pkg/front_end/testcases/general/inferred_void.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/inferred_void.dart.weak.transformed.expect
@@ -9,7 +9,7 @@
 static field core::List<void> l1 = core::_GrowableList::_literal1<void>(self::method());
 static field core::List<void> l2 = core::_GrowableList::_literal1<void>(self::method());
 static method method() → void {}
-static method test(core::Iterable<void> iterable, asy::Stream<void> stream) → dynamic /* originally async */ {
+static method test(core::Iterable<void> iterable, asy::Stream<void> stream) → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/issue38253b.dart.weak.expect b/pkg/front_end/testcases/general/issue38253b.dart.weak.expect
index 3d3ebd1..be3108a 100644
--- a/pkg/front_end/testcases/general/issue38253b.dart.weak.expect
+++ b/pkg/front_end/testcases/general/issue38253b.dart.weak.expect
@@ -26,7 +26,7 @@
     return;
     ^" in null;
   }
-  function f2() → invalid-type async {
+  function f2() → invalid-type async /* futureValueType= invalid-type */ {
     return invalid-expression "pkg/front_end/testcases/general/issue38253b.dart:11:5: Error: A value must be explicitly returned from a non-void async function.
     return;
     ^" in null;
diff --git a/pkg/front_end/testcases/general/issue38253b.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue38253b.dart.weak.modular.expect
index 3d3ebd1..be3108a 100644
--- a/pkg/front_end/testcases/general/issue38253b.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/issue38253b.dart.weak.modular.expect
@@ -26,7 +26,7 @@
     return;
     ^" in null;
   }
-  function f2() → invalid-type async {
+  function f2() → invalid-type async /* futureValueType= invalid-type */ {
     return invalid-expression "pkg/front_end/testcases/general/issue38253b.dart:11:5: Error: A value must be explicitly returned from a non-void async function.
     return;
     ^" in null;
diff --git a/pkg/front_end/testcases/general/issue38253b.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue38253b.dart.weak.transformed.expect
index 5073c13..0726288 100644
--- a/pkg/front_end/testcases/general/issue38253b.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/issue38253b.dart.weak.transformed.expect
@@ -28,7 +28,7 @@
     return;
     ^" in null;
   }
-  function f2() → invalid-type /* originally async */ {
+  function f2() → invalid-type /* futureValueType= invalid-type */ /* originally async */ {
     final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
diff --git a/pkg/front_end/testcases/general/issue38253c.dart.weak.expect b/pkg/front_end/testcases/general/issue38253c.dart.weak.expect
index 2de98d4..7681572 100644
--- a/pkg/front_end/testcases/general/issue38253c.dart.weak.expect
+++ b/pkg/front_end/testcases/general/issue38253c.dart.weak.expect
@@ -24,18 +24,18 @@
 
 static field () → Null a = () → Null {
   function f1() → invalid-type {}
-  function f2() → invalid-type async {}
+  function f2() → invalid-type async /* futureValueType= invalid-type */ {}
   function f3() → core::int {
     return invalid-expression "pkg/front_end/testcases/general/issue38253c.dart:8:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
   int f3() {}
   ^" in null;
   }
-  function f4() → asy::Future<core::int> async {
+  function f4() → asy::Future<core::int> async /* futureValueType= core::int */ {
     return invalid-expression "pkg/front_end/testcases/general/issue38253c.dart:9:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
   Future<int> f4() async {}
   ^" in null;
   }
 };
-static field (dynamic) → asy::Future<dynamic> b = (dynamic f) → asy::Future<dynamic> async => await f;
+static field (dynamic) → asy::Future<dynamic> b = (dynamic f) → asy::Future<dynamic> async /* futureValueType= dynamic */ => await f;
 static field (dynamic) → dynamic c = (dynamic f) → dynamic => f;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue38253c.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue38253c.dart.weak.modular.expect
index 2de98d4..7681572 100644
--- a/pkg/front_end/testcases/general/issue38253c.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/issue38253c.dart.weak.modular.expect
@@ -24,18 +24,18 @@
 
 static field () → Null a = () → Null {
   function f1() → invalid-type {}
-  function f2() → invalid-type async {}
+  function f2() → invalid-type async /* futureValueType= invalid-type */ {}
   function f3() → core::int {
     return invalid-expression "pkg/front_end/testcases/general/issue38253c.dart:8:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
   int f3() {}
   ^" in null;
   }
-  function f4() → asy::Future<core::int> async {
+  function f4() → asy::Future<core::int> async /* futureValueType= core::int */ {
     return invalid-expression "pkg/front_end/testcases/general/issue38253c.dart:9:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
   Future<int> f4() async {}
   ^" in null;
   }
 };
-static field (dynamic) → asy::Future<dynamic> b = (dynamic f) → asy::Future<dynamic> async => await f;
+static field (dynamic) → asy::Future<dynamic> b = (dynamic f) → asy::Future<dynamic> async /* futureValueType= dynamic */ => await f;
 static field (dynamic) → dynamic c = (dynamic f) → dynamic => f;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/issue38253c.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue38253c.dart.weak.transformed.expect
index d67c665..8beb24a 100644
--- a/pkg/front_end/testcases/general/issue38253c.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/issue38253c.dart.weak.transformed.expect
@@ -24,7 +24,7 @@
 
 static field () → Null a = () → Null {
   function f1() → invalid-type {}
-  function f2() → invalid-type /* originally async */ {
+  function f2() → invalid-type /* futureValueType= invalid-type */ /* originally async */ {
     final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     dynamic :return_value;
@@ -53,7 +53,7 @@
   int f3() {}
   ^" in null;
   }
-  function f4() → asy::Future<core::int> /* originally async */ {
+  function f4() → asy::Future<core::int> /* futureValueType= core::int */ /* originally async */ {
     final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
     core::bool* :is_sync = false;
     FutureOr<core::int>? :return_value;
@@ -83,7 +83,7 @@
     return :async_future;
   }
 };
-static field (dynamic) → asy::Future<dynamic> b = (dynamic f) → asy::Future<dynamic> /* originally async */ {
+static field (dynamic) → asy::Future<dynamic> b = (dynamic f) → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
diff --git a/pkg/front_end/testcases/general/issue40662.dart.weak.expect b/pkg/front_end/testcases/general/issue40662.dart.weak.expect
index dc6a6d8..d376a6f 100644
--- a/pkg/front_end/testcases/general/issue40662.dart.weak.expect
+++ b/pkg/front_end/testcases/general/issue40662.dart.weak.expect
@@ -6,9 +6,9 @@
   self::expect(1.{core::int::unary-}(){() →* core::int*}, a);
   self::expect(1.{core::int::unary-}(){() →* core::int*}, b.{core::List::[]}(0){(core::int*) →* core::int*}.{core::num::-}(2){(core::num*) →* core::int*});
 }
-static method foo(core::int* x) → dynamic async 
+static method foo(core::int* x) → dynamic async /* futureValueType= dynamic */ 
   return self::bar(x.{core::num::-}(1){(core::num*) →* core::int*}, !(x == null) ?{core::List<core::int*>*} <core::int*>[x.{core::num::+}(1){(core::num*) →* core::int*}, x.{core::num::+}(2){(core::num*) →* core::int*}, await null] : null);
-static method main() → void async 
+static method main() → void async /* futureValueType= void */ 
   return await self::foo(0);
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!(expected =={core::Object::==}{(core::Object*) →* core::bool*} actual))
diff --git a/pkg/front_end/testcases/general/issue40662.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue40662.dart.weak.modular.expect
index dc6a6d8..d376a6f 100644
--- a/pkg/front_end/testcases/general/issue40662.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/issue40662.dart.weak.modular.expect
@@ -6,9 +6,9 @@
   self::expect(1.{core::int::unary-}(){() →* core::int*}, a);
   self::expect(1.{core::int::unary-}(){() →* core::int*}, b.{core::List::[]}(0){(core::int*) →* core::int*}.{core::num::-}(2){(core::num*) →* core::int*});
 }
-static method foo(core::int* x) → dynamic async 
+static method foo(core::int* x) → dynamic async /* futureValueType= dynamic */ 
   return self::bar(x.{core::num::-}(1){(core::num*) →* core::int*}, !(x == null) ?{core::List<core::int*>*} <core::int*>[x.{core::num::+}(1){(core::num*) →* core::int*}, x.{core::num::+}(2){(core::num*) →* core::int*}, await null] : null);
-static method main() → void async 
+static method main() → void async /* futureValueType= void */ 
   return await self::foo(0);
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!(expected =={core::Object::==}{(core::Object*) →* core::bool*} actual))
diff --git a/pkg/front_end/testcases/general/issue40662.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue40662.dart.weak.transformed.expect
index 4fef8f9..4854611 100644
--- a/pkg/front_end/testcases/general/issue40662.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/issue40662.dart.weak.transformed.expect
@@ -8,7 +8,7 @@
   self::expect(1.{core::int::unary-}(){() →* core::int*}, a);
   self::expect(1.{core::int::unary-}(){() →* core::int*}, b.{core::List::[]}(0){(core::int*) →* core::int*}.{core::num::-}(2){(core::num*) →* core::int*});
 }
-static method foo(core::int* x) → dynamic /* originally async */ {
+static method foo(core::int* x) → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
@@ -50,7 +50,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method main() → void /* originally async */ {
+static method main() → void /* futureValueType= void */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
diff --git a/pkg/front_end/testcases/general/issue42615.dart.weak.expect b/pkg/front_end/testcases/general/issue42615.dart.weak.expect
index 08aafe4..4590283 100644
--- a/pkg/front_end/testcases/general/issue42615.dart.weak.expect
+++ b/pkg/front_end/testcases/general/issue42615.dart.weak.expect
@@ -22,7 +22,7 @@
 static method method() → dynamic
   return null;
 static method main() → dynamic {
-  new self::Class::•<dynamic>(a: () → FutureOr<core::List<dynamic>*>* async => self::method() as{TypeError} FutureOr<core::List<dynamic>*>*);
+  new self::Class::•<dynamic>(a: () → FutureOr<core::List<dynamic>*>* async /* futureValueType= core::List<dynamic>* */ => self::method() as{TypeError} FutureOr<core::List<dynamic>*>*);
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/general/issue42615.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue42615.dart.weak.modular.expect
index 08aafe4..4590283 100644
--- a/pkg/front_end/testcases/general/issue42615.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/issue42615.dart.weak.modular.expect
@@ -22,7 +22,7 @@
 static method method() → dynamic
   return null;
 static method main() → dynamic {
-  new self::Class::•<dynamic>(a: () → FutureOr<core::List<dynamic>*>* async => self::method() as{TypeError} FutureOr<core::List<dynamic>*>*);
+  new self::Class::•<dynamic>(a: () → FutureOr<core::List<dynamic>*>* async /* futureValueType= core::List<dynamic>* */ => self::method() as{TypeError} FutureOr<core::List<dynamic>*>*);
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/general/issue42615.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue42615.dart.weak.transformed.expect
index 3d98e0c..a5d9155 100644
--- a/pkg/front_end/testcases/general/issue42615.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/issue42615.dart.weak.transformed.expect
@@ -23,7 +23,7 @@
 static method method() → dynamic
   return null;
 static method main() → dynamic {
-  new self::Class::•<dynamic>(a: () → FutureOr<core::List<dynamic>*>* /* originally async */ {
+  new self::Class::•<dynamic>(a: () → FutureOr<core::List<dynamic>*>* /* futureValueType= core::List<dynamic>* */ /* originally async */ {
     final asy::_Future<core::List<dynamic>*>* :async_future = new asy::_Future::•<core::List<dynamic>*>();
     core::bool* :is_sync = false;
     FutureOr<core::List<dynamic>*>* :return_value;
diff --git a/pkg/front_end/testcases/general/issue46956.dart.weak.expect b/pkg/front_end/testcases/general/issue46956.dart.weak.expect
index eb4a9a3..23b5061 100644
--- a/pkg/front_end/testcases/general/issue46956.dart.weak.expect
+++ b/pkg/front_end/testcases/general/issue46956.dart.weak.expect
@@ -13,13 +13,13 @@
 static method foo<X extends core::Object?>(self::A<self::foo::X%> x) → asy::Future<self::foo::X?>
   return throw 42;
 static method bar(core::String? y) → dynamic {}
-static method test(self::A<core::String> a) → dynamic async {
-  final core::String? x = await(() → asy::Future<core::String?> async {
+static method test(self::A<core::String> a) → dynamic async /* futureValueType= dynamic */ {
+  final core::String? x = await(() → asy::Future<core::String?> async /* futureValueType= core::String? */ {
     return self::foo<core::String>(a);
   })(){() → asy::Future<core::String?>};
   self::bar(x);
 }
-static method test2(self::A<core::String> a) → dynamic async {
+static method test2(self::A<core::String> a) → dynamic async /* futureValueType= dynamic */ {
   return self::foo<core::String>(a);
 }
 static method test3(self::A<core::String> a) → dynamic {
diff --git a/pkg/front_end/testcases/general/issue46956.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue46956.dart.weak.modular.expect
index eb4a9a3..23b5061 100644
--- a/pkg/front_end/testcases/general/issue46956.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/issue46956.dart.weak.modular.expect
@@ -13,13 +13,13 @@
 static method foo<X extends core::Object?>(self::A<self::foo::X%> x) → asy::Future<self::foo::X?>
   return throw 42;
 static method bar(core::String? y) → dynamic {}
-static method test(self::A<core::String> a) → dynamic async {
-  final core::String? x = await(() → asy::Future<core::String?> async {
+static method test(self::A<core::String> a) → dynamic async /* futureValueType= dynamic */ {
+  final core::String? x = await(() → asy::Future<core::String?> async /* futureValueType= core::String? */ {
     return self::foo<core::String>(a);
   })(){() → asy::Future<core::String?>};
   self::bar(x);
 }
-static method test2(self::A<core::String> a) → dynamic async {
+static method test2(self::A<core::String> a) → dynamic async /* futureValueType= dynamic */ {
   return self::foo<core::String>(a);
 }
 static method test3(self::A<core::String> a) → dynamic {
diff --git a/pkg/front_end/testcases/general/issue46956.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue46956.dart.weak.transformed.expect
index 184f658..5209384 100644
--- a/pkg/front_end/testcases/general/issue46956.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/issue46956.dart.weak.transformed.expect
@@ -14,7 +14,7 @@
 static method foo<X extends core::Object?>(self::A<self::foo::X%> x) → asy::Future<self::foo::X?>
   return throw 42;
 static method bar(core::String? y) → dynamic {}
-static method test(self::A<core::String> a) → dynamic /* originally async */ {
+static method test(self::A<core::String> a) → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -27,7 +27,7 @@
     try {
       #L1:
       {
-        [yield] let dynamic #t1 = asy::_awaitHelper((() → asy::Future<core::String?> /* originally async */ {
+        [yield] let dynamic #t1 = asy::_awaitHelper((() → asy::Future<core::String?> /* futureValueType= core::String? */ /* originally async */ {
           final asy::_Future<core::String?> :async_future = new asy::_Future::•<core::String?>();
           core::bool* :is_sync = false;
           FutureOr<core::String?>? :return_value;
@@ -69,7 +69,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method test2(self::A<core::String> a) → dynamic /* originally async */ {
+static method test2(self::A<core::String> a) → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
diff --git a/pkg/front_end/testcases/general/issue47057.dart.weak.expect b/pkg/front_end/testcases/general/issue47057.dart.weak.expect
index abd22ad..da93591 100644
--- a/pkg/front_end/testcases/general/issue47057.dart.weak.expect
+++ b/pkg/front_end/testcases/general/issue47057.dart.weak.expect
@@ -5,7 +5,7 @@
 
 import "dart:async";
 
-static method foo<X extends core::Object?>(self::foo::X% x) → asy::Future<core::int> async {
+static method foo<X extends core::Object?>(self::foo::X% x) → asy::Future<core::int> async /* futureValueType= core::int */ {
   if(x is{ForNonNullableByDefault} asy::Future<core::int>) {
     return x{self::foo::X% & asy::Future<core::int> /* '%' & '!' = '!' */};
   }
diff --git a/pkg/front_end/testcases/general/issue47057.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue47057.dart.weak.modular.expect
index abd22ad..da93591 100644
--- a/pkg/front_end/testcases/general/issue47057.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/issue47057.dart.weak.modular.expect
@@ -5,7 +5,7 @@
 
 import "dart:async";
 
-static method foo<X extends core::Object?>(self::foo::X% x) → asy::Future<core::int> async {
+static method foo<X extends core::Object?>(self::foo::X% x) → asy::Future<core::int> async /* futureValueType= core::int */ {
   if(x is{ForNonNullableByDefault} asy::Future<core::int>) {
     return x{self::foo::X% & asy::Future<core::int> /* '%' & '!' = '!' */};
   }
diff --git a/pkg/front_end/testcases/general/issue47057.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue47057.dart.weak.transformed.expect
index 1e3ff27..745e0b9 100644
--- a/pkg/front_end/testcases/general/issue47057.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/issue47057.dart.weak.transformed.expect
@@ -5,7 +5,7 @@
 
 import "dart:async";
 
-static method foo<X extends core::Object?>(self::foo::X% x) → asy::Future<core::int> /* originally async */ {
+static method foo<X extends core::Object?>(self::foo::X% x) → asy::Future<core::int> /* futureValueType= core::int */ /* originally async */ {
   final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
   core::bool* :is_sync = false;
   FutureOr<core::int>? :return_value;
diff --git a/pkg/front_end/testcases/general/issue48347.dart.weak.expect b/pkg/front_end/testcases/general/issue48347.dart.weak.expect
index 555e190..4925232d 100644
--- a/pkg/front_end/testcases/general/issue48347.dart.weak.expect
+++ b/pkg/front_end/testcases/general/issue48347.dart.weak.expect
@@ -4,7 +4,7 @@
 
 import "dart:async";
 
-static method test(asy::StreamController<void> _eventStreamController) → dynamic async {
+static method test(asy::StreamController<void> _eventStreamController) → dynamic async /* futureValueType= dynamic */ {
   await for (final void _ in _eventStreamController.{asy::StreamController::stream}{asy::Stream<void>}) {
   }
 }
diff --git a/pkg/front_end/testcases/general/issue48347.dart.weak.modular.expect b/pkg/front_end/testcases/general/issue48347.dart.weak.modular.expect
index 555e190..4925232d 100644
--- a/pkg/front_end/testcases/general/issue48347.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/issue48347.dart.weak.modular.expect
@@ -4,7 +4,7 @@
 
 import "dart:async";
 
-static method test(asy::StreamController<void> _eventStreamController) → dynamic async {
+static method test(asy::StreamController<void> _eventStreamController) → dynamic async /* futureValueType= dynamic */ {
   await for (final void _ in _eventStreamController.{asy::StreamController::stream}{asy::Stream<void>}) {
   }
 }
diff --git a/pkg/front_end/testcases/general/issue48347.dart.weak.transformed.expect b/pkg/front_end/testcases/general/issue48347.dart.weak.transformed.expect
index 80b72a9..cb2e8b2 100644
--- a/pkg/front_end/testcases/general/issue48347.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/issue48347.dart.weak.transformed.expect
@@ -6,7 +6,7 @@
 
 import "dart:async";
 
-static method test(asy::StreamController<void> _eventStreamController) → dynamic /* originally async */ {
+static method test(asy::StreamController<void> _eventStreamController) → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.expect b/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.expect
index c43b411..21cedca 100644
--- a/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.expect
+++ b/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → self::X
     : super core::Object::•()
     ;
-  method _foo() → void async {
+  method _foo() → void async /* futureValueType= void */ {
     await null;
     core::print("hello");
   }
diff --git a/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.modular.expect b/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.modular.expect
index c43b411..21cedca 100644
--- a/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.modular.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → self::X
     : super core::Object::•()
     ;
-  method _foo() → void async {
+  method _foo() → void async /* futureValueType= void */ {
     await null;
     core::print("hello");
   }
diff --git a/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.transformed.expect b/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.transformed.expect
index f1d1f67..f3c06a2 100644
--- a/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/no_such_method_forwarder.dart.weak.transformed.expect
@@ -8,7 +8,7 @@
   synthetic constructor •() → self::X
     : super core::Object::•()
     ;
-  method _foo() → void /* originally async */ {
+  method _foo() → void /* futureValueType= void */ /* originally async */ {
     final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/regression_flutter51828.dart.weak.expect b/pkg/front_end/testcases/general/regression_flutter51828.dart.weak.expect
index 7171f2d..314e556 100644
--- a/pkg/front_end/testcases/general/regression_flutter51828.dart.weak.expect
+++ b/pkg/front_end/testcases/general/regression_flutter51828.dart.weak.expect
@@ -7,13 +7,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  method foo(dynamic x) → asy::Future<void> async {}
+  method foo(dynamic x) → asy::Future<void> async /* futureValueType= void */ {}
 }
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  method bar(dynamic x) → asy::Future<void> async {}
+  method bar(dynamic x) → asy::Future<void> async /* futureValueType= void */ {}
 }
-static method main() → dynamic async 
+static method main() → dynamic async /* futureValueType= dynamic */ 
   return <asy::Future<void>>[new self::A::•().{self::A::foo}(await null){(dynamic) → asy::Future<void>}, new self::B::•().{self::B::bar}(await null){(dynamic) → asy::Future<void>}];
diff --git a/pkg/front_end/testcases/general/regression_flutter51828.dart.weak.modular.expect b/pkg/front_end/testcases/general/regression_flutter51828.dart.weak.modular.expect
index 7171f2d..314e556 100644
--- a/pkg/front_end/testcases/general/regression_flutter51828.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/regression_flutter51828.dart.weak.modular.expect
@@ -7,13 +7,13 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  method foo(dynamic x) → asy::Future<void> async {}
+  method foo(dynamic x) → asy::Future<void> async /* futureValueType= void */ {}
 }
 class B extends core::Object {
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  method bar(dynamic x) → asy::Future<void> async {}
+  method bar(dynamic x) → asy::Future<void> async /* futureValueType= void */ {}
 }
-static method main() → dynamic async 
+static method main() → dynamic async /* futureValueType= dynamic */ 
   return <asy::Future<void>>[new self::A::•().{self::A::foo}(await null){(dynamic) → asy::Future<void>}, new self::B::•().{self::B::bar}(await null){(dynamic) → asy::Future<void>}];
diff --git a/pkg/front_end/testcases/general/regression_flutter51828.dart.weak.transformed.expect b/pkg/front_end/testcases/general/regression_flutter51828.dart.weak.transformed.expect
index 34a3bef..1fe23ba 100644
--- a/pkg/front_end/testcases/general/regression_flutter51828.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/regression_flutter51828.dart.weak.transformed.expect
@@ -8,7 +8,7 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-  method foo(dynamic x) → asy::Future<void> /* originally async */ {
+  method foo(dynamic x) → asy::Future<void> /* futureValueType= void */ /* originally async */ {
     final asy::_Future<void> :async_future = new asy::_Future::•<void>();
     core::bool* :is_sync = false;
     void :return_value;
@@ -37,7 +37,7 @@
   synthetic constructor •() → self::B
     : super core::Object::•()
     ;
-  method bar(dynamic x) → asy::Future<void> /* originally async */ {
+  method bar(dynamic x) → asy::Future<void> /* futureValueType= void */ /* originally async */ {
     final asy::_Future<void> :async_future = new asy::_Future::•<void>();
     core::bool* :is_sync = false;
     void :return_value;
@@ -62,7 +62,7 @@
     return :async_future;
   }
 }
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/general/return_async_promoted.dart b/pkg/front_end/testcases/general/return_async_promoted.dart
new file mode 100644
index 0000000..c6560d3
--- /dev/null
+++ b/pkg/front_end/testcases/general/return_async_promoted.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2022, 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.
+
+import 'return_async_promoted_lib.dart';
+
+void main() {
+  var f = <T>(o) async => o is int ? o : throw '';
+  var g = () async => legacy();
+}
+
+int? nullable() => null;
+int? nonNullable() => 0;
diff --git a/pkg/front_end/testcases/general/return_async_promoted.dart.textual_outline.expect b/pkg/front_end/testcases/general/return_async_promoted.dart.textual_outline.expect
new file mode 100644
index 0000000..b960f98
--- /dev/null
+++ b/pkg/front_end/testcases/general/return_async_promoted.dart.textual_outline.expect
@@ -0,0 +1,5 @@
+import 'return_async_promoted_lib.dart';
+
+void main() {}
+int? nullable() => null;
+int? nonNullable() => 0;
diff --git a/pkg/front_end/testcases/general/return_async_promoted.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/return_async_promoted.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..311eaa7
--- /dev/null
+++ b/pkg/front_end/testcases/general/return_async_promoted.dart.textual_outline_modelled.expect
@@ -0,0 +1,5 @@
+import 'return_async_promoted_lib.dart';
+
+int? nonNullable() => 0;
+int? nullable() => null;
+void main() {}
diff --git a/pkg/front_end/testcases/general/return_async_promoted.dart.weak.expect b/pkg/front_end/testcases/general/return_async_promoted.dart.weak.expect
new file mode 100644
index 0000000..1ed7164
--- /dev/null
+++ b/pkg/front_end/testcases/general/return_async_promoted.dart.weak.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "return_async_promoted_lib.dart" as ret;
+
+import "org-dartlang-testcase:///return_async_promoted_lib.dart";
+
+static method main() → void {
+  <T extends core::Object? = dynamic>(dynamic) → asy::Future<core::int> f = <T extends core::Object? = dynamic>(dynamic o) → asy::Future<core::int> async /* futureValueType= core::int */ => o is{ForNonNullableByDefault} core::int ?{core::int} o{core::int} : throw "";
+  () → asy::Future<core::int> g = () → asy::Future<core::int> async /* futureValueType= core::int* */ => ret::legacy();
+}
+static method nullable() → core::int?
+  return null;
+static method nonNullable() → core::int?
+  return 0;
+
+library;
+import self as ret;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "return_async_promoted.dart" as self;
+
+import "org-dartlang-testcase:///return_async_promoted.dart";
+
+static method legacy() → core::int* {
+  <T extends core::Object* = dynamic>(dynamic) →* asy::Future<core::int*>* f = <T extends core::Object* = dynamic>(dynamic o) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => o is core::int* ?{core::int*} o{core::int*} : throw "";
+  () →* asy::Future<core::int*>* g = () → asy::Future<core::int*>* async /* futureValueType= core::int* */ => self::nullable();
+  () →* asy::Future<core::int*>* h = () → asy::Future<core::int*>* async /* futureValueType= core::int* */ => self::nonNullable();
+  return null;
+}
diff --git a/pkg/front_end/testcases/general/return_async_promoted.dart.weak.modular.expect b/pkg/front_end/testcases/general/return_async_promoted.dart.weak.modular.expect
new file mode 100644
index 0000000..1ed7164
--- /dev/null
+++ b/pkg/front_end/testcases/general/return_async_promoted.dart.weak.modular.expect
@@ -0,0 +1,31 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "return_async_promoted_lib.dart" as ret;
+
+import "org-dartlang-testcase:///return_async_promoted_lib.dart";
+
+static method main() → void {
+  <T extends core::Object? = dynamic>(dynamic) → asy::Future<core::int> f = <T extends core::Object? = dynamic>(dynamic o) → asy::Future<core::int> async /* futureValueType= core::int */ => o is{ForNonNullableByDefault} core::int ?{core::int} o{core::int} : throw "";
+  () → asy::Future<core::int> g = () → asy::Future<core::int> async /* futureValueType= core::int* */ => ret::legacy();
+}
+static method nullable() → core::int?
+  return null;
+static method nonNullable() → core::int?
+  return 0;
+
+library;
+import self as ret;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "return_async_promoted.dart" as self;
+
+import "org-dartlang-testcase:///return_async_promoted.dart";
+
+static method legacy() → core::int* {
+  <T extends core::Object* = dynamic>(dynamic) →* asy::Future<core::int*>* f = <T extends core::Object* = dynamic>(dynamic o) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => o is core::int* ?{core::int*} o{core::int*} : throw "";
+  () →* asy::Future<core::int*>* g = () → asy::Future<core::int*>* async /* futureValueType= core::int* */ => self::nullable();
+  () →* asy::Future<core::int*>* h = () → asy::Future<core::int*>* async /* futureValueType= core::int* */ => self::nonNullable();
+  return null;
+}
diff --git a/pkg/front_end/testcases/general/return_async_promoted.dart.weak.outline.expect b/pkg/front_end/testcases/general/return_async_promoted.dart.weak.outline.expect
new file mode 100644
index 0000000..d14947e
--- /dev/null
+++ b/pkg/front_end/testcases/general/return_async_promoted.dart.weak.outline.expect
@@ -0,0 +1,21 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///return_async_promoted_lib.dart";
+
+static method main() → void
+  ;
+static method nullable() → core::int?
+  ;
+static method nonNullable() → core::int?
+  ;
+
+library;
+import self as self2;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///return_async_promoted.dart";
+
+static method legacy() → core::int*
+  ;
diff --git a/pkg/front_end/testcases/general/return_async_promoted.dart.weak.transformed.expect b/pkg/front_end/testcases/general/return_async_promoted.dart.weak.transformed.expect
new file mode 100644
index 0000000..9e92a56
--- /dev/null
+++ b/pkg/front_end/testcases/general/return_async_promoted.dart.weak.transformed.expect
@@ -0,0 +1,161 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "return_async_promoted_lib.dart" as ret;
+
+import "org-dartlang-testcase:///return_async_promoted_lib.dart";
+
+static method main() → void {
+  <T extends core::Object? = dynamic>(dynamic) → asy::Future<core::int> f = <T extends core::Object? = dynamic>(dynamic o) → asy::Future<core::int> /* futureValueType= core::int */ /* originally async */ {
+    final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+    core::bool* :is_sync = false;
+    core::int? :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
+    core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L1:
+        {
+          :return_value = o is{ForNonNullableByDefault} core::int ?{core::int} o{core::int} : throw "";
+          break #L1;
+        }
+        asy::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
+  };
+  () → asy::Future<core::int> g = () → asy::Future<core::int> /* futureValueType= core::int* */ /* originally async */ {
+    final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+    core::bool* :is_sync = false;
+    core::int? :return_value;
+    (dynamic) → dynamic :async_op_then;
+    (core::Object, core::StackTrace) → dynamic :async_op_error;
+    core::int :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L2:
+        {
+          :return_value = ret::legacy();
+          break #L2;
+        }
+        asy::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() → dynamic};
+    :is_sync = true;
+    return :async_future;
+  };
+}
+static method nullable() → core::int?
+  return null;
+static method nonNullable() → core::int?
+  return 0;
+
+library;
+import self as ret;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "return_async_promoted.dart" as self;
+
+import "org-dartlang-testcase:///return_async_promoted.dart";
+
+static method legacy() → core::int* {
+  <T extends core::Object* = dynamic>(dynamic) →* asy::Future<core::int*>* f = <T extends core::Object* = dynamic>(dynamic o) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
+    core::int? :return_value;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
+    core::int* :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L3:
+        {
+          :return_value = o is core::int* ?{core::int*} o{core::int*} : throw "";
+          break #L3;
+        }
+        asy::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() →* dynamic};
+    :is_sync = true;
+    return :async_future;
+  };
+  () →* asy::Future<core::int*>* g = () → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
+    core::int? :return_value;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
+    core::int* :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L4:
+        {
+          :return_value = self::nullable();
+          break #L4;
+        }
+        asy::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() →* dynamic};
+    :is_sync = true;
+    return :async_future;
+  };
+  () →* asy::Future<core::int*>* h = () → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
+    core::int? :return_value;
+    (dynamic) →* dynamic :async_op_then;
+    (core::Object*, core::StackTrace*) →* dynamic :async_op_error;
+    core::int* :await_jump_var = 0;
+    dynamic :await_ctx_var;
+    function :async_op(dynamic :result_or_exception, dynamic :stack_trace) → dynamic yielding 
+      try {
+        #L5:
+        {
+          :return_value = self::nonNullable();
+          break #L5;
+        }
+        asy::_completeWithNoFutureOnAsyncReturn(:async_future, :return_value, :is_sync);
+        return;
+      }
+      on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+      }
+    :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+    :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+    :async_op(null, null){() →* dynamic};
+    :is_sync = true;
+    return :async_future;
+  };
+  return null;
+}
diff --git a/pkg/front_end/testcases/general/return_async_promoted_lib.dart b/pkg/front_end/testcases/general/return_async_promoted_lib.dart
new file mode 100644
index 0000000..e04de19
--- /dev/null
+++ b/pkg/front_end/testcases/general/return_async_promoted_lib.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2022, 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 'return_async_promoted.dart';
+
+int legacy() {
+  var f = <T>(o) async => o is int ? o : throw '';
+  var g = () async => nullable();
+  var h = () async => nonNullable();
+  return null;
+}
diff --git a/pkg/front_end/testcases/general/stream_future.dart.weak.expect b/pkg/front_end/testcases/general/stream_future.dart.weak.expect
index b2cbd2b..b91c3c3 100644
--- a/pkg/front_end/testcases/general/stream_future.dart.weak.expect
+++ b/pkg/front_end/testcases/general/stream_future.dart.weak.expect
@@ -23,9 +23,9 @@
   return new self::Class::•();
 static method returnClass() → self::Class
   return new self::Class::•();
-static method returnFutureDynamic() → asy::Future<dynamic> async 
+static method returnFutureDynamic() → asy::Future<dynamic> async /* futureValueType= dynamic */ 
   return new self::Class::•();
-static method returnFutureClass() → asy::Future<self::Class> async 
+static method returnFutureClass() → asy::Future<self::Class> async /* futureValueType= self::Class */ 
   return new self::Class::•();
 static method error() → asy::Stream<FutureOr<self::Class>> async* {
   yield invalid-expression "pkg/front_end/testcases/general/stream_future.dart:18:9: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<Class>'.
@@ -39,7 +39,7 @@
   yield self::returnClass();
   yield self::returnFutureClass();
 }
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await for (FutureOr<self::Class>cls in self::stream()) {
     core::print(cls);
   }
diff --git a/pkg/front_end/testcases/general/stream_future.dart.weak.modular.expect b/pkg/front_end/testcases/general/stream_future.dart.weak.modular.expect
index b2cbd2b..b91c3c3 100644
--- a/pkg/front_end/testcases/general/stream_future.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/stream_future.dart.weak.modular.expect
@@ -23,9 +23,9 @@
   return new self::Class::•();
 static method returnClass() → self::Class
   return new self::Class::•();
-static method returnFutureDynamic() → asy::Future<dynamic> async 
+static method returnFutureDynamic() → asy::Future<dynamic> async /* futureValueType= dynamic */ 
   return new self::Class::•();
-static method returnFutureClass() → asy::Future<self::Class> async 
+static method returnFutureClass() → asy::Future<self::Class> async /* futureValueType= self::Class */ 
   return new self::Class::•();
 static method error() → asy::Stream<FutureOr<self::Class>> async* {
   yield invalid-expression "pkg/front_end/testcases/general/stream_future.dart:18:9: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'FutureOr<Class>'.
@@ -39,7 +39,7 @@
   yield self::returnClass();
   yield self::returnFutureClass();
 }
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await for (FutureOr<self::Class>cls in self::stream()) {
     core::print(cls);
   }
diff --git a/pkg/front_end/testcases/general/stream_future.dart.weak.transformed.expect b/pkg/front_end/testcases/general/stream_future.dart.weak.transformed.expect
index d609d5a..5f23e4e 100644
--- a/pkg/front_end/testcases/general/stream_future.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/stream_future.dart.weak.transformed.expect
@@ -24,7 +24,7 @@
   return new self::Class::•();
 static method returnClass() → self::Class
   return new self::Class::•();
-static method returnFutureDynamic() → asy::Future<dynamic> /* originally async */ {
+static method returnFutureDynamic() → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -51,7 +51,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnFutureClass() → asy::Future<self::Class> /* originally async */ {
+static method returnFutureClass() → asy::Future<self::Class> /* futureValueType= self::Class */ /* originally async */ {
   final asy::_Future<self::Class> :async_future = new asy::_Future::•<self::Class>();
   core::bool* :is_sync = false;
   self::Class? :return_value;
@@ -156,7 +156,7 @@
   :controller_stream = :controller.{asy::_AsyncStarStreamController::stream}{asy::Stream<FutureOr<self::Class>>};
   return :controller_stream;
 }
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_3.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_outline_change_3.yaml.world.1.expect
index 8967db1..e04acb1 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_3.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_3.yaml.world.1.expect
@@ -1,7 +1,7 @@
 main = main::main;
 library from "org-dartlang-test:///libA.dart" as libA {
 
-  static method whatever() → dynamic /* originally async */ {
+  static method whatever() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     dynamic :return_value;
@@ -53,7 +53,7 @@
     abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; -> dart.core::Object::noSuchMethod
     abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
   }
-  static method main() → dynamic /* originally async */ {
+  static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     dynamic :return_value;
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_3.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_outline_change_3.yaml.world.2.expect
index 0cfec60..56a2eb1 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_3.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_3.yaml.world.2.expect
@@ -1,7 +1,7 @@
 main = main::main;
 library from "org-dartlang-test:///libA.dart" as libA {
 
-  static method whatever() → dynamic /* originally async */ {
+  static method whatever() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     dynamic :return_value;
@@ -53,7 +53,7 @@
     abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; -> dart.core::Object::noSuchMethod
     abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
   }
-  static method main() → dynamic /* originally async */ {
+  static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     dynamic :return_value;
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_5.yaml.world.1.expect b/pkg/front_end/testcases/incremental/no_outline_change_5.yaml.world.1.expect
index da879b3..31712ce 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_5.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_5.yaml.world.1.expect
@@ -19,7 +19,7 @@
     abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; -> dart.core::Object::noSuchMethod
     abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
   }
-  static method main() → dynamic /* originally async */ {
+  static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     dynamic :return_value;
@@ -48,7 +48,7 @@
     :is_sync = true;
     return :async_future;
   }
-  static method /* from org-dartlang-test:///myPart.dart */ whatever() → dynamic /* originally async */ {
+  static method /* from org-dartlang-test:///myPart.dart */ whatever() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     dynamic :return_value;
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_5.yaml.world.2.expect b/pkg/front_end/testcases/incremental/no_outline_change_5.yaml.world.2.expect
index 44e9e46..37f43e7 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_5.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_5.yaml.world.2.expect
@@ -19,7 +19,7 @@
     abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; -> dart.core::Object::noSuchMethod
     abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
   }
-  static method main() → dynamic /* originally async */ {
+  static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     dynamic :return_value;
@@ -48,7 +48,7 @@
     :is_sync = true;
     return :async_future;
   }
-  static method /* from org-dartlang-test:///myPart.dart */ whatever() → dynamic /* originally async */ {
+  static method /* from org-dartlang-test:///myPart.dart */ whatever() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     dynamic :return_value;
diff --git a/pkg/front_end/testcases/incremental/no_outline_change_5.yaml.world.3.expect b/pkg/front_end/testcases/incremental/no_outline_change_5.yaml.world.3.expect
index ca8efcb..9d36a28 100644
--- a/pkg/front_end/testcases/incremental/no_outline_change_5.yaml.world.3.expect
+++ b/pkg/front_end/testcases/incremental/no_outline_change_5.yaml.world.3.expect
@@ -19,7 +19,7 @@
     abstract member-signature method noSuchMethod(dart.core::Invocation* invocation) → dynamic; -> dart.core::Object::noSuchMethod
     abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
   }
-  static method main() → dynamic /* originally async */ {
+  static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     dynamic :return_value;
@@ -49,7 +49,7 @@
     :is_sync = true;
     return :async_future;
   }
-  static method /* from org-dartlang-test:///myPart.dart */ whatever() → dynamic /* originally async */ {
+  static method /* from org-dartlang-test:///myPart.dart */ whatever() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     dynamic :return_value;
diff --git a/pkg/front_end/testcases/inference/async_await.dart.weak.expect b/pkg/front_end/testcases/inference/async_await.dart.weak.expect
index 3d172fc..73e7931 100644
--- a/pkg/front_end/testcases/inference/async_await.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/async_await.dart.weak.expect
@@ -25,7 +25,7 @@
   abstract member-signature method asStream() → asy::Stream<core::int*>*; -> asy::Future::asStream
   abstract member-signature method timeout(core::Duration* timeLimit, {covariant-by-class () →* FutureOr<core::int*>* onTimeout = #C1}) → asy::Future<core::int*>*; -> asy::Future::timeout
 }
-static method test() → void async {
+static method test() → void async /* futureValueType= void */ {
   core::int* x0;
   asy::Future<core::int*>* x1;
   asy::Future<asy::Future<core::int*>*>* x2;
@@ -36,25 +36,25 @@
   FutureOr<FutureOr<core::int*>*>* x7;
   FutureOr<self::MyFuture*>* x8;
   self::MyFuture* x9;
-  function test0() → asy::Future<core::int*>* async 
+  function test0() → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
     return x0;
-  function test1() → asy::Future<core::int*>* async 
+  function test1() → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
     return x1;
-  function test2() → asy::Future<asy::Future<core::int*>*>* async 
+  function test2() → asy::Future<asy::Future<core::int*>*>* async /* futureValueType= asy::Future<core::int*>* */ 
     return x2;
-  function test3() → asy::Future<FutureOr<core::int*>*>* async 
+  function test3() → asy::Future<FutureOr<core::int*>*>* async /* futureValueType= FutureOr<core::int*>* */ 
     return x3;
-  function test4() → asy::Future<self::MyFuture*>* async 
+  function test4() → asy::Future<self::MyFuture*>* async /* futureValueType= self::MyFuture* */ 
     return x4;
-  function test5() → asy::Future<core::int*>* async 
+  function test5() → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
     return x5;
-  function test6() → asy::Future<asy::Future<core::int*>*>* async 
+  function test6() → asy::Future<asy::Future<core::int*>*>* async /* futureValueType= asy::Future<core::int*>* */ 
     return x6;
-  function test7() → asy::Future<FutureOr<core::int*>*>* async 
+  function test7() → asy::Future<FutureOr<core::int*>*>* async /* futureValueType= FutureOr<core::int*>* */ 
     return x7;
-  function test8() → asy::Future<self::MyFuture*>* async 
+  function test8() → asy::Future<self::MyFuture*>* async /* futureValueType= self::MyFuture* */ 
     return x8;
-  function test9() → asy::Future<core::int*>* async 
+  function test9() → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
     return x9;
   core::int* y0 = await x0;
   core::int* y1 = await x1;
diff --git a/pkg/front_end/testcases/inference/async_await.dart.weak.modular.expect b/pkg/front_end/testcases/inference/async_await.dart.weak.modular.expect
index 3d172fc..73e7931 100644
--- a/pkg/front_end/testcases/inference/async_await.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/async_await.dart.weak.modular.expect
@@ -25,7 +25,7 @@
   abstract member-signature method asStream() → asy::Stream<core::int*>*; -> asy::Future::asStream
   abstract member-signature method timeout(core::Duration* timeLimit, {covariant-by-class () →* FutureOr<core::int*>* onTimeout = #C1}) → asy::Future<core::int*>*; -> asy::Future::timeout
 }
-static method test() → void async {
+static method test() → void async /* futureValueType= void */ {
   core::int* x0;
   asy::Future<core::int*>* x1;
   asy::Future<asy::Future<core::int*>*>* x2;
@@ -36,25 +36,25 @@
   FutureOr<FutureOr<core::int*>*>* x7;
   FutureOr<self::MyFuture*>* x8;
   self::MyFuture* x9;
-  function test0() → asy::Future<core::int*>* async 
+  function test0() → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
     return x0;
-  function test1() → asy::Future<core::int*>* async 
+  function test1() → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
     return x1;
-  function test2() → asy::Future<asy::Future<core::int*>*>* async 
+  function test2() → asy::Future<asy::Future<core::int*>*>* async /* futureValueType= asy::Future<core::int*>* */ 
     return x2;
-  function test3() → asy::Future<FutureOr<core::int*>*>* async 
+  function test3() → asy::Future<FutureOr<core::int*>*>* async /* futureValueType= FutureOr<core::int*>* */ 
     return x3;
-  function test4() → asy::Future<self::MyFuture*>* async 
+  function test4() → asy::Future<self::MyFuture*>* async /* futureValueType= self::MyFuture* */ 
     return x4;
-  function test5() → asy::Future<core::int*>* async 
+  function test5() → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
     return x5;
-  function test6() → asy::Future<asy::Future<core::int*>*>* async 
+  function test6() → asy::Future<asy::Future<core::int*>*>* async /* futureValueType= asy::Future<core::int*>* */ 
     return x6;
-  function test7() → asy::Future<FutureOr<core::int*>*>* async 
+  function test7() → asy::Future<FutureOr<core::int*>*>* async /* futureValueType= FutureOr<core::int*>* */ 
     return x7;
-  function test8() → asy::Future<self::MyFuture*>* async 
+  function test8() → asy::Future<self::MyFuture*>* async /* futureValueType= self::MyFuture* */ 
     return x8;
-  function test9() → asy::Future<core::int*>* async 
+  function test9() → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
     return x9;
   core::int* y0 = await x0;
   core::int* y1 = await x1;
diff --git a/pkg/front_end/testcases/inference/async_await.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/async_await.dart.weak.transformed.expect
index 1e14f9c..e66b45d 100644
--- a/pkg/front_end/testcases/inference/async_await.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_await.dart.weak.transformed.expect
@@ -26,7 +26,7 @@
   abstract member-signature method asStream() → asy::Stream<core::int*>*; -> asy::Future::asStream
   abstract member-signature method timeout(core::Duration* timeLimit, {covariant-by-class () →* FutureOr<core::int*>* onTimeout = #C1}) → asy::Future<core::int*>*; -> asy::Future::timeout
 }
-static method test() → void /* originally async */ {
+static method test() → void /* futureValueType= void */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -49,7 +49,7 @@
         FutureOr<FutureOr<core::int*>*>* x7;
         FutureOr<self::MyFuture*>* x8;
         self::MyFuture* x9;
-        function test0() → asy::Future<core::int*>* /* originally async */ {
+        function test0() → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
           final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
           core::bool* :is_sync = false;
           core::int? :return_value;
@@ -76,7 +76,7 @@
           :is_sync = true;
           return :async_future;
         }
-        function test1() → asy::Future<core::int*>* /* originally async */ {
+        function test1() → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
           final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
           core::bool* :is_sync = false;
           FutureOr<core::int*>* :return_value;
@@ -103,7 +103,7 @@
           :is_sync = true;
           return :async_future;
         }
-        function test2() → asy::Future<asy::Future<core::int*>*>* /* originally async */ {
+        function test2() → asy::Future<asy::Future<core::int*>*>* /* futureValueType= asy::Future<core::int*>* */ /* originally async */ {
           final asy::_Future<asy::Future<core::int*>*>* :async_future = new asy::_Future::•<asy::Future<core::int*>*>();
           core::bool* :is_sync = false;
           FutureOr<asy::Future<core::int*>*>* :return_value;
@@ -130,7 +130,7 @@
           :is_sync = true;
           return :async_future;
         }
-        function test3() → asy::Future<FutureOr<core::int*>*>* /* originally async */ {
+        function test3() → asy::Future<FutureOr<core::int*>*>* /* futureValueType= FutureOr<core::int*>* */ /* originally async */ {
           final asy::_Future<FutureOr<core::int*>*>* :async_future = new asy::_Future::•<FutureOr<core::int*>*>();
           core::bool* :is_sync = false;
           FutureOr<FutureOr<core::int*>*>* :return_value;
@@ -157,7 +157,7 @@
           :is_sync = true;
           return :async_future;
         }
-        function test4() → asy::Future<self::MyFuture*>* /* originally async */ {
+        function test4() → asy::Future<self::MyFuture*>* /* futureValueType= self::MyFuture* */ /* originally async */ {
           final asy::_Future<self::MyFuture*>* :async_future = new asy::_Future::•<self::MyFuture*>();
           core::bool* :is_sync = false;
           FutureOr<self::MyFuture*>* :return_value;
@@ -184,7 +184,7 @@
           :is_sync = true;
           return :async_future;
         }
-        function test5() → asy::Future<core::int*>* /* originally async */ {
+        function test5() → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
           final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
           core::bool* :is_sync = false;
           FutureOr<core::int*>* :return_value;
@@ -211,7 +211,7 @@
           :is_sync = true;
           return :async_future;
         }
-        function test6() → asy::Future<asy::Future<core::int*>*>* /* originally async */ {
+        function test6() → asy::Future<asy::Future<core::int*>*>* /* futureValueType= asy::Future<core::int*>* */ /* originally async */ {
           final asy::_Future<asy::Future<core::int*>*>* :async_future = new asy::_Future::•<asy::Future<core::int*>*>();
           core::bool* :is_sync = false;
           FutureOr<asy::Future<core::int*>*>* :return_value;
@@ -238,7 +238,7 @@
           :is_sync = true;
           return :async_future;
         }
-        function test7() → asy::Future<FutureOr<core::int*>*>* /* originally async */ {
+        function test7() → asy::Future<FutureOr<core::int*>*>* /* futureValueType= FutureOr<core::int*>* */ /* originally async */ {
           final asy::_Future<FutureOr<core::int*>*>* :async_future = new asy::_Future::•<FutureOr<core::int*>*>();
           core::bool* :is_sync = false;
           FutureOr<FutureOr<core::int*>*>* :return_value;
@@ -265,7 +265,7 @@
           :is_sync = true;
           return :async_future;
         }
-        function test8() → asy::Future<self::MyFuture*>* /* originally async */ {
+        function test8() → asy::Future<self::MyFuture*>* /* futureValueType= self::MyFuture* */ /* originally async */ {
           final asy::_Future<self::MyFuture*>* :async_future = new asy::_Future::•<self::MyFuture*>();
           core::bool* :is_sync = false;
           FutureOr<self::MyFuture*>* :return_value;
@@ -292,7 +292,7 @@
           :is_sync = true;
           return :async_future;
         }
-        function test9() → asy::Future<core::int*>* /* originally async */ {
+        function test9() → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
           final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
           core::bool* :is_sync = false;
           FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.weak.expect b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.weak.expect
index 7974c45..366738b 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.weak.expect
@@ -7,7 +7,7 @@
 
 static field asy::Future<core::int*>* futureInt = null;
 static field () →* asy::Future<core::int*>* f = () → asy::Future<core::int*>* => self::futureInt;
-static field () →* asy::Future<core::int*>* g = () → asy::Future<core::int*>* async => self::futureInt;
+static field () →* asy::Future<core::int*>* g = () → asy::Future<core::int*>* async /* futureValueType= core::int* */ => self::futureInt;
 static method main() → dynamic {
   self::f;
   self::g;
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.weak.modular.expect b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.weak.modular.expect
index 7974c45..366738b 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.weak.modular.expect
@@ -7,7 +7,7 @@
 
 static field asy::Future<core::int*>* futureInt = null;
 static field () →* asy::Future<core::int*>* f = () → asy::Future<core::int*>* => self::futureInt;
-static field () →* asy::Future<core::int*>* g = () → asy::Future<core::int*>* async => self::futureInt;
+static field () →* asy::Future<core::int*>* g = () → asy::Future<core::int*>* async /* futureValueType= core::int* */ => self::futureInt;
 static method main() → dynamic {
   self::f;
   self::g;
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.weak.transformed.expect
index 15fb18d..2324c89 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.weak.transformed.expect
@@ -7,7 +7,7 @@
 
 static field asy::Future<core::int*>* futureInt = null;
 static field () →* asy::Future<core::int*>* f = () → asy::Future<core::int*>* => self::futureInt;
-static field () →* asy::Future<core::int*>* g = () → asy::Future<core::int*>* /* originally async */ {
+static field () →* asy::Future<core::int*>* g = () → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.weak.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.weak.expect
index 6e90053..dcce00c 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.weak.expect
@@ -3,7 +3,7 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
-static field () →* asy::Future<core::int*>* f = () → asy::Future<core::int*>* async => 0;
+static field () →* asy::Future<core::int*>* f = () → asy::Future<core::int*>* async /* futureValueType= core::int* */ => 0;
 static method main() → dynamic {
   self::f;
 }
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.weak.modular.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.weak.modular.expect
index 6e90053..dcce00c 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.weak.modular.expect
@@ -3,7 +3,7 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
-static field () →* asy::Future<core::int*>* f = () → asy::Future<core::int*>* async => 0;
+static field () →* asy::Future<core::int*>* f = () → asy::Future<core::int*>* async /* futureValueType= core::int* */ => 0;
 static method main() → dynamic {
   self::f;
 }
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.weak.transformed.expect
index 7e432e9..d92144a 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.weak.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
-static field () →* asy::Future<core::int*>* f = () → asy::Future<core::int*>* /* originally async */ {
+static field () →* asy::Future<core::int*>* f = () → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   core::int? :return_value;
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.weak.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.weak.expect
index a44a6a9..5454d59 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.weak.expect
@@ -7,7 +7,7 @@
 
 static field FutureOr<core::int*>* futureOrInt = null;
 static field () →* FutureOr<core::int*>* f = () → FutureOr<core::int*>* => self::futureOrInt;
-static field () →* asy::Future<core::int*>* g = () → asy::Future<core::int*>* async => self::futureOrInt;
+static field () →* asy::Future<core::int*>* g = () → asy::Future<core::int*>* async /* futureValueType= core::int* */ => self::futureOrInt;
 static method main() → dynamic {
   self::f;
   self::g;
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.weak.modular.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.weak.modular.expect
index a44a6a9..5454d59 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.weak.modular.expect
@@ -7,7 +7,7 @@
 
 static field FutureOr<core::int*>* futureOrInt = null;
 static field () →* FutureOr<core::int*>* f = () → FutureOr<core::int*>* => self::futureOrInt;
-static field () →* asy::Future<core::int*>* g = () → asy::Future<core::int*>* async => self::futureOrInt;
+static field () →* asy::Future<core::int*>* g = () → asy::Future<core::int*>* async /* futureValueType= core::int* */ => self::futureOrInt;
 static method main() → dynamic {
   self::f;
   self::g;
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.weak.transformed.expect
index de99cb2..23c7b00 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.weak.transformed.expect
@@ -7,7 +7,7 @@
 
 static field FutureOr<core::int*>* futureOrInt = null;
 static field () →* FutureOr<core::int*>* f = () → FutureOr<core::int*>* => self::futureOrInt;
-static field () →* asy::Future<core::int*>* g = () → asy::Future<core::int*>* /* originally async */ {
+static field () →* asy::Future<core::int*>* g = () → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.weak.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.weak.expect
index f19d465..c2fcd34 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.weak.expect
@@ -8,7 +8,7 @@
 import "dart:math" show Random;
 
 static method test() → dynamic {
-  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* async {
+  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* async /* futureValueType= core::num* */ {
     if(math::Random::•().{math::Random::nextBool}(){() →* core::bool*}) {
       return asy::Future::value<core::int*>(1);
     }
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.weak.modular.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.weak.modular.expect
index f19d465..c2fcd34 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.weak.modular.expect
@@ -8,7 +8,7 @@
 import "dart:math" show Random;
 
 static method test() → dynamic {
-  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* async {
+  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* async /* futureValueType= core::num* */ {
     if(math::Random::•().{math::Random::nextBool}(){() →* core::bool*}) {
       return asy::Future::value<core::int*>(1);
     }
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.weak.transformed.expect
index c321e3e..68357cb 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.weak.transformed.expect
@@ -8,7 +8,7 @@
 import "dart:math" show Random;
 
 static method test() → dynamic {
-  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* /* originally async */ {
+  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* /* futureValueType= core::num* */ /* originally async */ {
     final asy::_Future<core::num*>* :async_future = new asy::_Future::•<core::num*>();
     core::bool* :is_sync = false;
     FutureOr<core::num*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.weak.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.weak.expect
index 419ef81..a28c927 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.weak.expect
@@ -8,7 +8,7 @@
 import "dart:math" show Random;
 
 static method test() → dynamic {
-  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* async {
+  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* async /* futureValueType= core::num* */ {
     if(math::Random::•().{math::Random::nextBool}(){() →* core::bool*}) {
       return 1;
     }
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.weak.modular.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.weak.modular.expect
index 419ef81..a28c927 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.weak.modular.expect
@@ -8,7 +8,7 @@
 import "dart:math" show Random;
 
 static method test() → dynamic {
-  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* async {
+  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* async /* futureValueType= core::num* */ {
     if(math::Random::•().{math::Random::nextBool}(){() →* core::bool*}) {
       return 1;
     }
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.weak.transformed.expect
index 81cc3b1..6dd1245 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.weak.transformed.expect
@@ -8,7 +8,7 @@
 import "dart:math" show Random;
 
 static method test() → dynamic {
-  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* /* originally async */ {
+  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* /* futureValueType= core::num* */ /* originally async */ {
     final asy::_Future<core::num*>* :async_future = new asy::_Future::•<core::num*>();
     core::bool* :is_sync = false;
     core::num? :return_value;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.weak.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.weak.expect
index 3af04ad..f4a674b 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.weak.expect
@@ -8,7 +8,7 @@
 import "dart:math" show Random;
 
 static method test() → dynamic {
-  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* async {
+  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* async /* futureValueType= core::num* */ {
     if(math::Random::•().{math::Random::nextBool}(){() →* core::bool*}) {
       return asy::Future::value<core::int*>(1);
     }
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.weak.modular.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.weak.modular.expect
index 3af04ad..f4a674b 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.weak.modular.expect
@@ -8,7 +8,7 @@
 import "dart:math" show Random;
 
 static method test() → dynamic {
-  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* async {
+  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* async /* futureValueType= core::num* */ {
     if(math::Random::•().{math::Random::nextBool}(){() →* core::bool*}) {
       return asy::Future::value<core::int*>(1);
     }
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.weak.transformed.expect
index e5f6a32..ff44989 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.weak.transformed.expect
@@ -8,7 +8,7 @@
 import "dart:math" show Random;
 
 static method test() → dynamic {
-  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* /* originally async */ {
+  () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* /* futureValueType= core::num* */ /* originally async */ {
     final asy::_Future<core::num*>* :async_future = new asy::_Future::•<core::num*>();
     core::bool* :is_sync = false;
     FutureOr<core::num*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.weak.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.weak.expect
index 729dbe7..2d31d8e 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.weak.expect
@@ -5,8 +5,8 @@
 
 import "dart:async";
 
-static method main() → dynamic async {
-  () →* asy::Future<Null>* f = () → asy::Future<Null>* async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
+  () →* asy::Future<Null>* f = () → asy::Future<Null>* async /* futureValueType= Null */ {
     return null;
   };
   asy::Future<dynamic>* y = f(){() →* asy::Future<Null>*};
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.weak.modular.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.weak.modular.expect
index 729dbe7..2d31d8e 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.weak.modular.expect
@@ -5,8 +5,8 @@
 
 import "dart:async";
 
-static method main() → dynamic async {
-  () →* asy::Future<Null>* f = () → asy::Future<Null>* async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
+  () →* asy::Future<Null>* f = () → asy::Future<Null>* async /* futureValueType= Null */ {
     return null;
   };
   asy::Future<dynamic>* y = f(){() →* asy::Future<Null>*};
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.weak.transformed.expect
index 2f60494..82fc16a 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.weak.transformed.expect
@@ -6,7 +6,7 @@
 
 import "dart:async";
 
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -19,7 +19,7 @@
     try {
       #L1:
       {
-        () →* asy::Future<Null>* f = () → asy::Future<Null>* /* originally async */ {
+        () →* asy::Future<Null>* f = () → asy::Future<Null>* /* futureValueType= Null */ /* originally async */ {
           final asy::_Future<Null>* :async_future = new asy::_Future::•<Null>();
           core::bool* :is_sync = false;
           FutureOr<Null>* :return_value;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.weak.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.weak.expect
index a85a79c..9a6dc27 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.weak.expect
@@ -5,7 +5,7 @@
 
 import "dart:async";
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   () →* asy::Stream<Null>* f = () → asy::Stream<Null>* async* {
     yield null;
   };
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.weak.modular.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.weak.modular.expect
index a85a79c..9a6dc27 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.weak.modular.expect
@@ -5,7 +5,7 @@
 
 import "dart:async";
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   () →* asy::Stream<Null>* f = () → asy::Stream<Null>* async* {
     yield null;
   };
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.weak.transformed.expect
index 6f20ea7..d81d2c2 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.weak.transformed.expect
@@ -6,7 +6,7 @@
 
 import "dart:async";
 
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.weak.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.weak.expect
index 1a5ac1a..031ded2 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.weak.expect
@@ -5,7 +5,7 @@
 
 import "dart:async";
 
-static method main() → asy::Future<dynamic>* async {
+static method main() → asy::Future<dynamic>* async /* futureValueType= dynamic */ {
   dynamic d;
   core::List<core::int*>* l0 = await<core::int*>[d as{TypeError,ForDynamic} core::int*];
   core::List<core::int*>* l1 = await asy::Future::value<core::List<core::int*>*>(<core::int*>[d as{TypeError,ForDynamic} core::int*]);
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.weak.modular.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.weak.modular.expect
index 1a5ac1a..031ded2 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.weak.modular.expect
@@ -5,7 +5,7 @@
 
 import "dart:async";
 
-static method main() → asy::Future<dynamic>* async {
+static method main() → asy::Future<dynamic>* async /* futureValueType= dynamic */ {
   dynamic d;
   core::List<core::int*>* l0 = await<core::int*>[d as{TypeError,ForDynamic} core::int*];
   core::List<core::int*>* l1 = await asy::Future::value<core::List<core::int*>*>(<core::int*>[d as{TypeError,ForDynamic} core::int*]);
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.weak.transformed.expect
index 9b64f1c..7a300f3 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.weak.transformed.expect
@@ -6,7 +6,7 @@
 
 import "dart:async";
 
-static method main() → asy::Future<dynamic>* /* originally async */ {
+static method main() → asy::Future<dynamic>* /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.weak.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.weak.expect
index e2d0f6d..6d06f17 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.weak.expect
@@ -58,7 +58,7 @@
 }
 static method F<T extends core::Object* = dynamic>() → self::F::T*
   return null;
-static method f() → asy::Future<dynamic>* async {
+static method f() → asy::Future<dynamic>* async /* futureValueType= dynamic */ {
   dynamic d;
   core::Object* o;
   for (dynamic x in self::F<core::Iterable<dynamic>*>()) {
@@ -86,7 +86,7 @@
     o = #t4;
   }
 }
-static method main() → asy::Future<dynamic>* async {
+static method main() → asy::Future<dynamic>* async /* futureValueType= dynamic */ {
   for (core::int* x in <core::int*>[1, 2, 3]) {
   }
   for (core::num* x in <core::num*>[1, 2, 3]) {
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.weak.modular.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.weak.modular.expect
index e2d0f6d..6d06f17 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.weak.modular.expect
@@ -58,7 +58,7 @@
 }
 static method F<T extends core::Object* = dynamic>() → self::F::T*
   return null;
-static method f() → asy::Future<dynamic>* async {
+static method f() → asy::Future<dynamic>* async /* futureValueType= dynamic */ {
   dynamic d;
   core::Object* o;
   for (dynamic x in self::F<core::Iterable<dynamic>*>()) {
@@ -86,7 +86,7 @@
     o = #t4;
   }
 }
-static method main() → asy::Future<dynamic>* async {
+static method main() → asy::Future<dynamic>* async /* futureValueType= dynamic */ {
   for (core::int* x in <core::int*>[1, 2, 3]) {
   }
   for (core::num* x in <core::num*>[1, 2, 3]) {
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.weak.transformed.expect
index 70f5a69..a0160b8 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.weak.transformed.expect
@@ -59,7 +59,7 @@
 }
 static method F<T extends core::Object* = dynamic>() → self::F::T*
   return null;
-static method f() → asy::Future<dynamic>* /* originally async */ {
+static method f() → asy::Future<dynamic>* /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -238,7 +238,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method main() → asy::Future<dynamic>* /* originally async */ {
+static method main() → asy::Future<dynamic>* /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.weak.expect b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.weak.expect
index 93ecd39..34ecf11 100644
--- a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.weak.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   core::Object* o;
   for (dynamic x in o as{TypeError} core::Iterable<dynamic>*) {
   }
diff --git a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.weak.modular.expect b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.weak.modular.expect
index 93ecd39..34ecf11 100644
--- a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.weak.modular.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   core::Object* o;
   for (dynamic x in o as{TypeError} core::Iterable<dynamic>*) {
   }
diff --git a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.weak.transformed.expect
index d8e4b15..258db25 100644
--- a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.weak.transformed.expect
@@ -4,7 +4,7 @@
 import "dart:core" as core;
 import "dart:_internal" as _in;
 
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/inference/future_then.dart.weak.expect b/pkg/front_end/testcases/inference/future_then.dart.weak.expect
index 3472083..806622d 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.weak.expect
@@ -34,20 +34,20 @@
 }
 static method test() → void {
   self::MyFuture<dynamic>* f;
-  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => await asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => await asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return await asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return 3;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   asy::Future<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* {
     return asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
 }
diff --git a/pkg/front_end/testcases/inference/future_then.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then.dart.weak.modular.expect
index 3472083..806622d 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.weak.modular.expect
@@ -34,20 +34,20 @@
 }
 static method test() → void {
   self::MyFuture<dynamic>* f;
-  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => await asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => await asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return await asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return 3;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   asy::Future<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* {
     return asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
 }
diff --git a/pkg/front_end/testcases/inference/future_then.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.weak.transformed.expect
index 1b0b3a6..5c43118 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
 }
 static method test() → void {
   self::MyFuture<dynamic>* f;
-  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -64,7 +64,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -93,7 +93,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -120,7 +120,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -151,7 +151,7 @@
   asy::Future<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* {
     return asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
@@ -178,7 +178,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_2.dart.weak.expect
index caba7e5..3239514 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.weak.expect
@@ -34,20 +34,20 @@
 }
 static method test() → void {
   self::MyFuture<dynamic>* f;
-  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => await new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => await new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return await new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return 3;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   asy::Future<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* {
     return new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
 }
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_2.dart.weak.modular.expect
index caba7e5..3239514 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.weak.modular.expect
@@ -34,20 +34,20 @@
 }
 static method test() → void {
   self::MyFuture<dynamic>* f;
-  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => await new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => await new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return await new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return 3;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   asy::Future<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* {
     return new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
 }
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.weak.transformed.expect
index 2945796..a14d3e6 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
 }
 static method test() → void {
   self::MyFuture<dynamic>* f;
-  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -64,7 +64,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -93,7 +93,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -120,7 +120,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -151,7 +151,7 @@
   asy::Future<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* {
     return new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
@@ -178,7 +178,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_3.dart.weak.expect
index 1efc406..9bbf98e 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.weak.expect
@@ -34,20 +34,20 @@
 }
 static method test() → void {
   self::MyFuture<dynamic>* f;
-  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => await asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => await asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return await asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return 3;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   self::MyFuture<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   self::MyFuture<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* {
     return asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  self::MyFuture<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
 }
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_3.dart.weak.modular.expect
index 1efc406..9bbf98e 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.weak.modular.expect
@@ -34,20 +34,20 @@
 }
 static method test() → void {
   self::MyFuture<dynamic>* f;
-  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => await asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => await asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return await asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return 3;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   self::MyFuture<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   self::MyFuture<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* {
     return asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  self::MyFuture<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
 }
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.weak.transformed.expect
index d075aa1..e39900a 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
 }
 static method test() → void {
   self::MyFuture<dynamic>* f;
-  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -64,7 +64,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -93,7 +93,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -120,7 +120,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -151,7 +151,7 @@
   self::MyFuture<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* {
     return asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
@@ -178,7 +178,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_4.dart.weak.expect
index eaff2a5..f4d9ecd 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.weak.expect
@@ -34,20 +34,20 @@
 }
 static method test() → void {
   self::MyFuture<dynamic>* f;
-  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => await new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => await new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return await new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return 3;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   self::MyFuture<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   self::MyFuture<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* {
     return new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  self::MyFuture<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
 }
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_4.dart.weak.modular.expect
index eaff2a5..f4d9ecd 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.weak.modular.expect
@@ -34,20 +34,20 @@
 }
 static method test() → void {
   self::MyFuture<dynamic>* f;
-  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => await new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => await new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return await new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return 3;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   self::MyFuture<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   self::MyFuture<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* {
     return new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  self::MyFuture<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
 }
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.weak.transformed.expect
index ecea355..3d41dfa 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
 }
 static method test() → void {
   self::MyFuture<dynamic>* f;
-  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -64,7 +64,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -93,7 +93,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -120,7 +120,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -151,7 +151,7 @@
   self::MyFuture<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* {
     return new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
@@ -178,7 +178,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_5.dart.weak.expect
index 955cbb3..0a41e1a 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.weak.expect
@@ -34,20 +34,20 @@
 }
 static method test() → void {
   asy::Future<dynamic>* f;
-  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => await new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => await new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return await new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return 3;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
   asy::Future<core::int*>* t5 = f.{asy::Future::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
   asy::Future<core::int*>* t6 = f.{asy::Future::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* {
     return new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t7 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t7 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
 }
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_5.dart.weak.modular.expect
index 955cbb3..0a41e1a 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.weak.modular.expect
@@ -34,20 +34,20 @@
 }
 static method test() → void {
   asy::Future<dynamic>* f;
-  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => await new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => await new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return await new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return 3;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
   asy::Future<core::int*>* t5 = f.{asy::Future::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
   asy::Future<core::int*>* t6 = f.{asy::Future::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* {
     return new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t7 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t7 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => new self::MyFuture::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
 }
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.weak.transformed.expect
index 4c59d38..cce1d0b 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
 }
 static method test() → void {
   asy::Future<dynamic>* f;
-  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -64,7 +64,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -93,7 +93,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -120,7 +120,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -151,7 +151,7 @@
   asy::Future<core::int*>* t6 = f.{asy::Future::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* {
     return new self::MyFuture::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t7 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t7 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
@@ -178,7 +178,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_6.dart.weak.expect
index 438bfac..c12d5d2 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.weak.expect
@@ -34,20 +34,20 @@
 }
 static method test() → void {
   asy::Future<dynamic>* f;
-  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => await asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => await asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return await asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return 3;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
   asy::Future<core::int*>* t5 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
   asy::Future<core::int*>* t6 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* {
     return asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t7 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t7 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
 }
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_6.dart.weak.modular.expect
index 438bfac..c12d5d2 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.weak.modular.expect
@@ -34,20 +34,20 @@
 }
 static method test() → void {
   asy::Future<dynamic>* f;
-  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => await asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => await asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return await asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => 3){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return 3;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
   asy::Future<core::int*>* t5 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
   asy::Future<core::int*>* t6 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* {
     return asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t7 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async {
+  asy::Future<core::int*>* t7 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => asy::Future::value<core::int*>(3)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
 }
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.weak.transformed.expect
index fdde079..36a0f77 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
 }
 static method test() → void {
   asy::Future<dynamic>* f;
-  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -64,7 +64,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -93,7 +93,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -120,7 +120,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -151,7 +151,7 @@
   asy::Future<core::int*>* t6 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* {
     return asy::Future::value<core::int*>(3);
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t7 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t7 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
@@ -178,7 +178,7 @@
     :is_sync = true;
     return :async_future;
   }){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.weak.expect
index 816b3ee..e736a28 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.weak.expect
@@ -34,8 +34,8 @@
 }
 static method test() → void {
   self::MyFuture<core::bool*>* f;
-  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async => x ?{core::int*} 2 : await asy::Future::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => x ?{core::int*} 2 : await asy::Future::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async /* futureValueType= core::int* */ {
     return (await x ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* => (x ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.weak.modular.expect
index 816b3ee..e736a28 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.weak.modular.expect
@@ -34,8 +34,8 @@
 }
 static method test() → void {
   self::MyFuture<core::bool*>* f;
-  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async => x ?{core::int*} 2 : await asy::Future::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => x ?{core::int*} 2 : await asy::Future::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async /* futureValueType= core::int* */ {
     return (await x ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* => (x ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.weak.transformed.expect
index ca269fc..0fbde92 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
 }
 static method test() → void {
   self::MyFuture<core::bool*>* f;
-  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -71,7 +71,7 @@
     :is_sync = true;
     return :async_future;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.weak.expect
index 11b74949..389affa 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.weak.expect
@@ -34,8 +34,8 @@
 }
 static method test() → void {
   self::MyFuture<core::bool*>* f;
-  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async => x ?{core::int*} 2 : await new self::MyFuture::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => x ?{core::int*} 2 : await new self::MyFuture::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async /* futureValueType= core::int* */ {
     return (await x ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* => (x ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.weak.modular.expect
index 11b74949..389affa 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.weak.modular.expect
@@ -34,8 +34,8 @@
 }
 static method test() → void {
   self::MyFuture<core::bool*>* f;
-  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async => x ?{core::int*} 2 : await new self::MyFuture::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => x ?{core::int*} 2 : await new self::MyFuture::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async /* futureValueType= core::int* */ {
     return (await x ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* => (x ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.weak.transformed.expect
index d41c46d..b88ca68 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
 }
 static method test() → void {
   self::MyFuture<core::bool*>* f;
-  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -71,7 +71,7 @@
     :is_sync = true;
     return :async_future;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.weak.expect
index 11b63b1..73dfd35 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.weak.expect
@@ -34,8 +34,8 @@
 }
 static method test() → void {
   self::MyFuture<core::bool*>* f;
-  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async => x ?{core::int*} 2 : await asy::Future::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async {
+  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => x ?{core::int*} 2 : await asy::Future::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async /* futureValueType= core::int* */ {
     return (await x ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   self::MyFuture<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* => (x ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.weak.modular.expect
index 11b63b1..73dfd35 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.weak.modular.expect
@@ -34,8 +34,8 @@
 }
 static method test() → void {
   self::MyFuture<core::bool*>* f;
-  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async => x ?{core::int*} 2 : await asy::Future::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async {
+  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => x ?{core::int*} 2 : await asy::Future::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async /* futureValueType= core::int* */ {
     return (await x ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   self::MyFuture<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* => (x ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.weak.transformed.expect
index 353cbcc..6a05bbf 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
 }
 static method test() → void {
   self::MyFuture<core::bool*>* f;
-  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -71,7 +71,7 @@
     :is_sync = true;
     return :async_future;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.weak.expect
index cc3ada3..d79b102 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.weak.expect
@@ -34,8 +34,8 @@
 }
 static method test() → void {
   self::MyFuture<core::bool*>* f;
-  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async => x ?{core::int*} 2 : await new self::MyFuture::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async {
+  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => x ?{core::int*} 2 : await new self::MyFuture::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async /* futureValueType= core::int* */ {
     return (await x ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   self::MyFuture<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* => (x ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.weak.modular.expect
index cc3ada3..d79b102 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.weak.modular.expect
@@ -34,8 +34,8 @@
 }
 static method test() → void {
   self::MyFuture<core::bool*>* f;
-  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async => x ?{core::int*} 2 : await new self::MyFuture::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async {
+  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => x ?{core::int*} 2 : await new self::MyFuture::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async /* futureValueType= core::int* */ {
     return (await x ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   self::MyFuture<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* => (x ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.weak.transformed.expect
index fa9b07f..34c2ea5 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
 }
 static method test() → void {
   self::MyFuture<core::bool*>* f;
-  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -71,7 +71,7 @@
     :is_sync = true;
     return :async_future;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* originally async */ {
+  self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.weak.expect
index 83acf25..6989a48 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.weak.expect
@@ -34,8 +34,8 @@
 }
 static method test() → void {
   asy::Future<core::bool*>* f;
-  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async => x ?{core::int*} 2 : await new self::MyFuture::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => x ?{core::int*} 2 : await new self::MyFuture::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async /* futureValueType= core::int* */ {
     return (await x ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
   asy::Future<core::int*>* t5 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* => (x ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.weak.modular.expect
index 83acf25..6989a48 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.weak.modular.expect
@@ -34,8 +34,8 @@
 }
 static method test() → void {
   asy::Future<core::bool*>* f;
-  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async => x ?{core::int*} 2 : await new self::MyFuture::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => x ?{core::int*} 2 : await new self::MyFuture::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async /* futureValueType= core::int* */ {
     return (await x ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
   asy::Future<core::int*>* t5 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* => (x ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.weak.transformed.expect
index 862a146..c47ee35 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
 }
 static method test() → void {
   asy::Future<core::bool*>* f;
-  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -71,7 +71,7 @@
     :is_sync = true;
     return :async_future;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.weak.expect
index 0c2809d..4d22096 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.weak.expect
@@ -34,8 +34,8 @@
 }
 static method test() → void {
   asy::Future<core::bool*>* f;
-  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async => x ?{core::int*} 2 : await asy::Future::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => x ?{core::int*} 2 : await asy::Future::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async /* futureValueType= core::int* */ {
     return (await x ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
   asy::Future<core::int*>* t5 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* => (x ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.weak.modular.expect
index 0c2809d..4d22096 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.weak.modular.expect
@@ -34,8 +34,8 @@
 }
 static method test() → void {
   asy::Future<core::bool*>* f;
-  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async => x ?{core::int*} 2 : await asy::Future::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => x ?{core::int*} 2 : await asy::Future::value<core::int*>(3)){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* async /* futureValueType= core::int* */ {
     return (await x ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
   asy::Future<core::int*>* t5 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* => (x ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.weak.transformed.expect
index 51cd23d..9c16fa5 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
 }
 static method test() → void {
   asy::Future<core::bool*>* f;
-  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t1 = f.{asy::Future::then}<core::int*>((core::bool* x) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -71,7 +71,7 @@
     :is_sync = true;
     return :async_future;
   }){((core::bool*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.weak.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.weak.expect
index 39e82e2..2dfc365 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.weak.expect
@@ -34,8 +34,8 @@
 }
 static method test() → void {
   self::MyFuture<core::int*>* f;
-  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::Future<core::int*>* async => let final core::int* #t1 = x in #t1 == null ?{core::int*} await asy::Future::value<core::int*>(3) : #t1){((core::int*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::int* x) → FutureOr<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => let final core::int* #t1 = x in #t1 == null ?{core::int*} await asy::Future::value<core::int*>(3) : #t1){((core::int*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::int* x) → FutureOr<core::int*>* async /* futureValueType= core::int* */ {
     return (let final core::int* #t2 = await x in #t2 == null ?{core::Object*} asy::Future::value<core::int*>(3) : #t2) as{TypeError} FutureOr<core::int*>*;
   }){((core::int*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::int* x) → FutureOr<core::int*>* => (let final core::int* #t3 = x in #t3 == null ?{core::Object*} asy::Future::value<core::int*>(3) : #t3) as{TypeError} FutureOr<core::int*>*){((core::int*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.weak.modular.expect
index 39e82e2..2dfc365 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.weak.modular.expect
@@ -34,8 +34,8 @@
 }
 static method test() → void {
   self::MyFuture<core::int*>* f;
-  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::Future<core::int*>* async => let final core::int* #t1 = x in #t1 == null ?{core::int*} await asy::Future::value<core::int*>(3) : #t1){((core::int*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::int* x) → FutureOr<core::int*>* async {
+  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ => let final core::int* #t1 = x in #t1 == null ?{core::int*} await asy::Future::value<core::int*>(3) : #t1){((core::int*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
+  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::int* x) → FutureOr<core::int*>* async /* futureValueType= core::int* */ {
     return (let final core::int* #t2 = await x in #t2 == null ?{core::Object*} asy::Future::value<core::int*>(3) : #t2) as{TypeError} FutureOr<core::int*>*;
   }){((core::int*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::int* x) → FutureOr<core::int*>* => (let final core::int* #t3 = x in #t3 == null ?{core::Object*} asy::Future::value<core::int*>(3) : #t3) as{TypeError} FutureOr<core::int*>*){((core::int*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.weak.transformed.expect
index 59febc8..83b6d1e 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
 }
 static method test() → void {
   self::MyFuture<core::int*>* f;
-  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::Future<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t1 = f.{self::MyFuture::then}<core::int*>((core::int* x) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -72,7 +72,7 @@
     :is_sync = true;
     return :async_future;
   }){((core::int*) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
-  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::int* x) → FutureOr<core::int*>* /* originally async */ {
+  asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::int* x) → FutureOr<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.weak.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.weak.expect
index dcdc4a1..162aade 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.weak.expect
@@ -32,12 +32,12 @@
   no-such-method-forwarder method timeout(core::Duration* timeLimit, {covariant-by-class () →* FutureOr<self::MyFuture::T*>* onTimeout = #C1}) → asy::Future<self::MyFuture::T*>*
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C10: onTimeout}))){(core::Invocation*) →* dynamic} as{TypeError,ForDynamic} asy::Future<self::MyFuture::T*>*;
 }
-static method g1(core::bool* x) → asy::Future<core::int*>* async {
+static method g1(core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
   return (x ?{core::Object*} 42 : asy::Future::value<core::int*>(42)) as{TypeError} FutureOr<core::int*>*;
 }
-static method g2(core::bool* x) → asy::Future<core::int*>* async 
+static method g2(core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
   return (x ?{core::Object*} 42 : asy::Future::value<core::int*>(42)) as{TypeError} FutureOr<core::int*>*;
-static method g3(core::bool* x) → asy::Future<core::int*>* async {
+static method g3(core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
   core::Object* y = x ?{core::Object*} 42 : asy::Future::value<core::int*>(42);
   return y as{TypeError} FutureOr<core::int*>*;
 }
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.weak.modular.expect
index dcdc4a1..162aade 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.weak.modular.expect
@@ -32,12 +32,12 @@
   no-such-method-forwarder method timeout(core::Duration* timeLimit, {covariant-by-class () →* FutureOr<self::MyFuture::T*>* onTimeout = #C1}) → asy::Future<self::MyFuture::T*>*
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C10: onTimeout}))){(core::Invocation*) →* dynamic} as{TypeError,ForDynamic} asy::Future<self::MyFuture::T*>*;
 }
-static method g1(core::bool* x) → asy::Future<core::int*>* async {
+static method g1(core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
   return (x ?{core::Object*} 42 : asy::Future::value<core::int*>(42)) as{TypeError} FutureOr<core::int*>*;
 }
-static method g2(core::bool* x) → asy::Future<core::int*>* async 
+static method g2(core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
   return (x ?{core::Object*} 42 : asy::Future::value<core::int*>(42)) as{TypeError} FutureOr<core::int*>*;
-static method g3(core::bool* x) → asy::Future<core::int*>* async {
+static method g3(core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
   core::Object* y = x ?{core::Object*} 42 : asy::Future::value<core::int*>(42);
   return y as{TypeError} FutureOr<core::int*>*;
 }
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.weak.transformed.expect
index ea1b07f..e561f29 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.weak.transformed.expect
@@ -32,7 +32,7 @@
   no-such-method-forwarder method timeout(core::Duration* timeLimit, {covariant-by-class () →* FutureOr<self::MyFuture::T*>* onTimeout = #C1}) → asy::Future<self::MyFuture::T*>*
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C10: onTimeout}))){(core::Invocation*) →* dynamic} as{TypeError,ForDynamic} asy::Future<self::MyFuture::T*>*;
 }
-static method g1(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
+static method g1(core::bool* x) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
@@ -59,7 +59,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method g2(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
+static method g2(core::bool* x) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
@@ -86,7 +86,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method g3(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
+static method g3(core::bool* x) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.weak.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.weak.expect
index 1c0791d..8bebe17 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.weak.expect
@@ -32,12 +32,12 @@
   no-such-method-forwarder method timeout(core::Duration* timeLimit, {covariant-by-class () →* FutureOr<self::MyFuture::T*>* onTimeout = #C1}) → asy::Future<self::MyFuture::T*>*
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C10: onTimeout}))){(core::Invocation*) →* dynamic} as{TypeError,ForDynamic} asy::Future<self::MyFuture::T*>*;
 }
-static method g1(core::bool* x) → asy::Future<core::int*>* async {
+static method g1(core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
   return (x ?{core::Object*} 42 : new self::MyFuture::value<core::int*>(42)) as{TypeError} FutureOr<core::int*>*;
 }
-static method g2(core::bool* x) → asy::Future<core::int*>* async 
+static method g2(core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
   return (x ?{core::Object*} 42 : new self::MyFuture::value<core::int*>(42)) as{TypeError} FutureOr<core::int*>*;
-static method g3(core::bool* x) → asy::Future<core::int*>* async {
+static method g3(core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
   core::Object* y = x ?{core::Object*} 42 : new self::MyFuture::value<dynamic>(42);
   return y as{TypeError} FutureOr<core::int*>*;
 }
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.weak.modular.expect
index 1c0791d..8bebe17 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.weak.modular.expect
@@ -32,12 +32,12 @@
   no-such-method-forwarder method timeout(core::Duration* timeLimit, {covariant-by-class () →* FutureOr<self::MyFuture::T*>* onTimeout = #C1}) → asy::Future<self::MyFuture::T*>*
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, core::List::unmodifiable<dynamic>(<dynamic>[timeLimit]), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C10: onTimeout}))){(core::Invocation*) →* dynamic} as{TypeError,ForDynamic} asy::Future<self::MyFuture::T*>*;
 }
-static method g1(core::bool* x) → asy::Future<core::int*>* async {
+static method g1(core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
   return (x ?{core::Object*} 42 : new self::MyFuture::value<core::int*>(42)) as{TypeError} FutureOr<core::int*>*;
 }
-static method g2(core::bool* x) → asy::Future<core::int*>* async 
+static method g2(core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
   return (x ?{core::Object*} 42 : new self::MyFuture::value<core::int*>(42)) as{TypeError} FutureOr<core::int*>*;
-static method g3(core::bool* x) → asy::Future<core::int*>* async {
+static method g3(core::bool* x) → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
   core::Object* y = x ?{core::Object*} 42 : new self::MyFuture::value<dynamic>(42);
   return y as{TypeError} FutureOr<core::int*>*;
 }
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.weak.transformed.expect
index 110e697..042521a 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.weak.transformed.expect
@@ -32,7 +32,7 @@
   no-such-method-forwarder method timeout(core::Duration* timeLimit, {covariant-by-class () →* FutureOr<self::MyFuture::T*>* onTimeout = #C1}) → asy::Future<self::MyFuture::T*>*
     return this.{self::MyFuture::noSuchMethod}(new core::_InvocationMirror::_withType(#C9, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C10: onTimeout}))){(core::Invocation*) →* dynamic} as{TypeError,ForDynamic} asy::Future<self::MyFuture::T*>*;
 }
-static method g1(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
+static method g1(core::bool* x) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
@@ -59,7 +59,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method g2(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
+static method g2(core::bool* x) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
@@ -86,7 +86,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method g3(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
+static method g3(core::bool* x) → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
   final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
   core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.expect
index ccef45f..cc96345 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.expect
@@ -44,10 +44,10 @@
         new /*@ typeArgs=int* */ Future.value('hi'));
                                               ^" in "hi" as{TypeError} FutureOr<core::int*>?)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{self::MyFuture::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => <core::int*>[3]){((dynamic) →* FutureOr<core::List<core::int*>*>*, {onError: core::Function*}) →* self::MyFuture<core::List<core::int*>*>*};
-static method g2() → asy::Future<core::List<core::int*>*>* async {
+static method g2() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return <core::int*>[3];
 }
-static method g3() → asy::Future<core::List<core::int*>*>* async {
+static method g3() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return asy::Future::value<core::List<core::int*>*>(<core::int*>[3]);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.modular.expect
index ccef45f..cc96345 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.modular.expect
@@ -44,10 +44,10 @@
         new /*@ typeArgs=int* */ Future.value('hi'));
                                               ^" in "hi" as{TypeError} FutureOr<core::int*>?)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{self::MyFuture::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => <core::int*>[3]){((dynamic) →* FutureOr<core::List<core::int*>*>*, {onError: core::Function*}) →* self::MyFuture<core::List<core::int*>*>*};
-static method g2() → asy::Future<core::List<core::int*>*>* async {
+static method g2() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return <core::int*>[3];
 }
-static method g3() → asy::Future<core::List<core::int*>*>* async {
+static method g3() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return asy::Future::value<core::List<core::int*>*>(<core::int*>[3]);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.transformed.expect
index 8d75a91..4d9373c 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.weak.transformed.expect
@@ -44,7 +44,7 @@
         new /*@ typeArgs=int* */ Future.value('hi'));
                                               ^" in "hi" as{TypeError} FutureOr<core::int*>?)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{self::MyFuture::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => core::_GrowableList::_literal1<core::int*>(3)){((dynamic) →* FutureOr<core::List<core::int*>*>*, {onError: core::Function*}) →* self::MyFuture<core::List<core::int*>*>*};
-static method g2() → asy::Future<core::List<core::int*>*>* /* originally async */ {
+static method g2() → asy::Future<core::List<core::int*>*>* /* futureValueType= core::List<core::int*>* */ /* originally async */ {
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   core::List<core::int*>? :return_value;
@@ -71,7 +71,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method g3() → asy::Future<core::List<core::int*>*>* /* originally async */ {
+static method g3() → asy::Future<core::List<core::int*>*>* /* futureValueType= core::List<core::int*>* */ /* originally async */ {
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::List<core::int*>*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.expect
index 09bd9c2..ddc2463 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.expect
@@ -35,10 +35,10 @@
 static field self::MyFuture<dynamic>* f;
 static field asy::Future<core::int*>* t1 = self::f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>("hi")){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{self::MyFuture::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => <core::int*>[3]){((dynamic) →* FutureOr<core::List<core::int*>*>*, {onError: core::Function*}) →* self::MyFuture<core::List<core::int*>*>*};
-static method g2() → asy::Future<core::List<core::int*>*>* async {
+static method g2() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return <core::int*>[3];
 }
-static method g3() → asy::Future<core::List<core::int*>*>* async {
+static method g3() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return new self::MyFuture::value<core::List<core::int*>*>(<core::int*>[3]);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.modular.expect
index 09bd9c2..ddc2463 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.modular.expect
@@ -35,10 +35,10 @@
 static field self::MyFuture<dynamic>* f;
 static field asy::Future<core::int*>* t1 = self::f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>("hi")){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{self::MyFuture::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => <core::int*>[3]){((dynamic) →* FutureOr<core::List<core::int*>*>*, {onError: core::Function*}) →* self::MyFuture<core::List<core::int*>*>*};
-static method g2() → asy::Future<core::List<core::int*>*>* async {
+static method g2() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return <core::int*>[3];
 }
-static method g3() → asy::Future<core::List<core::int*>*>* async {
+static method g3() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return new self::MyFuture::value<core::List<core::int*>*>(<core::int*>[3]);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.transformed.expect
index c18f5d9..b24c57d 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
 static field self::MyFuture<dynamic>* f;
 static field asy::Future<core::int*>* t1 = self::f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>("hi")){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* self::MyFuture<core::int*>*};
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{self::MyFuture::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => core::_GrowableList::_literal1<core::int*>(3)){((dynamic) →* FutureOr<core::List<core::int*>*>*, {onError: core::Function*}) →* self::MyFuture<core::List<core::int*>*>*};
-static method g2() → asy::Future<core::List<core::int*>*>* /* originally async */ {
+static method g2() → asy::Future<core::List<core::int*>*>* /* futureValueType= core::List<core::int*>* */ /* originally async */ {
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   core::List<core::int*>? :return_value;
@@ -62,7 +62,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method g3() → asy::Future<core::List<core::int*>*>* /* originally async */ {
+static method g3() → asy::Future<core::List<core::int*>*>* /* futureValueType= core::List<core::int*>* */ /* originally async */ {
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::List<core::int*>*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.expect
index 36b2fa5..a49daa8 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.expect
@@ -44,10 +44,10 @@
         new /*@ typeArgs=int* */ Future.value('hi'));
                                               ^" in "hi" as{TypeError} FutureOr<core::int*>?)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{asy::Future::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => <core::int*>[3]){((dynamic) →* FutureOr<core::List<core::int*>*>*, {onError: core::Function*}) →* asy::Future<core::List<core::int*>*>*};
-static method g2() → asy::Future<core::List<core::int*>*>* async {
+static method g2() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return <core::int*>[3];
 }
-static method g3() → asy::Future<core::List<core::int*>*>* async {
+static method g3() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return asy::Future::value<core::List<core::int*>*>(<core::int*>[3]);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.modular.expect
index 36b2fa5..a49daa8 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.modular.expect
@@ -44,10 +44,10 @@
         new /*@ typeArgs=int* */ Future.value('hi'));
                                               ^" in "hi" as{TypeError} FutureOr<core::int*>?)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{asy::Future::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => <core::int*>[3]){((dynamic) →* FutureOr<core::List<core::int*>*>*, {onError: core::Function*}) →* asy::Future<core::List<core::int*>*>*};
-static method g2() → asy::Future<core::List<core::int*>*>* async {
+static method g2() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return <core::int*>[3];
 }
-static method g3() → asy::Future<core::List<core::int*>*>* async {
+static method g3() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return asy::Future::value<core::List<core::int*>*>(<core::int*>[3]);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.transformed.expect
index e17a236..feef12c 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.weak.transformed.expect
@@ -44,7 +44,7 @@
         new /*@ typeArgs=int* */ Future.value('hi'));
                                               ^" in "hi" as{TypeError} FutureOr<core::int*>?)){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{asy::Future::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => core::_GrowableList::_literal1<core::int*>(3)){((dynamic) →* FutureOr<core::List<core::int*>*>*, {onError: core::Function*}) →* asy::Future<core::List<core::int*>*>*};
-static method g2() → asy::Future<core::List<core::int*>*>* /* originally async */ {
+static method g2() → asy::Future<core::List<core::int*>*>* /* futureValueType= core::List<core::int*>* */ /* originally async */ {
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   core::List<core::int*>? :return_value;
@@ -71,7 +71,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method g3() → asy::Future<core::List<core::int*>*>* /* originally async */ {
+static method g3() → asy::Future<core::List<core::int*>*>* /* futureValueType= core::List<core::int*>* */ /* originally async */ {
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::List<core::int*>*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.expect
index 5ecc3e7..dcf9785 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.expect
@@ -35,10 +35,10 @@
 static field asy::Future<dynamic>* f;
 static field asy::Future<core::int*>* t1 = self::f.{asy::Future::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>("hi")){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{asy::Future::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => <core::int*>[3]){((dynamic) →* FutureOr<core::List<core::int*>*>*, {onError: core::Function*}) →* asy::Future<core::List<core::int*>*>*};
-static method g2() → asy::Future<core::List<core::int*>*>* async {
+static method g2() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return <core::int*>[3];
 }
-static method g3() → asy::Future<core::List<core::int*>*>* async {
+static method g3() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return new self::MyFuture::value<core::List<core::int*>*>(<core::int*>[3]);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.modular.expect
index 5ecc3e7..dcf9785 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.modular.expect
@@ -35,10 +35,10 @@
 static field asy::Future<dynamic>* f;
 static field asy::Future<core::int*>* t1 = self::f.{asy::Future::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>("hi")){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{asy::Future::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => <core::int*>[3]){((dynamic) →* FutureOr<core::List<core::int*>*>*, {onError: core::Function*}) →* asy::Future<core::List<core::int*>*>*};
-static method g2() → asy::Future<core::List<core::int*>*>* async {
+static method g2() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return <core::int*>[3];
 }
-static method g3() → asy::Future<core::List<core::int*>*>* async {
+static method g3() → asy::Future<core::List<core::int*>*>* async /* futureValueType= core::List<core::int*>* */ {
   return new self::MyFuture::value<core::List<core::int*>*>(<core::int*>[3]);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.transformed.expect
index 87fe01a..685b7cb 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.weak.transformed.expect
@@ -35,7 +35,7 @@
 static field asy::Future<dynamic>* f;
 static field asy::Future<core::int*>* t1 = self::f.{asy::Future::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>("hi")){((dynamic) →* FutureOr<core::int*>*, {onError: core::Function*}) →* asy::Future<core::int*>*};
 static field asy::Future<core::List<core::int*>*>* t2 = self::f.{asy::Future::then}<core::List<core::int*>*>((dynamic _) → core::List<core::int*>* => core::_GrowableList::_literal1<core::int*>(3)){((dynamic) →* FutureOr<core::List<core::int*>*>*, {onError: core::Function*}) →* asy::Future<core::List<core::int*>*>*};
-static method g2() → asy::Future<core::List<core::int*>*>* /* originally async */ {
+static method g2() → asy::Future<core::List<core::int*>*>* /* futureValueType= core::List<core::int*>* */ /* originally async */ {
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   core::List<core::int*>? :return_value;
@@ -62,7 +62,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method g3() → asy::Future<core::List<core::int*>*>* /* originally async */ {
+static method g3() → asy::Future<core::List<core::int*>*>* /* futureValueType= core::List<core::int*>* */ /* originally async */ {
   final asy::_Future<core::List<core::int*>*>* :async_future = new asy::_Future::•<core::List<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<core::List<core::int*>*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.weak.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.weak.expect
index 05e3e74..d938457 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.weak.expect
@@ -20,7 +20,7 @@
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
-static method foo() → dynamic async {
+static method foo() → dynamic async /* futureValueType= dynamic */ {
   asy::Future<core::List<self::A*>*>* f1 = null;
   asy::Future<core::List<self::A*>*>* f2 = null;
   core::List<core::List<self::A*>*>* merged = await asy::Future::wait<core::List<self::A*>*>(<asy::Future<core::List<self::A*>*>*>[f1, f2]);
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.weak.modular.expect
index 05e3e74..d938457 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.weak.modular.expect
@@ -20,7 +20,7 @@
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
-static method foo() → dynamic async {
+static method foo() → dynamic async /* futureValueType= dynamic */ {
   asy::Future<core::List<self::A*>*>* f1 = null;
   asy::Future<core::List<self::A*>*>* f2 = null;
   core::List<core::List<self::A*>*>* merged = await asy::Future::wait<core::List<self::A*>*>(<asy::Future<core::List<self::A*>*>*>[f1, f2]);
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.weak.transformed.expect
index 719fe87..0664c85 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.weak.transformed.expect
@@ -21,7 +21,7 @@
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
-static method foo() → dynamic /* originally async */ {
+static method foo() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.weak.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.weak.expect
index 8b0d132..9fb7dae 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.weak.expect
@@ -7,7 +7,7 @@
 
 static method id<T extends core::Object* = dynamic>(self::id::T* x) → self::id::T*
   return x;
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   asy::Future<core::String*>* f;
   core::String* s = await self::id<FutureOr<core::String*>*>(f);
 }
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.weak.modular.expect
index 8b0d132..9fb7dae 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.weak.modular.expect
@@ -7,7 +7,7 @@
 
 static method id<T extends core::Object* = dynamic>(self::id::T* x) → self::id::T*
   return x;
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   asy::Future<core::String*>* f;
   core::String* s = await self::id<FutureOr<core::String*>*>(f);
 }
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.weak.transformed.expect
index 289f3bf..ee68309 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.weak.transformed.expect
@@ -8,7 +8,7 @@
 
 static method id<T extends core::Object* = dynamic>(self::id::T* x) → self::id::T*
   return x;
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.weak.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.weak.expect
index f663f65..8c17d48 100644
--- a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.weak.expect
@@ -30,7 +30,7 @@
     : super self::A::•()
     ;
 }
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   asy::Future<self::B*>* b = asy::Future::value<self::B*>(new self::B::•());
   asy::Future<self::C*>* c = asy::Future::value<self::C*>(new self::C::•());
   core::List<asy::Future<self::A*>*>* lll = <asy::Future<self::A*>*>[b, c];
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.weak.modular.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.weak.modular.expect
index f663f65..8c17d48 100644
--- a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.weak.modular.expect
@@ -30,7 +30,7 @@
     : super self::A::•()
     ;
 }
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   asy::Future<self::B*>* b = asy::Future::value<self::B*>(new self::B::•());
   asy::Future<self::C*>* c = asy::Future::value<self::C*>(new self::C::•());
   core::List<asy::Future<self::A*>*>* lll = <asy::Future<self::A*>*>[b, c];
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.weak.transformed.expect
index 0045a57..7d0a74b 100644
--- a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.weak.transformed.expect
@@ -31,7 +31,7 @@
     : super self::A::•()
     ;
 }
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.weak.expect b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.weak.expect
index eb05a20..9486b2b 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.weak.expect
@@ -6,12 +6,12 @@
 static method test() → dynamic {
   function f0() → core::int*
     return 42;
-  function f1() → asy::Future<core::int*>* async 
+  function f1() → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
     return 42;
   function f2() → core::int* {
     return 42;
   }
-  function f3() → asy::Future<core::int*>* async {
+  function f3() → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return 42;
   }
   function f4() → core::Iterable<core::int*>* sync* {
diff --git a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.weak.modular.expect b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.weak.modular.expect
index eb05a20..9486b2b 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.weak.modular.expect
@@ -6,12 +6,12 @@
 static method test() → dynamic {
   function f0() → core::int*
     return 42;
-  function f1() → asy::Future<core::int*>* async 
+  function f1() → asy::Future<core::int*>* async /* futureValueType= core::int* */ 
     return 42;
   function f2() → core::int* {
     return 42;
   }
-  function f3() → asy::Future<core::int*>* async {
+  function f3() → asy::Future<core::int*>* async /* futureValueType= core::int* */ {
     return 42;
   }
   function f4() → core::Iterable<core::int*>* sync* {
diff --git a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.weak.transformed.expect
index afb8f44..f5a8bb3 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.weak.transformed.expect
@@ -6,7 +6,7 @@
 static method test() → dynamic {
   function f0() → core::int*
     return 42;
-  function f1() → asy::Future<core::int*>* /* originally async */ {
+  function f1() → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -36,7 +36,7 @@
   function f2() → core::int* {
     return 42;
   }
-  function f3() → asy::Future<core::int*>* /* originally async */ {
+  function f3() → asy::Future<core::int*>* /* futureValueType= core::int* */ /* originally async */ {
     final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
     core::bool* :is_sync = false;
     core::int? :return_value;
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.weak.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.weak.expect
index c16146f..0acd6fd 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.weak.expect
@@ -54,7 +54,7 @@
   synthetic constructor •() → self::Bar<self::Bar::T*>*
     : super core::Object::•()
     ;
-  method foo(covariant-by-class self::Bar::T* t) → dynamic async {
+  method foo(covariant-by-class self::Bar::T* t) → dynamic async /* futureValueType= dynamic */ {
     await for (core::String* i in t) {
       core::int* x = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:17:44: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
       int x = /*error:INVALID_ASSIGNMENT*/ i;
@@ -76,7 +76,7 @@
   synthetic constructor •() → self::Baz<self::Baz::T*, self::Baz::E*, self::Baz::S*>*
     : super core::Object::•()
     ;
-  method foo(covariant-by-class self::Baz::S* t) → dynamic async {
+  method foo(covariant-by-class self::Baz::S* t) → dynamic async /* futureValueType= dynamic */ {
     await for (self::Baz::T* i in t) {
       core::int* x = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:25:44: Error: A value of type 'T' can't be assigned to a variable of type 'int'.
       int x = /*error:INVALID_ASSIGNMENT*/ i;
@@ -146,7 +146,7 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
   abstract member-signature method listen((self::MyStream::T*) →* void onData, {core::Function* onError = #C1, () →* void onDone = #C1, core::bool* cancelOnError = #C1}) → asy::StreamSubscription<self::MyStream::T*>*; -> asy::Stream::listen
 }
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   self::MyStream<self::Foo*>* myStream = self::MyStream::•<self::Foo*>();
   await for (self::Foo* x in myStream) {
     core::String* y = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:38:45: Error: A value of type 'Foo' can't be assigned to a variable of type 'String'.
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.weak.modular.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.weak.modular.expect
index c16146f..0acd6fd 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.weak.modular.expect
@@ -54,7 +54,7 @@
   synthetic constructor •() → self::Bar<self::Bar::T*>*
     : super core::Object::•()
     ;
-  method foo(covariant-by-class self::Bar::T* t) → dynamic async {
+  method foo(covariant-by-class self::Bar::T* t) → dynamic async /* futureValueType= dynamic */ {
     await for (core::String* i in t) {
       core::int* x = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:17:44: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
       int x = /*error:INVALID_ASSIGNMENT*/ i;
@@ -76,7 +76,7 @@
   synthetic constructor •() → self::Baz<self::Baz::T*, self::Baz::E*, self::Baz::S*>*
     : super core::Object::•()
     ;
-  method foo(covariant-by-class self::Baz::S* t) → dynamic async {
+  method foo(covariant-by-class self::Baz::S* t) → dynamic async /* futureValueType= dynamic */ {
     await for (self::Baz::T* i in t) {
       core::int* x = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:25:44: Error: A value of type 'T' can't be assigned to a variable of type 'int'.
       int x = /*error:INVALID_ASSIGNMENT*/ i;
@@ -146,7 +146,7 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
   abstract member-signature method listen((self::MyStream::T*) →* void onData, {core::Function* onError = #C1, () →* void onDone = #C1, core::bool* cancelOnError = #C1}) → asy::StreamSubscription<self::MyStream::T*>*; -> asy::Stream::listen
 }
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   self::MyStream<self::Foo*>* myStream = self::MyStream::•<self::Foo*>();
   await for (self::Foo* x in myStream) {
     core::String* y = invalid-expression "pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart:38:45: Error: A value of type 'Foo' can't be assigned to a variable of type 'String'.
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.weak.transformed.expect
index f060c75..170116d 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.weak.transformed.expect
@@ -55,7 +55,7 @@
   synthetic constructor •() → self::Bar<self::Bar::T*>*
     : super core::Object::•()
     ;
-  method foo(covariant-by-class self::Bar::T* t) → dynamic /* originally async */ {
+  method foo(covariant-by-class self::Bar::T* t) → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     dynamic :return_value;
@@ -124,7 +124,7 @@
   synthetic constructor •() → self::Baz<self::Baz::T*, self::Baz::E*, self::Baz::S*>*
     : super core::Object::•()
     ;
-  method foo(covariant-by-class self::Baz::S* t) → dynamic /* originally async */ {
+  method foo(covariant-by-class self::Baz::S* t) → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     dynamic :return_value;
@@ -241,7 +241,7 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
   abstract member-signature method listen((self::MyStream::T*) →* void onData, {core::Function* onError = #C1, () →* void onDone = #C1, core::bool* cancelOnError = #C1}) → asy::StreamSubscription<self::MyStream::T*>*; -> asy::Stream::listen
 }
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.expect
index 421e71c..67f213e 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.expect
@@ -18,7 +18,7 @@
   function a() → (core::int*) →* core::int* {
     return (core::int* x) → core::int* => x;
   }
-  function b() → asy::Future<(core::int*) →* core::int*>* async {
+  function b() → asy::Future<(core::int*) →* core::int*>* async /* futureValueType= (core::int*) →* core::int* */ {
     return invalid-expression "pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
  - 'Future' is from 'dart:async'.
     return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.modular.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.modular.expect
index 421e71c..67f213e 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.modular.expect
@@ -18,7 +18,7 @@
   function a() → (core::int*) →* core::int* {
     return (core::int* x) → core::int* => x;
   }
-  function b() → asy::Future<(core::int*) →* core::int*>* async {
+  function b() → asy::Future<(core::int*) →* core::int*>* async /* futureValueType= (core::int*) →* core::int* */ {
     return invalid-expression "pkg/front_end/testcases/inference/local_return_and_yield.dart:19:38: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
  - 'Future' is from 'dart:async'.
     return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.transformed.expect
index 285cb47..fbcd719 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.weak.transformed.expect
@@ -18,7 +18,7 @@
   function a() → (core::int*) →* core::int* {
     return (core::int* x) → core::int* => x;
   }
-  function b() → asy::Future<(core::int*) →* core::int*>* /* originally async */ {
+  function b() → asy::Future<(core::int*) →* core::int*>* /* futureValueType= (core::int*) →* core::int* */ /* originally async */ {
     final asy::_Future<(core::int*) →* core::int*>* :async_future = new asy::_Future::•<(core::int*) →* core::int*>();
     core::bool* :is_sync = false;
     FutureOr<(core::int*) →* core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.expect
index 3ca6230..f7164a5 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.expect
@@ -17,7 +17,7 @@
 static method a() → (core::int*) →* core::int* {
   return (core::int* x) → core::int* => x;
 }
-static method b() → asy::Future<(core::int*) →* core::int*>* async {
+static method b() → asy::Future<(core::int*) →* core::int*>* async /* futureValueType= (core::int*) →* core::int* */ {
   return invalid-expression "pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
  - 'Future' is from 'dart:async'.
   return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.modular.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.modular.expect
index 3ca6230..f7164a5 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.modular.expect
@@ -17,7 +17,7 @@
 static method a() → (core::int*) →* core::int* {
   return (core::int* x) → core::int* => x;
 }
-static method b() → asy::Future<(core::int*) →* core::int*>* async {
+static method b() → asy::Future<(core::int*) →* core::int*>* async /* futureValueType= (core::int*) →* core::int* */ {
   return invalid-expression "pkg/front_end/testcases/inference/top_level_return_and_yield.dart:18:36: Error: A value of type 'Future<dynamic Function(dynamic)>' can't be assigned to a variable of type 'FutureOr<int Function(int)>'.
  - 'Future' is from 'dart:async'.
   return /*@ returnType=dynamic */ (/*@ type=dynamic */ x) => x;
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.transformed.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.transformed.expect
index d7f66be..84ea22c 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.weak.transformed.expect
@@ -17,7 +17,7 @@
 static method a() → (core::int*) →* core::int* {
   return (core::int* x) → core::int* => x;
 }
-static method b() → asy::Future<(core::int*) →* core::int*>* /* originally async */ {
+static method b() → asy::Future<(core::int*) →* core::int*>* /* futureValueType= (core::int*) →* core::int* */ /* originally async */ {
   final asy::_Future<(core::int*) →* core::int*>* :async_future = new asy::_Future::•<(core::int*) →* core::int*>();
   core::bool* :is_sync = false;
   FutureOr<(core::int*) →* core::int*>* :return_value;
diff --git a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.weak.expect b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.weak.expect
index 727e04a..63943b6 100644
--- a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.weak.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.weak.expect
@@ -26,7 +26,7 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   core::String* s;
   for (final dynamic #t1 in invalid-expression "pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:10:17: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
diff --git a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.weak.modular.expect b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.weak.modular.expect
index 727e04a..63943b6 100644
--- a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.weak.modular.expect
@@ -26,7 +26,7 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   core::String* s;
   for (final dynamic #t1 in invalid-expression "pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart:10:17: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
diff --git a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.weak.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.weak.transformed.expect
index 2eaaf2a..71aadc6 100644
--- a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.weak.transformed.expect
@@ -27,7 +27,7 @@
 import "dart:core" as core;
 import "dart:_internal" as _in;
 
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.weak.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.weak.expect
index e195507..5c4c5e0 100644
--- a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.weak.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.weak.expect
@@ -42,7 +42,7 @@
 }
 static method f<T extends core::Object* = dynamic>() → self::f::T*
   return null;
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   core::Iterable<self::A*>* iterable;
   asy::Stream<self::A*>* stream;
   self::A* a;
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.weak.modular.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.weak.modular.expect
index e195507..5c4c5e0 100644
--- a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.weak.modular.expect
@@ -42,7 +42,7 @@
 }
 static method f<T extends core::Object* = dynamic>() → self::f::T*
   return null;
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   core::Iterable<self::A*>* iterable;
   asy::Stream<self::A*>* stream;
   self::A* a;
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.weak.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.weak.transformed.expect
index 703f7d8..c30707e 100644
--- a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.weak.transformed.expect
@@ -43,7 +43,7 @@
 }
 static method f<T extends core::Object* = dynamic>() → self::f::T*
   return null;
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.strong.expect b/pkg/front_end/testcases/late_lowering/later.dart.strong.expect
index dac68ea..d3a7d53 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.strong.expect
@@ -130,13 +130,13 @@
       #t5.{core::List::add}{Invariant}(i){(core::int) → void};
   } =>#t5;
 }
-static method hest() → dynamic async {
+static method hest() → dynamic async /* futureValueType= dynamic */ {
   await for (core::String s in asy::Stream::fromIterable<core::String>(<core::String>["hest"])) {
     core::print(s);
   }
   return "hest";
 }
-static method fisk() → dynamic async {
+static method fisk() → dynamic async /* futureValueType= dynamic */ {
   lowered core::String? #s1;
   function #s1#get() → core::String
     return let final core::String? #t6 = #s1 in #t6 == null ?{core::String} #s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
@@ -153,7 +153,7 @@
     return #s2 = s2#param;
   lowered core::Function? #f;
   function #f#get() → core::Function
-    return let final core::Function? #t8 = #f in #t8 == null ?{core::Function} #f = () → asy::Future<dynamic> async => await self::hest() : #t8{core::Function};
+    return let final core::Function? #t8 = #f in #t8 == null ?{core::Function} #f = () → asy::Future<dynamic> async /* futureValueType= dynamic */ => await self::hest() : #t8{core::Function};
   function #f#set(core::Function f#param) → dynamic
     return #f = f#param;
 }
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect
index 5595103..e452424 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect
@@ -136,7 +136,7 @@
       #t5.{core::List::add}{Invariant}(i){(core::int) → void};
   } =>#t5;
 }
-static method hest() → dynamic /* originally async */ {
+static method hest() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -190,7 +190,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method fisk() → dynamic /* originally async */ {
+static method fisk() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -218,7 +218,7 @@
           return #s2 = s2#param;
         lowered core::Function? #f;
         function #f#get() → core::Function
-          return let final core::Function? #t11 = #f in #t11 == null ?{core::Function} #f = () → asy::Future<dynamic> /* originally async */ {
+          return let final core::Function? #t11 = #f in #t11 == null ?{core::Function} #f = () → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
             final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
             core::bool* :is_sync = false;
             FutureOr<dynamic>? :return_value;
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.weak.expect b/pkg/front_end/testcases/late_lowering/later.dart.weak.expect
index 74e414d..7d779ec 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.weak.expect
@@ -150,13 +150,13 @@
       #t5.{core::List::add}{Invariant}(i){(core::int) → void};
   } =>#t5;
 }
-static method hest() → dynamic async {
+static method hest() → dynamic async /* futureValueType= dynamic */ {
   await for (core::String s in asy::Stream::fromIterable<core::String>(<core::String>["hest"])) {
     core::print(s);
   }
   return "hest";
 }
-static method fisk() → dynamic async {
+static method fisk() → dynamic async /* futureValueType= dynamic */ {
   lowered core::String? #s1;
   lowered core::bool #s1#isSet = false;
   function #s1#get() → core::String {
@@ -191,7 +191,7 @@
   lowered core::bool #f#isSet = false;
   function #f#get() → core::Function {
     if(!#f#isSet) {
-      #f = () → asy::Future<dynamic> async => await self::hest();
+      #f = () → asy::Future<dynamic> async /* futureValueType= dynamic */ => await self::hest();
       #f#isSet = true;
     }
     return #f{core::Function};
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.weak.modular.expect b/pkg/front_end/testcases/late_lowering/later.dart.weak.modular.expect
index 74e414d..7d779ec 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.weak.modular.expect
@@ -150,13 +150,13 @@
       #t5.{core::List::add}{Invariant}(i){(core::int) → void};
   } =>#t5;
 }
-static method hest() → dynamic async {
+static method hest() → dynamic async /* futureValueType= dynamic */ {
   await for (core::String s in asy::Stream::fromIterable<core::String>(<core::String>["hest"])) {
     core::print(s);
   }
   return "hest";
 }
-static method fisk() → dynamic async {
+static method fisk() → dynamic async /* futureValueType= dynamic */ {
   lowered core::String? #s1;
   lowered core::bool #s1#isSet = false;
   function #s1#get() → core::String {
@@ -191,7 +191,7 @@
   lowered core::bool #f#isSet = false;
   function #f#get() → core::Function {
     if(!#f#isSet) {
-      #f = () → asy::Future<dynamic> async => await self::hest();
+      #f = () → asy::Future<dynamic> async /* futureValueType= dynamic */ => await self::hest();
       #f#isSet = true;
     }
     return #f{core::Function};
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect
index 7d0a057..73b9804 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect
@@ -156,7 +156,7 @@
       #t5.{core::List::add}{Invariant}(i){(core::int) → void};
   } =>#t5;
 }
-static method hest() → dynamic /* originally async */ {
+static method hest() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -210,7 +210,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method fisk() → dynamic /* originally async */ {
+static method fisk() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -256,7 +256,7 @@
         lowered core::bool #f#isSet = false;
         function #f#get() → core::Function {
           if(!#f#isSet) {
-            #f = () → asy::Future<dynamic> /* originally async */ {
+            #f = () → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
               final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
               core::bool* :is_sync = false;
               FutureOr<dynamic>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.expect b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.expect
index 1f4c1bb..e2e0194 100644
--- a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.expect
@@ -261,7 +261,7 @@
         break #L1;
       }
   }
-  function local() → FutureOr<self::A> async {
+  function local() → FutureOr<self::A> async /* futureValueType= self::A */ {
     if(true) {
       return invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:43:14: Error: A value of type 'B?' can't be returned from an async function with return type 'FutureOr<A>' because 'B?' is nullable and 'FutureOr<A>' isn't.
  - 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
@@ -364,7 +364,7 @@
     return null; // Error.
            ^" in null as{TypeError,ForNonNullableByDefault} self::A;
   }
-  function local() → FutureOr<self::A> async {
+  function local() → FutureOr<self::A> async /* futureValueType= self::A */ {
     if(true) {
       return invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:77:14: Error: The value 'null' can't be returned from an async function with return type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
diff --git a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect
index 2b23c4c..1bb1cc7 100644
--- a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect
@@ -272,7 +272,7 @@
         break #L1;
       }
   }
-  function local() → FutureOr<self::A> /* originally async */ {
+  function local() → FutureOr<self::A> /* futureValueType= self::A */ /* originally async */ {
     final asy::_Future<self::A> :async_future = new asy::_Future::•<self::A>();
     core::bool* :is_sync = false;
     FutureOr<self::A>? :return_value;
@@ -406,7 +406,7 @@
     return null; // Error.
            ^" in let Null #t15 = null in #t15 == null ?{self::A} #t15 as{TypeError,ForNonNullableByDefault} self::A : #t15{self::A};
   }
-  function local() → FutureOr<self::A> /* originally async */ {
+  function local() → FutureOr<self::A> /* futureValueType= self::A */ /* originally async */ {
     final asy::_Future<self::A> :async_future = new asy::_Future::•<self::A>();
     core::bool* :is_sync = false;
     FutureOr<self::A>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.expect b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.expect
index 1f4c1bb..e2e0194 100644
--- a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.expect
@@ -261,7 +261,7 @@
         break #L1;
       }
   }
-  function local() → FutureOr<self::A> async {
+  function local() → FutureOr<self::A> async /* futureValueType= self::A */ {
     if(true) {
       return invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:43:14: Error: A value of type 'B?' can't be returned from an async function with return type 'FutureOr<A>' because 'B?' is nullable and 'FutureOr<A>' isn't.
  - 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
@@ -364,7 +364,7 @@
     return null; // Error.
            ^" in null as{TypeError,ForNonNullableByDefault} self::A;
   }
-  function local() → FutureOr<self::A> async {
+  function local() → FutureOr<self::A> async /* futureValueType= self::A */ {
     if(true) {
       return invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:77:14: Error: The value 'null' can't be returned from an async function with return type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
diff --git a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.modular.expect
index 1f4c1bb..e2e0194 100644
--- a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.modular.expect
@@ -261,7 +261,7 @@
         break #L1;
       }
   }
-  function local() → FutureOr<self::A> async {
+  function local() → FutureOr<self::A> async /* futureValueType= self::A */ {
     if(true) {
       return invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:43:14: Error: A value of type 'B?' can't be returned from an async function with return type 'FutureOr<A>' because 'B?' is nullable and 'FutureOr<A>' isn't.
  - 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
@@ -364,7 +364,7 @@
     return null; // Error.
            ^" in null as{TypeError,ForNonNullableByDefault} self::A;
   }
-  function local() → FutureOr<self::A> async {
+  function local() → FutureOr<self::A> async /* futureValueType= self::A */ {
     if(true) {
       return invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:77:14: Error: The value 'null' can't be returned from an async function with return type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
  - 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
diff --git a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.transformed.expect
index 90f48aa..2268408 100644
--- a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.transformed.expect
@@ -272,7 +272,7 @@
         break #L1;
       }
   }
-  function local() → FutureOr<self::A> /* originally async */ {
+  function local() → FutureOr<self::A> /* futureValueType= self::A */ /* originally async */ {
     final asy::_Future<self::A> :async_future = new asy::_Future::•<self::A>();
     core::bool* :is_sync = false;
     FutureOr<self::A>? :return_value;
@@ -406,7 +406,7 @@
     return null; // Error.
            ^" in null;
   }
-  function local() → FutureOr<self::A> /* originally async */ {
+  function local() → FutureOr<self::A> /* futureValueType= self::A */ /* originally async */ {
     final asy::_Future<self::A> :async_future = new asy::_Future::•<self::A>();
     core::bool* :is_sync = false;
     FutureOr<self::A>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.expect b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.expect
index 5ed98d4..9026d7f 100644
--- a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.expect
@@ -4,7 +4,7 @@
 import "dart:async" as asy;
 
 abstract class TestMixin<R extends core::Object? = dynamic, T extends core::Object? = dynamic> extends core::Object /*isMixinDeclaration*/  {
-  method test(covariant-by-class asy::Future<self::TestMixin::R%> fetch) → asy::Future<self::TestMixin::T%> async {
+  method test(covariant-by-class asy::Future<self::TestMixin::R%> fetch) → asy::Future<self::TestMixin::T%> async /* futureValueType= self::TestMixin::T% */ {
     final self::TestMixin::R% response = await fetch;
     self::TestMixin::T% result;
     if(response is{ForNonNullableByDefault} self::Response<dynamic>) {
diff --git a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.transformed.expect
index 2c07b45..dd7aa66 100644
--- a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.transformed.expect
@@ -5,7 +5,7 @@
 import "dart:_internal" as _in;
 
 abstract class TestMixin<R extends core::Object? = dynamic, T extends core::Object? = dynamic> extends core::Object /*isMixinDeclaration*/  {
-  method test(covariant-by-class asy::Future<self::TestMixin::R%> fetch) → asy::Future<self::TestMixin::T%> /* originally async */ {
+  method test(covariant-by-class asy::Future<self::TestMixin::R%> fetch) → asy::Future<self::TestMixin::T%> /* futureValueType= self::TestMixin::T% */ /* originally async */ {
     final asy::_Future<self::TestMixin::T%> :async_future = new asy::_Future::•<self::TestMixin::T%>();
     core::bool* :is_sync = false;
     FutureOr<self::TestMixin::T%>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.expect b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.expect
index 5ed98d4..9026d7f 100644
--- a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.expect
@@ -4,7 +4,7 @@
 import "dart:async" as asy;
 
 abstract class TestMixin<R extends core::Object? = dynamic, T extends core::Object? = dynamic> extends core::Object /*isMixinDeclaration*/  {
-  method test(covariant-by-class asy::Future<self::TestMixin::R%> fetch) → asy::Future<self::TestMixin::T%> async {
+  method test(covariant-by-class asy::Future<self::TestMixin::R%> fetch) → asy::Future<self::TestMixin::T%> async /* futureValueType= self::TestMixin::T% */ {
     final self::TestMixin::R% response = await fetch;
     self::TestMixin::T% result;
     if(response is{ForNonNullableByDefault} self::Response<dynamic>) {
diff --git a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.modular.expect
index 5ed98d4..9026d7f 100644
--- a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.modular.expect
@@ -4,7 +4,7 @@
 import "dart:async" as asy;
 
 abstract class TestMixin<R extends core::Object? = dynamic, T extends core::Object? = dynamic> extends core::Object /*isMixinDeclaration*/  {
-  method test(covariant-by-class asy::Future<self::TestMixin::R%> fetch) → asy::Future<self::TestMixin::T%> async {
+  method test(covariant-by-class asy::Future<self::TestMixin::R%> fetch) → asy::Future<self::TestMixin::T%> async /* futureValueType= self::TestMixin::T% */ {
     final self::TestMixin::R% response = await fetch;
     self::TestMixin::T% result;
     if(response is{ForNonNullableByDefault} self::Response<dynamic>) {
diff --git a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.transformed.expect
index 2c07b45..dd7aa66 100644
--- a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.transformed.expect
@@ -5,7 +5,7 @@
 import "dart:_internal" as _in;
 
 abstract class TestMixin<R extends core::Object? = dynamic, T extends core::Object? = dynamic> extends core::Object /*isMixinDeclaration*/  {
-  method test(covariant-by-class asy::Future<self::TestMixin::R%> fetch) → asy::Future<self::TestMixin::T%> /* originally async */ {
+  method test(covariant-by-class asy::Future<self::TestMixin::R%> fetch) → asy::Future<self::TestMixin::T%> /* futureValueType= self::TestMixin::T% */ /* originally async */ {
     final asy::_Future<self::TestMixin::T%> :async_future = new asy::_Future::•<self::TestMixin::T%>();
     core::bool* :is_sync = false;
     FutureOr<self::TestMixin::T%>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41108.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41108.dart.strong.expect
index 3874c5a..cfff8d6 100644
--- a/pkg/front_end/testcases/nnbd/issue41108.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41108.dart.strong.expect
@@ -11,7 +11,7 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   core::List<dynamic> y = invalid-expression "pkg/front_end/testcases/nnbd/issue41108.dart:6:12: Error: A value of type 'List<dynamic>?' can't be assigned to a variable of type 'List<dynamic>' because 'List<dynamic>?' is nullable and 'List<dynamic>' isn't.
  - 'List' is from 'dart:core'.
   List y = await l(); // should be a List?
diff --git a/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect
index 3911f56..b0a1eca 100644
--- a/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect
@@ -12,7 +12,7 @@
 import "dart:core" as core;
 import "dart:_internal" as _in;
 
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41108.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41108.dart.weak.expect
index 3874c5a..cfff8d6 100644
--- a/pkg/front_end/testcases/nnbd/issue41108.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41108.dart.weak.expect
@@ -11,7 +11,7 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   core::List<dynamic> y = invalid-expression "pkg/front_end/testcases/nnbd/issue41108.dart:6:12: Error: A value of type 'List<dynamic>?' can't be assigned to a variable of type 'List<dynamic>' because 'List<dynamic>?' is nullable and 'List<dynamic>' isn't.
  - 'List' is from 'dart:core'.
   List y = await l(); // should be a List?
diff --git a/pkg/front_end/testcases/nnbd/issue41108.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue41108.dart.weak.modular.expect
index 3874c5a..cfff8d6 100644
--- a/pkg/front_end/testcases/nnbd/issue41108.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue41108.dart.weak.modular.expect
@@ -11,7 +11,7 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   core::List<dynamic> y = invalid-expression "pkg/front_end/testcases/nnbd/issue41108.dart:6:12: Error: A value of type 'List<dynamic>?' can't be assigned to a variable of type 'List<dynamic>' because 'List<dynamic>?' is nullable and 'List<dynamic>' isn't.
  - 'List' is from 'dart:core'.
   List y = await l(); // should be a List?
diff --git a/pkg/front_end/testcases/nnbd/issue41108.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41108.dart.weak.transformed.expect
index c8d68d4..af4fa89 100644
--- a/pkg/front_end/testcases/nnbd/issue41108.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41108.dart.weak.transformed.expect
@@ -12,7 +12,7 @@
 import "dart:core" as core;
 import "dart:_internal" as _in;
 
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.strong.expect
index 467d91a..b7109c8 100644
--- a/pkg/front_end/testcases/nnbd/issue41114.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.strong.expect
@@ -2,7 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   core::List<core::String>? a = <core::String>[] as{ForNonNullableByDefault} core::List<core::String>?;
   core::Iterable<core::String>? b = let final core::List<core::String>? #t1 = a in #t1 == null ?{core::Iterable<core::String>?} null : #t1{core::List<core::String>}.{core::Iterable::map}<core::String>((core::String e) → core::String => e){((core::String) → core::String) → core::Iterable<core::String>};
   core::Iterable<core::String>? i = let final core::Iterable<core::String>? #t2 = b in #t2 == null ?{core::Iterable<core::String>?} a : #t2{core::Iterable<core::String>};
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.strong.transformed.expect
index 5a8290a..b91c2a7 100644
--- a/pkg/front_end/testcases/nnbd/issue41114.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.strong.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.weak.expect
index 467d91a..b7109c8 100644
--- a/pkg/front_end/testcases/nnbd/issue41114.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.weak.expect
@@ -2,7 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   core::List<core::String>? a = <core::String>[] as{ForNonNullableByDefault} core::List<core::String>?;
   core::Iterable<core::String>? b = let final core::List<core::String>? #t1 = a in #t1 == null ?{core::Iterable<core::String>?} null : #t1{core::List<core::String>}.{core::Iterable::map}<core::String>((core::String e) → core::String => e){((core::String) → core::String) → core::Iterable<core::String>};
   core::Iterable<core::String>? i = let final core::Iterable<core::String>? #t2 = b in #t2 == null ?{core::Iterable<core::String>?} a : #t2{core::Iterable<core::String>};
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.weak.modular.expect
index 467d91a..b7109c8 100644
--- a/pkg/front_end/testcases/nnbd/issue41114.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.weak.modular.expect
@@ -2,7 +2,7 @@
 import self as self;
 import "dart:core" as core;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   core::List<core::String>? a = <core::String>[] as{ForNonNullableByDefault} core::List<core::String>?;
   core::Iterable<core::String>? b = let final core::List<core::String>? #t1 = a in #t1 == null ?{core::Iterable<core::String>?} null : #t1{core::List<core::String>}.{core::Iterable::map}<core::String>((core::String e) → core::String => e){((core::String) → core::String) → core::Iterable<core::String>};
   core::Iterable<core::String>? i = let final core::Iterable<core::String>? #t2 = b in #t2 == null ?{core::Iterable<core::String>?} a : #t2{core::Iterable<core::String>};
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.weak.transformed.expect
index 5a8290a..b91c2a7 100644
--- a/pkg/front_end/testcases/nnbd/issue41114.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.weak.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.strong.expect
index 5fca931..fad7dab 100644
--- a/pkg/front_end/testcases/nnbd/issue41156.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.strong.expect
@@ -55,22 +55,22 @@
   (core::int) → core::String x6 = (core::int v) → Never {
     return self::throwing();
   };
-  (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> async => throw v;
-  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> async {
+  (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ => throw v;
+  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ {
     throw v;
   };
-  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> async {
+  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ {
     return throw v;
   };
-  (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> async => self::throwing();
-  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> async {
+  (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ => self::throwing();
+  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ {
     self::throwing();
   };
-  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> async {
+  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ {
     return self::throwing();
   };
 }
-static method errors() → void async {
+static method errors() → void async /* futureValueType= void */ {
   (core::int) → core::String x2 = (core::int v) → core::String {
     try {
       throw v;
@@ -111,7 +111,7 @@
   String Function(int) x6 = (int v) /* error */ {
                             ^" in null;
   };
-  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<core::String> async {
+  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<core::String> async /* futureValueType= core::String */ {
     try {
       throw v;
     }
@@ -121,7 +121,7 @@
   Future<String> Function(int) y2 = (int v) async /* error */ {
                                     ^" in null;
   };
-  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<core::String> async {
+  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<core::String> async /* futureValueType= core::String */ {
     try {
       return throw v;
     }
@@ -131,7 +131,7 @@
   Future<String> Function(int) y3 = (int v) async /* error */ {
                                     ^" in null;
   };
-  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<core::String> async {
+  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<core::String> async /* futureValueType= core::String */ {
     try {
       self::throwing();
     }
@@ -141,7 +141,7 @@
   Future<String> Function(int) y5 = (int v) async /* error */ {
                                     ^" in null;
   };
-  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<core::String> async {
+  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<core::String> async /* futureValueType= core::String */ {
     try {
       return self::throwing();
     }
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect
index 8190be5..38b54a6 100644
--- a/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect
@@ -55,7 +55,7 @@
   (core::int) → core::String x6 = (core::int v) → Never {
     return self::throwing();
   };
-  (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> /* originally async */ {
+  (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> /* futureValueType= Never */ /* originally async */ {
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
@@ -82,7 +82,7 @@
     :is_sync = true;
     return :async_future;
   };
-  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> /* originally async */ {
+  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> /* futureValueType= Never */ /* originally async */ {
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     Never? :return_value;
@@ -108,7 +108,7 @@
     :is_sync = true;
     return :async_future;
   };
-  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> /* originally async */ {
+  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> /* futureValueType= Never */ /* originally async */ {
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
@@ -135,7 +135,7 @@
     :is_sync = true;
     return :async_future;
   };
-  (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> /* originally async */ {
+  (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> /* futureValueType= Never */ /* originally async */ {
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
@@ -162,7 +162,7 @@
     :is_sync = true;
     return :async_future;
   };
-  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> /* originally async */ {
+  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> /* futureValueType= Never */ /* originally async */ {
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     Never? :return_value;
@@ -188,7 +188,7 @@
     :is_sync = true;
     return :async_future;
   };
-  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> /* originally async */ {
+  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> /* futureValueType= Never */ /* originally async */ {
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
@@ -216,7 +216,7 @@
     return :async_future;
   };
 }
-static method errors() → void /* originally async */ {
+static method errors() → void /* futureValueType= void */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -268,7 +268,7 @@
   String Function(int) x6 = (int v) /* error */ {
                             ^" in null;
         };
-        (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<core::String> /* originally async */ {
+        (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<core::String> /* futureValueType= core::String */ /* originally async */ {
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
@@ -302,7 +302,7 @@
           :is_sync = true;
           return :async_future;
         };
-        (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<core::String> /* originally async */ {
+        (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<core::String> /* futureValueType= core::String */ /* originally async */ {
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
@@ -337,7 +337,7 @@
           :is_sync = true;
           return :async_future;
         };
-        (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<core::String> /* originally async */ {
+        (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<core::String> /* futureValueType= core::String */ /* originally async */ {
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
@@ -371,7 +371,7 @@
           :is_sync = true;
           return :async_future;
         };
-        (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<core::String> /* originally async */ {
+        (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<core::String> /* futureValueType= core::String */ /* originally async */ {
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.expect
index 9940f1b..f8ca0c2 100644
--- a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.expect
@@ -56,22 +56,22 @@
   (core::int) → core::String x6 = (core::int v) → Never {
     return let final Never #t3 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
   };
-  (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> async => throw v;
-  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> async {
+  (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ => throw v;
+  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ {
     throw v;
   };
-  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> async {
+  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ {
     return throw v;
   };
-  (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> async => let final Never #t4 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> async {
+  (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ => let final Never #t4 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ {
     let final Never #t5 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
   };
-  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> async {
+  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ {
     return let final Never #t6 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
   };
 }
-static method errors() → void async {
+static method errors() → void async /* futureValueType= void */ {
   (core::int) → core::String x2 = (core::int v) → core::String {
     try {
       throw v;
@@ -112,7 +112,7 @@
   String Function(int) x6 = (int v) /* error */ {
                             ^" in null;
   };
-  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<core::String> async {
+  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<core::String> async /* futureValueType= core::String */ {
     try {
       throw v;
     }
@@ -122,7 +122,7 @@
   Future<String> Function(int) y2 = (int v) async /* error */ {
                                     ^" in null;
   };
-  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<core::String> async {
+  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<core::String> async /* futureValueType= core::String */ {
     try {
       return throw v;
     }
@@ -132,7 +132,7 @@
   Future<String> Function(int) y3 = (int v) async /* error */ {
                                     ^" in null;
   };
-  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<core::String> async {
+  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<core::String> async /* futureValueType= core::String */ {
     try {
       let final Never #t9 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
     }
@@ -142,7 +142,7 @@
   Future<String> Function(int) y5 = (int v) async /* error */ {
                                     ^" in null;
   };
-  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<core::String> async {
+  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<core::String> async /* futureValueType= core::String */ {
     try {
       return let final Never #t10 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
     }
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.modular.expect
index 9940f1b..f8ca0c2 100644
--- a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.modular.expect
@@ -56,22 +56,22 @@
   (core::int) → core::String x6 = (core::int v) → Never {
     return let final Never #t3 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
   };
-  (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> async => throw v;
-  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> async {
+  (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ => throw v;
+  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ {
     throw v;
   };
-  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> async {
+  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ {
     return throw v;
   };
-  (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> async => let final Never #t4 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
-  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> async {
+  (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ => let final Never #t4 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ {
     let final Never #t5 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
   };
-  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> async {
+  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> async /* futureValueType= Never */ {
     return let final Never #t6 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
   };
 }
-static method errors() → void async {
+static method errors() → void async /* futureValueType= void */ {
   (core::int) → core::String x2 = (core::int v) → core::String {
     try {
       throw v;
@@ -112,7 +112,7 @@
   String Function(int) x6 = (int v) /* error */ {
                             ^" in null;
   };
-  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<core::String> async {
+  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<core::String> async /* futureValueType= core::String */ {
     try {
       throw v;
     }
@@ -122,7 +122,7 @@
   Future<String> Function(int) y2 = (int v) async /* error */ {
                                     ^" in null;
   };
-  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<core::String> async {
+  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<core::String> async /* futureValueType= core::String */ {
     try {
       return throw v;
     }
@@ -132,7 +132,7 @@
   Future<String> Function(int) y3 = (int v) async /* error */ {
                                     ^" in null;
   };
-  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<core::String> async {
+  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<core::String> async /* futureValueType= core::String */ {
     try {
       let final Never #t9 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
     }
@@ -142,7 +142,7 @@
   Future<String> Function(int) y5 = (int v) async /* error */ {
                                     ^" in null;
   };
-  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<core::String> async {
+  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<core::String> async /* futureValueType= core::String */ {
     try {
       return let final Never #t10 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
     }
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect
index 69eb4d9..c6419e0 100644
--- a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect
@@ -56,7 +56,7 @@
   (core::int) → core::String x6 = (core::int v) → Never {
     return let final Never #t3 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
   };
-  (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> /* originally async */ {
+  (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> /* futureValueType= Never */ /* originally async */ {
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
@@ -83,7 +83,7 @@
     :is_sync = true;
     return :async_future;
   };
-  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> /* originally async */ {
+  (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> /* futureValueType= Never */ /* originally async */ {
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     Never? :return_value;
@@ -109,7 +109,7 @@
     :is_sync = true;
     return :async_future;
   };
-  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> /* originally async */ {
+  (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> /* futureValueType= Never */ /* originally async */ {
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
@@ -136,7 +136,7 @@
     :is_sync = true;
     return :async_future;
   };
-  (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> /* originally async */ {
+  (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> /* futureValueType= Never */ /* originally async */ {
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
@@ -163,7 +163,7 @@
     :is_sync = true;
     return :async_future;
   };
-  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> /* originally async */ {
+  (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> /* futureValueType= Never */ /* originally async */ {
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     Never? :return_value;
@@ -189,7 +189,7 @@
     :is_sync = true;
     return :async_future;
   };
-  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> /* originally async */ {
+  (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> /* futureValueType= Never */ /* originally async */ {
     final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
     core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
@@ -217,7 +217,7 @@
     return :async_future;
   };
 }
-static method errors() → void /* originally async */ {
+static method errors() → void /* futureValueType= void */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -269,7 +269,7 @@
   String Function(int) x6 = (int v) /* error */ {
                             ^" in null;
         };
-        (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<core::String> /* originally async */ {
+        (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<core::String> /* futureValueType= core::String */ /* originally async */ {
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
@@ -303,7 +303,7 @@
           :is_sync = true;
           return :async_future;
         };
-        (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<core::String> /* originally async */ {
+        (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<core::String> /* futureValueType= core::String */ /* originally async */ {
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
@@ -338,7 +338,7 @@
           :is_sync = true;
           return :async_future;
         };
-        (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<core::String> /* originally async */ {
+        (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<core::String> /* futureValueType= core::String */ /* originally async */ {
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
@@ -372,7 +372,7 @@
           :is_sync = true;
           return :async_future;
         };
-        (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<core::String> /* originally async */ {
+        (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<core::String> /* futureValueType= core::String */ /* originally async */ {
           final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
           core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.expect
index 6b82704..030ca78 100644
--- a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.expect
@@ -33,19 +33,19 @@
 
 static method getNull() → dynamic
   return null;
-static method getFutureNull() → asy::Future<dynamic> async {
+static method getFutureNull() → asy::Future<dynamic> async /* futureValueType= dynamic */ {
   return null;
 }
-static method getFutureBool() → asy::Future<core::bool> async {
+static method getFutureBool() → asy::Future<core::bool> async /* futureValueType= core::bool */ {
   return true;
 }
-static method test1() → asy::Future<core::bool> async 
+static method test1() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
   return await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
 static method test2() → asy::Future<core::bool>
   return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
 static method test3() → core::bool
   return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
-static method test4() → asy::Future<core::bool> async 
+static method test4() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
   return await self::getFutureNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
 static method test5() → asy::Future<core::bool>
   return invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be returned from a function with return type 'Future<bool>'.
@@ -54,16 +54,16 @@
                         ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
 static method test6() → asy::Future<core::bool>
   return self::getFutureBool();
-static method test7() → asy::Future<core::bool> async 
+static method test7() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
   return self::getFutureBool();
-static method test() → dynamic async {
-  function test1() → asy::Future<core::bool> async 
+static method test() → dynamic async /* futureValueType= dynamic */ {
+  function test1() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
     return await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
   function test2() → asy::Future<core::bool>
     return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
   function test3() → core::bool
     return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
-  function test4() → asy::Future<core::bool> async 
+  function test4() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
     return await self::getFutureNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
   function test5() → asy::Future<core::bool>
     return invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be returned from a function with return type 'Future<bool>'.
@@ -72,23 +72,23 @@
                           ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
   function test6() → asy::Future<core::bool>
     return self::getFutureBool();
-  function test7() → asy::Future<core::bool> async 
+  function test7() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
     return self::getFutureBool();
   asy::Future<core::bool> var1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
   Future<bool> var1 = (() async => await getNull())(); // error
-                                                   ^" in (() → asy::Future<dynamic> async => await self::getNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+                                                   ^" in (() → asy::Future<dynamic> async /* futureValueType= dynamic */ => await self::getNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
   asy::Future<core::bool> var2 = (() → dynamic => self::getNull())(){() → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
   core::bool var3 = (() → dynamic => self::getNull())(){() → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
   asy::Future<core::bool> var4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
   Future<bool> var4 = (() async => await getFutureNull())(); // error
-                                                         ^" in (() → asy::Future<dynamic> async => await self::getFutureNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+                                                         ^" in (() → asy::Future<dynamic> async /* futureValueType= dynamic */ => await self::getFutureNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
   asy::Future<core::bool> var5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
   Future<bool> var5 = (() => getFutureNull())(); // error
                                              ^" in (() → asy::Future<dynamic> => self::getFutureNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
   asy::Future<core::bool> var6 = (() → asy::Future<core::bool> => self::getFutureBool())(){() → asy::Future<core::bool>};
-  asy::Future<core::bool> var7 = (() → asy::Future<core::bool> async => self::getFutureBool())(){() → asy::Future<core::bool>};
+  asy::Future<core::bool> var7 = (() → asy::Future<core::bool> async /* futureValueType= core::bool */ => self::getFutureBool())(){() → asy::Future<core::bool>};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
index 6e2c362..5c6560a 100644
--- a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
@@ -33,7 +33,7 @@
 
 static method getNull() → dynamic
   return null;
-static method getFutureNull() → asy::Future<dynamic> /* originally async */ {
+static method getFutureNull() → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
@@ -60,7 +60,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method getFutureBool() → asy::Future<core::bool> /* originally async */ {
+static method getFutureBool() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   core::bool? :return_value;
@@ -87,7 +87,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method test1() → asy::Future<core::bool> /* originally async */ {
+static method test1() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
@@ -120,7 +120,7 @@
   return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
 static method test3() → core::bool
   return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
-static method test4() → asy::Future<core::bool> /* originally async */ {
+static method test4() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
@@ -156,7 +156,7 @@
                         ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
 static method test6() → asy::Future<core::bool>
   return self::getFutureBool();
-static method test7() → asy::Future<core::bool> /* originally async */ {
+static method test7() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
@@ -183,7 +183,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -195,7 +195,7 @@
     try {
       #L6:
       {
-        function test1() → asy::Future<core::bool> /* originally async */ {
+        function test1() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
@@ -228,7 +228,7 @@
           return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
         function test3() → core::bool
           return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
-        function test4() → asy::Future<core::bool> /* originally async */ {
+        function test4() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
@@ -264,7 +264,7 @@
                           ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
         function test6() → asy::Future<core::bool>
           return self::getFutureBool();
-        function test7() → asy::Future<core::bool> /* originally async */ {
+        function test7() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
@@ -294,7 +294,7 @@
         asy::Future<core::bool> var1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
   Future<bool> var1 = (() async => await getNull())(); // error
-                                                   ^" in (() → asy::Future<dynamic> /* originally async */ {
+                                                   ^" in (() → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
           final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
           core::bool* :is_sync = false;
           FutureOr<dynamic>? :return_value;
@@ -328,7 +328,7 @@
         asy::Future<core::bool> var4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
   Future<bool> var4 = (() async => await getFutureNull())(); // error
-                                                         ^" in (() → asy::Future<dynamic> /* originally async */ {
+                                                         ^" in (() → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
           final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
           core::bool* :is_sync = false;
           FutureOr<dynamic>? :return_value;
@@ -362,7 +362,7 @@
   Future<bool> var5 = (() => getFutureNull())(); // error
                                              ^" in (() → asy::Future<dynamic> => self::getFutureNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
         asy::Future<core::bool> var6 = (() → asy::Future<core::bool> => self::getFutureBool())(){() → asy::Future<core::bool>};
-        asy::Future<core::bool> var7 = (() → asy::Future<core::bool> /* originally async */ {
+        asy::Future<core::bool> var7 = (() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.expect
index 6b82704..030ca78 100644
--- a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.expect
@@ -33,19 +33,19 @@
 
 static method getNull() → dynamic
   return null;
-static method getFutureNull() → asy::Future<dynamic> async {
+static method getFutureNull() → asy::Future<dynamic> async /* futureValueType= dynamic */ {
   return null;
 }
-static method getFutureBool() → asy::Future<core::bool> async {
+static method getFutureBool() → asy::Future<core::bool> async /* futureValueType= core::bool */ {
   return true;
 }
-static method test1() → asy::Future<core::bool> async 
+static method test1() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
   return await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
 static method test2() → asy::Future<core::bool>
   return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
 static method test3() → core::bool
   return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
-static method test4() → asy::Future<core::bool> async 
+static method test4() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
   return await self::getFutureNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
 static method test5() → asy::Future<core::bool>
   return invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be returned from a function with return type 'Future<bool>'.
@@ -54,16 +54,16 @@
                         ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
 static method test6() → asy::Future<core::bool>
   return self::getFutureBool();
-static method test7() → asy::Future<core::bool> async 
+static method test7() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
   return self::getFutureBool();
-static method test() → dynamic async {
-  function test1() → asy::Future<core::bool> async 
+static method test() → dynamic async /* futureValueType= dynamic */ {
+  function test1() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
     return await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
   function test2() → asy::Future<core::bool>
     return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
   function test3() → core::bool
     return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
-  function test4() → asy::Future<core::bool> async 
+  function test4() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
     return await self::getFutureNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
   function test5() → asy::Future<core::bool>
     return invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be returned from a function with return type 'Future<bool>'.
@@ -72,23 +72,23 @@
                           ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
   function test6() → asy::Future<core::bool>
     return self::getFutureBool();
-  function test7() → asy::Future<core::bool> async 
+  function test7() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
     return self::getFutureBool();
   asy::Future<core::bool> var1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
   Future<bool> var1 = (() async => await getNull())(); // error
-                                                   ^" in (() → asy::Future<dynamic> async => await self::getNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+                                                   ^" in (() → asy::Future<dynamic> async /* futureValueType= dynamic */ => await self::getNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
   asy::Future<core::bool> var2 = (() → dynamic => self::getNull())(){() → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
   core::bool var3 = (() → dynamic => self::getNull())(){() → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
   asy::Future<core::bool> var4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
   Future<bool> var4 = (() async => await getFutureNull())(); // error
-                                                         ^" in (() → asy::Future<dynamic> async => await self::getFutureNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+                                                         ^" in (() → asy::Future<dynamic> async /* futureValueType= dynamic */ => await self::getFutureNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
   asy::Future<core::bool> var5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
   Future<bool> var5 = (() => getFutureNull())(); // error
                                              ^" in (() → asy::Future<dynamic> => self::getFutureNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
   asy::Future<core::bool> var6 = (() → asy::Future<core::bool> => self::getFutureBool())(){() → asy::Future<core::bool>};
-  asy::Future<core::bool> var7 = (() → asy::Future<core::bool> async => self::getFutureBool())(){() → asy::Future<core::bool>};
+  asy::Future<core::bool> var7 = (() → asy::Future<core::bool> async /* futureValueType= core::bool */ => self::getFutureBool())(){() → asy::Future<core::bool>};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.modular.expect
index 6b82704..030ca78 100644
--- a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.modular.expect
@@ -33,19 +33,19 @@
 
 static method getNull() → dynamic
   return null;
-static method getFutureNull() → asy::Future<dynamic> async {
+static method getFutureNull() → asy::Future<dynamic> async /* futureValueType= dynamic */ {
   return null;
 }
-static method getFutureBool() → asy::Future<core::bool> async {
+static method getFutureBool() → asy::Future<core::bool> async /* futureValueType= core::bool */ {
   return true;
 }
-static method test1() → asy::Future<core::bool> async 
+static method test1() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
   return await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
 static method test2() → asy::Future<core::bool>
   return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
 static method test3() → core::bool
   return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
-static method test4() → asy::Future<core::bool> async 
+static method test4() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
   return await self::getFutureNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
 static method test5() → asy::Future<core::bool>
   return invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be returned from a function with return type 'Future<bool>'.
@@ -54,16 +54,16 @@
                         ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
 static method test6() → asy::Future<core::bool>
   return self::getFutureBool();
-static method test7() → asy::Future<core::bool> async 
+static method test7() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
   return self::getFutureBool();
-static method test() → dynamic async {
-  function test1() → asy::Future<core::bool> async 
+static method test() → dynamic async /* futureValueType= dynamic */ {
+  function test1() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
     return await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
   function test2() → asy::Future<core::bool>
     return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
   function test3() → core::bool
     return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
-  function test4() → asy::Future<core::bool> async 
+  function test4() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
     return await self::getFutureNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
   function test5() → asy::Future<core::bool>
     return invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be returned from a function with return type 'Future<bool>'.
@@ -72,23 +72,23 @@
                           ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
   function test6() → asy::Future<core::bool>
     return self::getFutureBool();
-  function test7() → asy::Future<core::bool> async 
+  function test7() → asy::Future<core::bool> async /* futureValueType= core::bool */ 
     return self::getFutureBool();
   asy::Future<core::bool> var1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
   Future<bool> var1 = (() async => await getNull())(); // error
-                                                   ^" in (() → asy::Future<dynamic> async => await self::getNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+                                                   ^" in (() → asy::Future<dynamic> async /* futureValueType= dynamic */ => await self::getNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
   asy::Future<core::bool> var2 = (() → dynamic => self::getNull())(){() → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
   core::bool var3 = (() → dynamic => self::getNull())(){() → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
   asy::Future<core::bool> var4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
   Future<bool> var4 = (() async => await getFutureNull())(); // error
-                                                         ^" in (() → asy::Future<dynamic> async => await self::getFutureNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+                                                         ^" in (() → asy::Future<dynamic> async /* futureValueType= dynamic */ => await self::getFutureNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
   asy::Future<core::bool> var5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
   Future<bool> var5 = (() => getFutureNull())(); // error
                                              ^" in (() → asy::Future<dynamic> => self::getFutureNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
   asy::Future<core::bool> var6 = (() → asy::Future<core::bool> => self::getFutureBool())(){() → asy::Future<core::bool>};
-  asy::Future<core::bool> var7 = (() → asy::Future<core::bool> async => self::getFutureBool())(){() → asy::Future<core::bool>};
+  asy::Future<core::bool> var7 = (() → asy::Future<core::bool> async /* futureValueType= core::bool */ => self::getFutureBool())(){() → asy::Future<core::bool>};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect
index 6e2c362..5c6560a 100644
--- a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect
@@ -33,7 +33,7 @@
 
 static method getNull() → dynamic
   return null;
-static method getFutureNull() → asy::Future<dynamic> /* originally async */ {
+static method getFutureNull() → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
@@ -60,7 +60,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method getFutureBool() → asy::Future<core::bool> /* originally async */ {
+static method getFutureBool() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   core::bool? :return_value;
@@ -87,7 +87,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method test1() → asy::Future<core::bool> /* originally async */ {
+static method test1() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
@@ -120,7 +120,7 @@
   return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
 static method test3() → core::bool
   return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
-static method test4() → asy::Future<core::bool> /* originally async */ {
+static method test4() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
@@ -156,7 +156,7 @@
                         ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
 static method test6() → asy::Future<core::bool>
   return self::getFutureBool();
-static method test7() → asy::Future<core::bool> /* originally async */ {
+static method test7() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
   final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
   core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
@@ -183,7 +183,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -195,7 +195,7 @@
     try {
       #L6:
       {
-        function test1() → asy::Future<core::bool> /* originally async */ {
+        function test1() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
@@ -228,7 +228,7 @@
           return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
         function test3() → core::bool
           return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
-        function test4() → asy::Future<core::bool> /* originally async */ {
+        function test4() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
@@ -264,7 +264,7 @@
                           ^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
         function test6() → asy::Future<core::bool>
           return self::getFutureBool();
-        function test7() → asy::Future<core::bool> /* originally async */ {
+        function test7() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
@@ -294,7 +294,7 @@
         asy::Future<core::bool> var1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
   Future<bool> var1 = (() async => await getNull())(); // error
-                                                   ^" in (() → asy::Future<dynamic> /* originally async */ {
+                                                   ^" in (() → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
           final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
           core::bool* :is_sync = false;
           FutureOr<dynamic>? :return_value;
@@ -328,7 +328,7 @@
         asy::Future<core::bool> var4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
   Future<bool> var4 = (() async => await getFutureNull())(); // error
-                                                         ^" in (() → asy::Future<dynamic> /* originally async */ {
+                                                         ^" in (() → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
           final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
           core::bool* :is_sync = false;
           FutureOr<dynamic>? :return_value;
@@ -362,7 +362,7 @@
   Future<bool> var5 = (() => getFutureNull())(); // error
                                              ^" in (() → asy::Future<dynamic> => self::getFutureNull())(){() → asy::Future<dynamic>} as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
         asy::Future<core::bool> var6 = (() → asy::Future<core::bool> => self::getFutureBool())(){() → asy::Future<core::bool>};
-        asy::Future<core::bool> var7 = (() → asy::Future<core::bool> /* originally async */ {
+        asy::Future<core::bool> var7 = (() → asy::Future<core::bool> /* futureValueType= core::bool */ /* originally async */ {
           final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
           core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.expect
index 89bdcad..a8a9162 100644
--- a/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.expect
@@ -71,7 +71,7 @@
 static method test7() → core::Iterable<core::bool> sync* {
   yield* self::getIterableBool();
 }
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   function test1() → core::Iterable<core::bool> sync* {
     yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
   }
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
index 06df3f0..815faef 100644
--- a/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
@@ -142,7 +142,7 @@
   }
   return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
 }
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.expect
index 89bdcad..a8a9162 100644
--- a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.expect
@@ -71,7 +71,7 @@
 static method test7() → core::Iterable<core::bool> sync* {
   yield* self::getIterableBool();
 }
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   function test1() → core::Iterable<core::bool> sync* {
     yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
   }
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.modular.expect
index 89bdcad..a8a9162 100644
--- a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.modular.expect
@@ -71,7 +71,7 @@
 static method test7() → core::Iterable<core::bool> sync* {
   yield* self::getIterableBool();
 }
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   function test1() → core::Iterable<core::bool> sync* {
     yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
   }
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
index 06df3f0..815faef 100644
--- a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
@@ -142,7 +142,7 @@
   }
   return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
 }
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.expect
index 54bbc93..a6f6ba7 100644
--- a/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.expect
@@ -72,7 +72,7 @@
 static method test7() → asy::Stream<core::bool> async* {
   yield* self::getStreamBool();
 }
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   function test1() → asy::Stream<core::bool> async* {
     yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
   }
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
index ce8b32e..cfc0b05 100644
--- a/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
@@ -222,7 +222,7 @@
   :controller_stream = :controller.{asy::_AsyncStarStreamController::stream}{asy::Stream<core::bool>};
   return :controller_stream;
 }
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.expect
index 54bbc93..a6f6ba7 100644
--- a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.expect
@@ -72,7 +72,7 @@
 static method test7() → asy::Stream<core::bool> async* {
   yield* self::getStreamBool();
 }
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   function test1() → asy::Stream<core::bool> async* {
     yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
   }
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.modular.expect
index 54bbc93..a6f6ba7 100644
--- a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.modular.expect
@@ -72,7 +72,7 @@
 static method test7() → asy::Stream<core::bool> async* {
   yield* self::getStreamBool();
 }
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   function test1() → asy::Stream<core::bool> async* {
     yield self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
   }
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
index ce8b32e..cfc0b05 100644
--- a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
@@ -222,7 +222,7 @@
   :controller_stream = :controller.{asy::_AsyncStarStreamController::stream}{asy::Stream<core::bool>};
   return :controller_stream;
 }
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41602.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41602.dart.strong.expect
index d7d296d..bab6d364 100644
--- a/pkg/front_end/testcases/nnbd/issue41602.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41602.dart.strong.expect
@@ -13,13 +13,13 @@
 import self as self;
 import "dart:async" as asy;
 
-static method returnFutureOfVoid() → asy::Future<void> async {}
+static method returnFutureOfVoid() → asy::Future<void> async /* futureValueType= void */ {}
 static method returnVoid() → void {}
-static method returnVoidAsync() → void async {}
-static method test() → dynamic async {
+static method returnVoidAsync() → void async /* futureValueType= void */ {}
+static method test() → dynamic async /* futureValueType= dynamic */ {
   await self::returnVoid();
   await self::returnVoidAsync();
 }
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await self::returnFutureOfVoid();
 }
diff --git a/pkg/front_end/testcases/nnbd/issue41602.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41602.dart.strong.transformed.expect
index 675b14d..756e88b 100644
--- a/pkg/front_end/testcases/nnbd/issue41602.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41602.dart.strong.transformed.expect
@@ -15,7 +15,7 @@
 import "dart:core" as core;
 import "dart:_internal" as _in;
 
-static method returnFutureOfVoid() → asy::Future<void> /* originally async */ {
+static method returnFutureOfVoid() → asy::Future<void> /* futureValueType= void */ /* originally async */ {
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   void :return_value;
@@ -40,7 +40,7 @@
   return :async_future;
 }
 static method returnVoid() → void {}
-static method returnVoidAsync() → void /* originally async */ {
+static method returnVoidAsync() → void /* futureValueType= void */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -64,7 +64,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -94,7 +94,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41602.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41602.dart.weak.expect
index d7d296d..bab6d364 100644
--- a/pkg/front_end/testcases/nnbd/issue41602.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41602.dart.weak.expect
@@ -13,13 +13,13 @@
 import self as self;
 import "dart:async" as asy;
 
-static method returnFutureOfVoid() → asy::Future<void> async {}
+static method returnFutureOfVoid() → asy::Future<void> async /* futureValueType= void */ {}
 static method returnVoid() → void {}
-static method returnVoidAsync() → void async {}
-static method test() → dynamic async {
+static method returnVoidAsync() → void async /* futureValueType= void */ {}
+static method test() → dynamic async /* futureValueType= dynamic */ {
   await self::returnVoid();
   await self::returnVoidAsync();
 }
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await self::returnFutureOfVoid();
 }
diff --git a/pkg/front_end/testcases/nnbd/issue41602.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue41602.dart.weak.modular.expect
index d7d296d..bab6d364 100644
--- a/pkg/front_end/testcases/nnbd/issue41602.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue41602.dart.weak.modular.expect
@@ -13,13 +13,13 @@
 import self as self;
 import "dart:async" as asy;
 
-static method returnFutureOfVoid() → asy::Future<void> async {}
+static method returnFutureOfVoid() → asy::Future<void> async /* futureValueType= void */ {}
 static method returnVoid() → void {}
-static method returnVoidAsync() → void async {}
-static method test() → dynamic async {
+static method returnVoidAsync() → void async /* futureValueType= void */ {}
+static method test() → dynamic async /* futureValueType= dynamic */ {
   await self::returnVoid();
   await self::returnVoidAsync();
 }
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await self::returnFutureOfVoid();
 }
diff --git a/pkg/front_end/testcases/nnbd/issue41602.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41602.dart.weak.transformed.expect
index 675b14d..756e88b 100644
--- a/pkg/front_end/testcases/nnbd/issue41602.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41602.dart.weak.transformed.expect
@@ -15,7 +15,7 @@
 import "dart:core" as core;
 import "dart:_internal" as _in;
 
-static method returnFutureOfVoid() → asy::Future<void> /* originally async */ {
+static method returnFutureOfVoid() → asy::Future<void> /* futureValueType= void */ /* originally async */ {
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   void :return_value;
@@ -40,7 +40,7 @@
   return :async_future;
 }
 static method returnVoid() → void {}
-static method returnVoidAsync() → void /* originally async */ {
+static method returnVoidAsync() → void /* futureValueType= void */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -64,7 +64,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -94,7 +94,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41697.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41697.dart.strong.expect
index d7f0e7d..6b5ec79 100644
--- a/pkg/front_end/testcases/nnbd/issue41697.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41697.dart.strong.expect
@@ -33,7 +33,7 @@
   <S extends core::num>(S) → core::num f1 = c.{self::C::field1} = <S extends core::num>(S s) → core::num {
     return s.{core::num::+}(1){(core::num) → core::num};
   };
-  <S extends FutureOr<core::num>>(S, FutureOr<core::num>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num>>(S s, FutureOr<core::num>t) → asy::Future<core::num> async {
+  <S extends FutureOr<core::num>>(S, FutureOr<core::num>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num>>(S s, FutureOr<core::num>t) → asy::Future<core::num> async /* futureValueType= core::num */ {
     return (await t).{core::num::+}(1){(core::num) → core::num};
   };
 }
@@ -43,7 +43,7 @@
     return s + 1; // error
              ^" in s.{core::num::+}(1){(core::num) → core::num};
   };
-  <S extends FutureOr<core::num?>>(S%, FutureOr<core::num?>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num?>>(S% s, FutureOr<core::num?>t) → asy::Future<core::num> async {
+  <S extends FutureOr<core::num?>>(S%, FutureOr<core::num?>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num?>>(S% s, FutureOr<core::num?>t) → asy::Future<core::num> async /* futureValueType= core::num */ {
     return invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:36:22: Error: Operator '+' cannot be called on 'num?' because it is potentially null.
     return (await t) + 1; // error
                      ^" in (await t).{core::num::+}(1){(core::num) → core::num};
diff --git a/pkg/front_end/testcases/nnbd/issue41697.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41697.dart.strong.transformed.expect
index 1c73ad9..271e82e 100644
--- a/pkg/front_end/testcases/nnbd/issue41697.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41697.dart.strong.transformed.expect
@@ -34,7 +34,7 @@
   <S extends core::num>(S) → core::num f1 = c.{self::C::field1} = <S extends core::num>(S s) → core::num {
     return s.{core::num::+}(1){(core::num) → core::num};
   };
-  <S extends FutureOr<core::num>>(S, FutureOr<core::num>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num>>(S s, FutureOr<core::num>t) → asy::Future<core::num> /* originally async */ {
+  <S extends FutureOr<core::num>>(S, FutureOr<core::num>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num>>(S s, FutureOr<core::num>t) → asy::Future<core::num> /* futureValueType= core::num */ /* originally async */ {
     final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
     core::bool* :is_sync = false;
     core::num? :return_value;
@@ -70,7 +70,7 @@
     return s + 1; // error
              ^" in s.{core::num::+}(1){(core::num) → core::num};
   };
-  <S extends FutureOr<core::num?>>(S%, FutureOr<core::num?>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num?>>(S% s, FutureOr<core::num?>t) → asy::Future<core::num> /* originally async */ {
+  <S extends FutureOr<core::num?>>(S%, FutureOr<core::num?>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num?>>(S% s, FutureOr<core::num?>t) → asy::Future<core::num> /* futureValueType= core::num */ /* originally async */ {
     final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
     core::bool* :is_sync = false;
     FutureOr<core::num>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue41697.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41697.dart.weak.expect
index d7f0e7d..6b5ec79 100644
--- a/pkg/front_end/testcases/nnbd/issue41697.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41697.dart.weak.expect
@@ -33,7 +33,7 @@
   <S extends core::num>(S) → core::num f1 = c.{self::C::field1} = <S extends core::num>(S s) → core::num {
     return s.{core::num::+}(1){(core::num) → core::num};
   };
-  <S extends FutureOr<core::num>>(S, FutureOr<core::num>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num>>(S s, FutureOr<core::num>t) → asy::Future<core::num> async {
+  <S extends FutureOr<core::num>>(S, FutureOr<core::num>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num>>(S s, FutureOr<core::num>t) → asy::Future<core::num> async /* futureValueType= core::num */ {
     return (await t).{core::num::+}(1){(core::num) → core::num};
   };
 }
@@ -43,7 +43,7 @@
     return s + 1; // error
              ^" in s.{core::num::+}(1){(core::num) → core::num};
   };
-  <S extends FutureOr<core::num?>>(S%, FutureOr<core::num?>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num?>>(S% s, FutureOr<core::num?>t) → asy::Future<core::num> async {
+  <S extends FutureOr<core::num?>>(S%, FutureOr<core::num?>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num?>>(S% s, FutureOr<core::num?>t) → asy::Future<core::num> async /* futureValueType= core::num */ {
     return invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:36:22: Error: Operator '+' cannot be called on 'num?' because it is potentially null.
     return (await t) + 1; // error
                      ^" in (await t).{core::num::+}(1){(core::num) → core::num};
diff --git a/pkg/front_end/testcases/nnbd/issue41697.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue41697.dart.weak.modular.expect
index d7f0e7d..6b5ec79 100644
--- a/pkg/front_end/testcases/nnbd/issue41697.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue41697.dart.weak.modular.expect
@@ -33,7 +33,7 @@
   <S extends core::num>(S) → core::num f1 = c.{self::C::field1} = <S extends core::num>(S s) → core::num {
     return s.{core::num::+}(1){(core::num) → core::num};
   };
-  <S extends FutureOr<core::num>>(S, FutureOr<core::num>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num>>(S s, FutureOr<core::num>t) → asy::Future<core::num> async {
+  <S extends FutureOr<core::num>>(S, FutureOr<core::num>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num>>(S s, FutureOr<core::num>t) → asy::Future<core::num> async /* futureValueType= core::num */ {
     return (await t).{core::num::+}(1){(core::num) → core::num};
   };
 }
@@ -43,7 +43,7 @@
     return s + 1; // error
              ^" in s.{core::num::+}(1){(core::num) → core::num};
   };
-  <S extends FutureOr<core::num?>>(S%, FutureOr<core::num?>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num?>>(S% s, FutureOr<core::num?>t) → asy::Future<core::num> async {
+  <S extends FutureOr<core::num?>>(S%, FutureOr<core::num?>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num?>>(S% s, FutureOr<core::num?>t) → asy::Future<core::num> async /* futureValueType= core::num */ {
     return invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:36:22: Error: Operator '+' cannot be called on 'num?' because it is potentially null.
     return (await t) + 1; // error
                      ^" in (await t).{core::num::+}(1){(core::num) → core::num};
diff --git a/pkg/front_end/testcases/nnbd/issue41697.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41697.dart.weak.transformed.expect
index 1c73ad9..271e82e 100644
--- a/pkg/front_end/testcases/nnbd/issue41697.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41697.dart.weak.transformed.expect
@@ -34,7 +34,7 @@
   <S extends core::num>(S) → core::num f1 = c.{self::C::field1} = <S extends core::num>(S s) → core::num {
     return s.{core::num::+}(1){(core::num) → core::num};
   };
-  <S extends FutureOr<core::num>>(S, FutureOr<core::num>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num>>(S s, FutureOr<core::num>t) → asy::Future<core::num> /* originally async */ {
+  <S extends FutureOr<core::num>>(S, FutureOr<core::num>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num>>(S s, FutureOr<core::num>t) → asy::Future<core::num> /* futureValueType= core::num */ /* originally async */ {
     final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
     core::bool* :is_sync = false;
     core::num? :return_value;
@@ -70,7 +70,7 @@
     return s + 1; // error
              ^" in s.{core::num::+}(1){(core::num) → core::num};
   };
-  <S extends FutureOr<core::num?>>(S%, FutureOr<core::num?>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num?>>(S% s, FutureOr<core::num?>t) → asy::Future<core::num> /* originally async */ {
+  <S extends FutureOr<core::num?>>(S%, FutureOr<core::num?>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num?>>(S% s, FutureOr<core::num?>t) → asy::Future<core::num> /* futureValueType= core::num */ /* originally async */ {
     final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
     core::bool* :is_sync = false;
     FutureOr<core::num>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue42540.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42540.dart.strong.expect
index aaf931d..04de009 100644
--- a/pkg/front_end/testcases/nnbd/issue42540.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue42540.dart.strong.expect
@@ -5,7 +5,7 @@
 
 static method getNull() → dynamic
   return null;
-static method fn() → asy::Future<core::Object> async {
+static method fn() → asy::Future<core::Object> async /* futureValueType= core::Object */ {
   core::Object o = await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Object;
   return await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::Object>;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect
index 2b136de..e9c16e6 100644
--- a/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect
@@ -5,7 +5,7 @@
 
 static method getNull() → dynamic
   return null;
-static method fn() → asy::Future<core::Object> /* originally async */ {
+static method fn() → asy::Future<core::Object> /* futureValueType= core::Object */ /* originally async */ {
   final asy::_Future<core::Object> :async_future = new asy::_Future::•<core::Object>();
   core::bool* :is_sync = false;
   FutureOr<core::Object>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue42540.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42540.dart.weak.expect
index aaf931d..04de009 100644
--- a/pkg/front_end/testcases/nnbd/issue42540.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue42540.dart.weak.expect
@@ -5,7 +5,7 @@
 
 static method getNull() → dynamic
   return null;
-static method fn() → asy::Future<core::Object> async {
+static method fn() → asy::Future<core::Object> async /* futureValueType= core::Object */ {
   core::Object o = await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Object;
   return await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::Object>;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue42540.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue42540.dart.weak.modular.expect
index aaf931d..04de009 100644
--- a/pkg/front_end/testcases/nnbd/issue42540.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue42540.dart.weak.modular.expect
@@ -5,7 +5,7 @@
 
 static method getNull() → dynamic
   return null;
-static method fn() → asy::Future<core::Object> async {
+static method fn() → asy::Future<core::Object> async /* futureValueType= core::Object */ {
   core::Object o = await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Object;
   return await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::Object>;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue42540.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42540.dart.weak.transformed.expect
index 74c0365..717c3ef 100644
--- a/pkg/front_end/testcases/nnbd/issue42540.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42540.dart.weak.transformed.expect
@@ -5,7 +5,7 @@
 
 static method getNull() → dynamic
   return null;
-static method fn() → asy::Future<core::Object> /* originally async */ {
+static method fn() → asy::Future<core::Object> /* futureValueType= core::Object */ /* originally async */ {
   final asy::_Future<core::Object> :async_future = new asy::_Future::•<core::Object>();
   core::bool* :is_sync = false;
   FutureOr<core::Object>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.strong.expect
index 8563b46..64a0fed 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.strong.expect
@@ -37,12 +37,12 @@
   no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C11, 0, #C3, #C12, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>;
 }
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   asy::Future<self::Divergent<self::Divergent<core::int>>> x = invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:75: Error: A value of type 'Future<Divergent<Divergent<Divergent<int>>>>' can't be assigned to a variable of type 'Future<Divergent<Divergent<int>>>'.
  - 'Future' is from 'dart:async'.
  - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
   Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
-                                                                          ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> async => invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:58: Error: A value of type 'Divergent<int>' can't be returned from an async function with return type 'Future<Divergent<Divergent<Divergent<int>>>>'.
+                                                                          ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> async /* futureValueType= self::Divergent<self::Divergent<self::Divergent<core::int>>> */ => invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:58: Error: A value of type 'Divergent<int>' can't be returned from an async function with return type 'Future<Divergent<Divergent<Divergent<int>>>>'.
  - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
  - 'Future' is from 'dart:async'.
   Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.strong.transformed.expect
index e5489e1..229b2a9 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.strong.transformed.expect
@@ -37,7 +37,7 @@
   no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C11, 0, #C3, #C12, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>;
 }
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -53,7 +53,7 @@
  - 'Future' is from 'dart:async'.
  - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
   Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
-                                                                          ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> /* originally async */ {
+                                                                          ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> /* futureValueType= self::Divergent<self::Divergent<self::Divergent<core::int>>> */ /* originally async */ {
           final asy::_Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> :async_future = new asy::_Future::•<self::Divergent<self::Divergent<self::Divergent<core::int>>>>();
           core::bool* :is_sync = false;
           FutureOr<self::Divergent<self::Divergent<self::Divergent<core::int>>>>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.expect
index 8563b46..64a0fed 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.expect
@@ -37,12 +37,12 @@
   no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C11, 0, #C3, #C12, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>;
 }
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   asy::Future<self::Divergent<self::Divergent<core::int>>> x = invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:75: Error: A value of type 'Future<Divergent<Divergent<Divergent<int>>>>' can't be assigned to a variable of type 'Future<Divergent<Divergent<int>>>'.
  - 'Future' is from 'dart:async'.
  - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
   Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
-                                                                          ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> async => invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:58: Error: A value of type 'Divergent<int>' can't be returned from an async function with return type 'Future<Divergent<Divergent<Divergent<int>>>>'.
+                                                                          ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> async /* futureValueType= self::Divergent<self::Divergent<self::Divergent<core::int>>> */ => invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:58: Error: A value of type 'Divergent<int>' can't be returned from an async function with return type 'Future<Divergent<Divergent<Divergent<int>>>>'.
  - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
  - 'Future' is from 'dart:async'.
   Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.modular.expect
index 8563b46..64a0fed 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.modular.expect
@@ -37,12 +37,12 @@
   no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C11, 0, #C3, #C12, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>;
 }
-static method test() → dynamic async {
+static method test() → dynamic async /* futureValueType= dynamic */ {
   asy::Future<self::Divergent<self::Divergent<core::int>>> x = invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:75: Error: A value of type 'Future<Divergent<Divergent<Divergent<int>>>>' can't be assigned to a variable of type 'Future<Divergent<Divergent<int>>>'.
  - 'Future' is from 'dart:async'.
  - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
   Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
-                                                                          ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> async => invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:58: Error: A value of type 'Divergent<int>' can't be returned from an async function with return type 'Future<Divergent<Divergent<Divergent<int>>>>'.
+                                                                          ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> async /* futureValueType= self::Divergent<self::Divergent<self::Divergent<core::int>>> */ => invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:58: Error: A value of type 'Divergent<int>' can't be returned from an async function with return type 'Future<Divergent<Divergent<Divergent<int>>>>'.
  - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
  - 'Future' is from 'dart:async'.
   Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.transformed.expect
index e5489e1..229b2a9 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.transformed.expect
@@ -37,7 +37,7 @@
   no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
     return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C11, 0, #C3, #C12, core::Map::unmodifiable<core::Symbol*, dynamic>(#C6))){(core::Invocation) → dynamic} as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>;
 }
-static method test() → dynamic /* originally async */ {
+static method test() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -53,7 +53,7 @@
  - 'Future' is from 'dart:async'.
  - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
   Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
-                                                                          ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> /* originally async */ {
+                                                                          ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> /* futureValueType= self::Divergent<self::Divergent<self::Divergent<core::int>>> */ /* originally async */ {
           final asy::_Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> :async_future = new asy::_Future::•<self::Divergent<self::Divergent<self::Divergent<core::int>>>>();
           core::bool* :is_sync = false;
           FutureOr<self::Divergent<self::Divergent<self::Divergent<core::int>>>>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue42743.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42743.dart.strong.expect
index 3e6d749..8bf045e 100644
--- a/pkg/front_end/testcases/nnbd/issue42743.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue42743.dart.strong.expect
@@ -3,13 +3,13 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   core::bool b = (() → core::bool => true)(){() → core::bool};
   (dynamic _) → core::int? {
     if(b)
       return 42;
   };
-  (dynamic _) → asy::Future<core::int?> async {
+  (dynamic _) → asy::Future<core::int?> async /* futureValueType= core::int? */ {
     if(b)
       return 42;
   };
diff --git a/pkg/front_end/testcases/nnbd/issue42743.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42743.dart.strong.transformed.expect
index 199ae9b..057b001 100644
--- a/pkg/front_end/testcases/nnbd/issue42743.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42743.dart.strong.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -20,7 +20,7 @@
           if(b)
             return 42;
         };
-        (dynamic _) → asy::Future<core::int?> /* originally async */ {
+        (dynamic _) → asy::Future<core::int?> /* futureValueType= core::int? */ /* originally async */ {
           final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
           core::bool* :is_sync = false;
           core::int? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue42743.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42743.dart.weak.expect
index 3e6d749..8bf045e 100644
--- a/pkg/front_end/testcases/nnbd/issue42743.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue42743.dart.weak.expect
@@ -3,13 +3,13 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   core::bool b = (() → core::bool => true)(){() → core::bool};
   (dynamic _) → core::int? {
     if(b)
       return 42;
   };
-  (dynamic _) → asy::Future<core::int?> async {
+  (dynamic _) → asy::Future<core::int?> async /* futureValueType= core::int? */ {
     if(b)
       return 42;
   };
diff --git a/pkg/front_end/testcases/nnbd/issue42743.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue42743.dart.weak.modular.expect
index 3e6d749..8bf045e 100644
--- a/pkg/front_end/testcases/nnbd/issue42743.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue42743.dart.weak.modular.expect
@@ -3,13 +3,13 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   core::bool b = (() → core::bool => true)(){() → core::bool};
   (dynamic _) → core::int? {
     if(b)
       return 42;
   };
-  (dynamic _) → asy::Future<core::int?> async {
+  (dynamic _) → asy::Future<core::int?> async /* futureValueType= core::int? */ {
     if(b)
       return 42;
   };
diff --git a/pkg/front_end/testcases/nnbd/issue42743.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42743.dart.weak.transformed.expect
index 199ae9b..057b001 100644
--- a/pkg/front_end/testcases/nnbd/issue42743.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42743.dart.weak.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:async" as asy;
 import "dart:core" as core;
 
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -20,7 +20,7 @@
           if(b)
             return 42;
         };
-        (dynamic _) → asy::Future<core::int?> /* originally async */ {
+        (dynamic _) → asy::Future<core::int?> /* futureValueType= core::int? */ /* originally async */ {
           final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
           core::bool* :is_sync = false;
           core::int? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue44595.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue44595.dart.strong.expect
index 150af53..8429111 100644
--- a/pkg/front_end/testcases/nnbd/issue44595.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue44595.dart.strong.expect
@@ -11,7 +11,7 @@
 }
 static method id<T extends core::Object? = dynamic>(self::id::T% value) → self::id::T%
   return value;
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   FutureOr<core::int>x = 1.{core::num::+}(self::id<core::int>(1)){(core::num) → core::int};
   FutureOr<core::int>y = let final core::int #t1 = 1.{core::num::+}(self::id<core::int>(1)){(core::num) → core::int} in block {
     self::_extension#0|checkStaticType<core::int, (core::int) → core::int>(#t1);
diff --git a/pkg/front_end/testcases/nnbd/issue44595.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue44595.dart.strong.transformed.expect
index 0bf212b..65142ef 100644
--- a/pkg/front_end/testcases/nnbd/issue44595.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue44595.dart.strong.transformed.expect
@@ -12,7 +12,7 @@
 }
 static method id<T extends core::Object? = dynamic>(self::id::T% value) → self::id::T%
   return value;
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/nnbd/issue44595.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue44595.dart.weak.expect
index 150af53..8429111 100644
--- a/pkg/front_end/testcases/nnbd/issue44595.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue44595.dart.weak.expect
@@ -11,7 +11,7 @@
 }
 static method id<T extends core::Object? = dynamic>(self::id::T% value) → self::id::T%
   return value;
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   FutureOr<core::int>x = 1.{core::num::+}(self::id<core::int>(1)){(core::num) → core::int};
   FutureOr<core::int>y = let final core::int #t1 = 1.{core::num::+}(self::id<core::int>(1)){(core::num) → core::int} in block {
     self::_extension#0|checkStaticType<core::int, (core::int) → core::int>(#t1);
diff --git a/pkg/front_end/testcases/nnbd/issue44595.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/issue44595.dart.weak.modular.expect
index 150af53..8429111 100644
--- a/pkg/front_end/testcases/nnbd/issue44595.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/issue44595.dart.weak.modular.expect
@@ -11,7 +11,7 @@
 }
 static method id<T extends core::Object? = dynamic>(self::id::T% value) → self::id::T%
   return value;
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   FutureOr<core::int>x = 1.{core::num::+}(self::id<core::int>(1)){(core::num) → core::int};
   FutureOr<core::int>y = let final core::int #t1 = 1.{core::num::+}(self::id<core::int>(1)){(core::num) → core::int} in block {
     self::_extension#0|checkStaticType<core::int, (core::int) → core::int>(#t1);
diff --git a/pkg/front_end/testcases/nnbd/issue44595.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue44595.dart.weak.transformed.expect
index 0bf212b..65142ef 100644
--- a/pkg/front_end/testcases/nnbd/issue44595.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue44595.dart.weak.transformed.expect
@@ -12,7 +12,7 @@
 }
 static method id<T extends core::Object? = dynamic>(self::id::T% value) → self::id::T%
   return value;
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/nnbd/later.dart.strong.expect b/pkg/front_end/testcases/nnbd/later.dart.strong.expect
index 63fc71a..ef843ca 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.strong.expect
@@ -116,20 +116,20 @@
       #t1.{core::List::add}{Invariant}(i){(core::int) → void};
   } =>#t1;
 }
-static method hest() → dynamic async {
+static method hest() → dynamic async /* futureValueType= dynamic */ {
   await for (core::String s in asy::Stream::fromIterable<core::String>(<core::String>["hest"])) {
     core::print(s);
   }
   return "hest";
 }
-static method fisk() → dynamic async {
+static method fisk() → dynamic async /* futureValueType= dynamic */ {
   late core::String s1 = invalid-expression "pkg/front_end/testcases/nnbd/later.dart:38:20: Error: `await` expressions are not supported in late local initializers.
   late String s1 = await hest();
                    ^^^^^";
   late core::String s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/nnbd/later.dart:39:30: Error: `await` expressions are not supported in late local initializers.
   late String s2 = '\${fisk}\${await hest()}\${fisk}';
                              ^^^^^"}${#C1}";
-  late core::Function f = () → asy::Future<dynamic> async => await self::hest();
+  late core::Function f = () → asy::Future<dynamic> async /* futureValueType= dynamic */ => await self::hest();
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
index c26058b..f0900fa 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
@@ -123,7 +123,7 @@
       #t1.{core::List::add}{Invariant}(i){(core::int) → void};
   } =>#t1;
 }
-static method hest() → dynamic /* originally async */ {
+static method hest() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -177,7 +177,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method fisk() → dynamic /* originally async */ {
+static method fisk() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -200,7 +200,7 @@
                              ^^^^^"}${#C1}";
         late core::String s2 = #s2#initializer(){() → core::String};
         function #f#initializer() → core::Function
-          return () → asy::Future<dynamic> /* originally async */ {
+          return () → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
             final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
             core::bool* :is_sync = false;
             FutureOr<dynamic>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/later.dart.weak.expect b/pkg/front_end/testcases/nnbd/later.dart.weak.expect
index 63fc71a..ef843ca 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.weak.expect
@@ -116,20 +116,20 @@
       #t1.{core::List::add}{Invariant}(i){(core::int) → void};
   } =>#t1;
 }
-static method hest() → dynamic async {
+static method hest() → dynamic async /* futureValueType= dynamic */ {
   await for (core::String s in asy::Stream::fromIterable<core::String>(<core::String>["hest"])) {
     core::print(s);
   }
   return "hest";
 }
-static method fisk() → dynamic async {
+static method fisk() → dynamic async /* futureValueType= dynamic */ {
   late core::String s1 = invalid-expression "pkg/front_end/testcases/nnbd/later.dart:38:20: Error: `await` expressions are not supported in late local initializers.
   late String s1 = await hest();
                    ^^^^^";
   late core::String s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/nnbd/later.dart:39:30: Error: `await` expressions are not supported in late local initializers.
   late String s2 = '\${fisk}\${await hest()}\${fisk}';
                              ^^^^^"}${#C1}";
-  late core::Function f = () → asy::Future<dynamic> async => await self::hest();
+  late core::Function f = () → asy::Future<dynamic> async /* futureValueType= dynamic */ => await self::hest();
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/nnbd/later.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/later.dart.weak.modular.expect
index 63fc71a..ef843ca 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.weak.modular.expect
@@ -116,20 +116,20 @@
       #t1.{core::List::add}{Invariant}(i){(core::int) → void};
   } =>#t1;
 }
-static method hest() → dynamic async {
+static method hest() → dynamic async /* futureValueType= dynamic */ {
   await for (core::String s in asy::Stream::fromIterable<core::String>(<core::String>["hest"])) {
     core::print(s);
   }
   return "hest";
 }
-static method fisk() → dynamic async {
+static method fisk() → dynamic async /* futureValueType= dynamic */ {
   late core::String s1 = invalid-expression "pkg/front_end/testcases/nnbd/later.dart:38:20: Error: `await` expressions are not supported in late local initializers.
   late String s1 = await hest();
                    ^^^^^";
   late core::String s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/nnbd/later.dart:39:30: Error: `await` expressions are not supported in late local initializers.
   late String s2 = '\${fisk}\${await hest()}\${fisk}';
                              ^^^^^"}${#C1}";
-  late core::Function f = () → asy::Future<dynamic> async => await self::hest();
+  late core::Function f = () → asy::Future<dynamic> async /* futureValueType= dynamic */ => await self::hest();
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
index c26058b..f0900fa 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
@@ -123,7 +123,7 @@
       #t1.{core::List::add}{Invariant}(i){(core::int) → void};
   } =>#t1;
 }
-static method hest() → dynamic /* originally async */ {
+static method hest() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -177,7 +177,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method fisk() → dynamic /* originally async */ {
+static method fisk() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -200,7 +200,7 @@
                              ^^^^^"}${#C1}";
         late core::String s2 = #s2#initializer(){() → core::String};
         function #f#initializer() → core::Function
-          return () → asy::Future<dynamic> /* originally async */ {
+          return () → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
             final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
             core::bool* :is_sync = false;
             FutureOr<dynamic>? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/return_async.dart.strong.expect b/pkg/front_end/testcases/nnbd/return_async.dart.strong.expect
index ce2f50d..efe6e98 100644
--- a/pkg/front_end/testcases/nnbd/return_async.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/return_async.dart.strong.expect
@@ -8,21 +8,21 @@
 static method throwSync() → asy::Future<void> {
   throw "";
 }
-static method allYield() → asy::Future<void> async {
+static method allYield() → asy::Future<void> async /* futureValueType= void */ {
   await 0;
   await self::allYield2();
 }
-static method allYield2() → asy::Future<void> async {
+static method allYield2() → asy::Future<void> async /* futureValueType= void */ {
   await 0;
   await self::allYield3();
 }
-static method allYield3() → asy::Future<void> async {
+static method allYield3() → asy::Future<void> async /* futureValueType= void */ {
   await 0;
   self::throwSync();
 }
-static method customErrorZone() → asy::Future<void> async {
+static method customErrorZone() → asy::Future<void> async /* futureValueType= void */ {
   final asy::Completer<void> completer = asy::Completer::•<void>();
-  asy::runZonedGuarded<asy::Future<Null>>(() → asy::Future<Null> async {
+  asy::runZonedGuarded<asy::Future<Null>>(() → asy::Future<Null> async /* futureValueType= Null */ {
     await self::allYield();
     completer.{asy::Completer::complete}(null){([FutureOr<void>?]) → void};
   }, (core::Object e, core::StackTrace s) → void {
diff --git a/pkg/front_end/testcases/nnbd/return_async.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/return_async.dart.strong.transformed.expect
index 8e3b2c1..53360c1 100644
--- a/pkg/front_end/testcases/nnbd/return_async.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_async.dart.strong.transformed.expect
@@ -9,7 +9,7 @@
 static method throwSync() → asy::Future<void> {
   throw "";
 }
-static method allYield() → asy::Future<void> /* originally async */ {
+static method allYield() → asy::Future<void> /* futureValueType= void */ /* originally async */ {
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   void :return_value;
@@ -39,7 +39,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method allYield2() → asy::Future<void> /* originally async */ {
+static method allYield2() → asy::Future<void> /* futureValueType= void */ /* originally async */ {
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   void :return_value;
@@ -69,7 +69,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method allYield3() → asy::Future<void> /* originally async */ {
+static method allYield3() → asy::Future<void> /* futureValueType= void */ /* originally async */ {
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   void :return_value;
@@ -98,7 +98,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method customErrorZone() → asy::Future<void> /* originally async */ {
+static method customErrorZone() → asy::Future<void> /* futureValueType= void */ /* originally async */ {
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
@@ -111,7 +111,7 @@
       #L4:
       {
         final asy::Completer<void> completer = asy::Completer::•<void>();
-        asy::runZonedGuarded<asy::Future<Null>>(() → asy::Future<Null> /* originally async */ {
+        asy::runZonedGuarded<asy::Future<Null>>(() → asy::Future<Null> /* futureValueType= Null */ /* originally async */ {
           final asy::_Future<Null> :async_future = new asy::_Future::•<Null>();
           core::bool* :is_sync = false;
           Null :return_value;
diff --git a/pkg/front_end/testcases/nnbd/return_async.dart.weak.expect b/pkg/front_end/testcases/nnbd/return_async.dart.weak.expect
index ce2f50d..efe6e98 100644
--- a/pkg/front_end/testcases/nnbd/return_async.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/return_async.dart.weak.expect
@@ -8,21 +8,21 @@
 static method throwSync() → asy::Future<void> {
   throw "";
 }
-static method allYield() → asy::Future<void> async {
+static method allYield() → asy::Future<void> async /* futureValueType= void */ {
   await 0;
   await self::allYield2();
 }
-static method allYield2() → asy::Future<void> async {
+static method allYield2() → asy::Future<void> async /* futureValueType= void */ {
   await 0;
   await self::allYield3();
 }
-static method allYield3() → asy::Future<void> async {
+static method allYield3() → asy::Future<void> async /* futureValueType= void */ {
   await 0;
   self::throwSync();
 }
-static method customErrorZone() → asy::Future<void> async {
+static method customErrorZone() → asy::Future<void> async /* futureValueType= void */ {
   final asy::Completer<void> completer = asy::Completer::•<void>();
-  asy::runZonedGuarded<asy::Future<Null>>(() → asy::Future<Null> async {
+  asy::runZonedGuarded<asy::Future<Null>>(() → asy::Future<Null> async /* futureValueType= Null */ {
     await self::allYield();
     completer.{asy::Completer::complete}(null){([FutureOr<void>?]) → void};
   }, (core::Object e, core::StackTrace s) → void {
diff --git a/pkg/front_end/testcases/nnbd/return_async.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/return_async.dart.weak.modular.expect
index ce2f50d..efe6e98 100644
--- a/pkg/front_end/testcases/nnbd/return_async.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/return_async.dart.weak.modular.expect
@@ -8,21 +8,21 @@
 static method throwSync() → asy::Future<void> {
   throw "";
 }
-static method allYield() → asy::Future<void> async {
+static method allYield() → asy::Future<void> async /* futureValueType= void */ {
   await 0;
   await self::allYield2();
 }
-static method allYield2() → asy::Future<void> async {
+static method allYield2() → asy::Future<void> async /* futureValueType= void */ {
   await 0;
   await self::allYield3();
 }
-static method allYield3() → asy::Future<void> async {
+static method allYield3() → asy::Future<void> async /* futureValueType= void */ {
   await 0;
   self::throwSync();
 }
-static method customErrorZone() → asy::Future<void> async {
+static method customErrorZone() → asy::Future<void> async /* futureValueType= void */ {
   final asy::Completer<void> completer = asy::Completer::•<void>();
-  asy::runZonedGuarded<asy::Future<Null>>(() → asy::Future<Null> async {
+  asy::runZonedGuarded<asy::Future<Null>>(() → asy::Future<Null> async /* futureValueType= Null */ {
     await self::allYield();
     completer.{asy::Completer::complete}(null){([FutureOr<void>?]) → void};
   }, (core::Object e, core::StackTrace s) → void {
diff --git a/pkg/front_end/testcases/nnbd/return_async.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/return_async.dart.weak.transformed.expect
index 8e3b2c1..53360c1 100644
--- a/pkg/front_end/testcases/nnbd/return_async.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_async.dart.weak.transformed.expect
@@ -9,7 +9,7 @@
 static method throwSync() → asy::Future<void> {
   throw "";
 }
-static method allYield() → asy::Future<void> /* originally async */ {
+static method allYield() → asy::Future<void> /* futureValueType= void */ /* originally async */ {
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   void :return_value;
@@ -39,7 +39,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method allYield2() → asy::Future<void> /* originally async */ {
+static method allYield2() → asy::Future<void> /* futureValueType= void */ /* originally async */ {
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   void :return_value;
@@ -69,7 +69,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method allYield3() → asy::Future<void> /* originally async */ {
+static method allYield3() → asy::Future<void> /* futureValueType= void */ /* originally async */ {
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   void :return_value;
@@ -98,7 +98,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method customErrorZone() → asy::Future<void> /* originally async */ {
+static method customErrorZone() → asy::Future<void> /* futureValueType= void */ /* originally async */ {
   final asy::_Future<void> :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
@@ -111,7 +111,7 @@
       #L4:
       {
         final asy::Completer<void> completer = asy::Completer::•<void>();
-        asy::runZonedGuarded<asy::Future<Null>>(() → asy::Future<Null> /* originally async */ {
+        asy::runZonedGuarded<asy::Future<Null>>(() → asy::Future<Null> /* futureValueType= Null */ /* originally async */ {
           final asy::_Future<Null> :async_future = new asy::_Future::•<Null>();
           core::bool* :is_sync = false;
           Null :return_value;
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect b/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect
index 918c16c..99358d9 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect
@@ -91,19 +91,19 @@
 String returnMixed(bool b) /*error*/ {
        ^" in null;
 }
-static method returnAsync1() → asy::Future<dynamic> async {}
-static method returnAsync2() → FutureOr<dynamic> async {}
-static method returnAsync3() → FutureOr<core::int> async {
+static method returnAsync1() → asy::Future<dynamic> async /* futureValueType= dynamic */ {}
+static method returnAsync2() → FutureOr<dynamic> async /* futureValueType= dynamic */ {}
+static method returnAsync3() → FutureOr<core::int> async /* futureValueType= core::int */ {
   return invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:27:15: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
 FutureOr<int> returnAsync3() async {} // error
               ^" in null;
 }
-static method returnAsync4() → FutureOr<core::int?> async {}
-static method returnAsync5() → dynamic async {}
-static method returnAsync6() → asy::Future<core::int?> async {
+static method returnAsync4() → FutureOr<core::int?> async /* futureValueType= core::int? */ {}
+static method returnAsync5() → dynamic async /* futureValueType= dynamic */ {}
+static method returnAsync6() → asy::Future<core::int?> async /* futureValueType= core::int? */ {
   return null;
 }
-static method returnAsync7() → asy::Future<core::int?> async {}
+static method returnAsync7() → asy::Future<core::int?> async /* futureValueType= core::int? */ {}
 static method yieldSync() → core::Iterable<dynamic> sync* {}
 static method yieldAsync() → asy::Stream<dynamic> async* {}
 static method caseReturn1(self::Enum e) → self::Enum {
@@ -160,19 +160,19 @@
   String returnMixed(bool b) /* error */ {
   ^" in null;
   }
-  function returnAsync1() → asy::Future<dynamic> async {}
-  function returnAsync2() → FutureOr<dynamic> async {}
-  function returnAsync3() → FutureOr<core::int> async {
+  function returnAsync1() → asy::Future<dynamic> async /* futureValueType= dynamic */ {}
+  function returnAsync2() → FutureOr<dynamic> async /* futureValueType= dynamic */ {}
+  function returnAsync3() → FutureOr<core::int> async /* futureValueType= core::int */ {
     return invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:83:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
   FutureOr<int> returnAsync3() async {} // error
   ^" in null;
   }
-  function returnAsync4() → FutureOr<core::int?> async {}
-  function returnAsync5() → asy::Future<Null> async {}
-  function returnAsync6() → asy::Future<core::int?> async {
+  function returnAsync4() → FutureOr<core::int?> async /* futureValueType= core::int? */ {}
+  function returnAsync5() → asy::Future<Null> async /* futureValueType= Null */ {}
+  function returnAsync6() → asy::Future<core::int?> async /* futureValueType= core::int? */ {
     return null;
   }
-  function returnAsync7() → asy::Future<core::int?> async {}
+  function returnAsync7() → asy::Future<core::int?> async /* futureValueType= core::int? */ {}
   function yieldSync() → core::Iterable<dynamic> sync* {}
   function yieldAsync() → asy::Stream<dynamic> async* {}
   function caseReturn1(self::Enum e) → self::Enum {
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
index f464a2f..6200c9f 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
@@ -91,7 +91,7 @@
 String returnMixed(bool b) /*error*/ {
        ^" in null;
 }
-static method returnAsync1() → asy::Future<dynamic> /* originally async */ {
+static method returnAsync1() → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -115,7 +115,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnAsync2() → FutureOr<dynamic> /* originally async */ {
+static method returnAsync2() → FutureOr<dynamic> /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -139,7 +139,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnAsync3() → FutureOr<core::int> /* originally async */ {
+static method returnAsync3() → FutureOr<core::int> /* futureValueType= core::int */ /* originally async */ {
   final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
   core::bool* :is_sync = false;
   FutureOr<core::int>? :return_value;
@@ -168,7 +168,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnAsync4() → FutureOr<core::int?> /* originally async */ {
+static method returnAsync4() → FutureOr<core::int?> /* futureValueType= core::int? */ /* originally async */ {
   final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
   core::bool* :is_sync = false;
   core::int? :return_value;
@@ -192,7 +192,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnAsync5() → dynamic /* originally async */ {
+static method returnAsync5() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -216,7 +216,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnAsync6() → asy::Future<core::int?> /* originally async */ {
+static method returnAsync6() → asy::Future<core::int?> /* futureValueType= core::int? */ /* originally async */ {
   final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
   core::bool* :is_sync = false;
   FutureOr<core::int?>? :return_value;
@@ -243,7 +243,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnAsync7() → asy::Future<core::int?> /* originally async */ {
+static method returnAsync7() → asy::Future<core::int?> /* futureValueType= core::int? */ /* originally async */ {
   final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
   core::bool* :is_sync = false;
   core::int? :return_value;
@@ -359,7 +359,7 @@
   String returnMixed(bool b) /* error */ {
   ^" in null;
   }
-  function returnAsync1() → asy::Future<dynamic> /* originally async */ {
+  function returnAsync1() → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
     final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     dynamic :return_value;
@@ -383,7 +383,7 @@
     :is_sync = true;
     return :async_future;
   }
-  function returnAsync2() → FutureOr<dynamic> /* originally async */ {
+  function returnAsync2() → FutureOr<dynamic> /* futureValueType= dynamic */ /* originally async */ {
     final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     dynamic :return_value;
@@ -407,7 +407,7 @@
     :is_sync = true;
     return :async_future;
   }
-  function returnAsync3() → FutureOr<core::int> /* originally async */ {
+  function returnAsync3() → FutureOr<core::int> /* futureValueType= core::int */ /* originally async */ {
     final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
     core::bool* :is_sync = false;
     FutureOr<core::int>? :return_value;
@@ -436,7 +436,7 @@
     :is_sync = true;
     return :async_future;
   }
-  function returnAsync4() → FutureOr<core::int?> /* originally async */ {
+  function returnAsync4() → FutureOr<core::int?> /* futureValueType= core::int? */ /* originally async */ {
     final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -460,7 +460,7 @@
     :is_sync = true;
     return :async_future;
   }
-  function returnAsync5() → asy::Future<Null> /* originally async */ {
+  function returnAsync5() → asy::Future<Null> /* futureValueType= Null */ /* originally async */ {
     final asy::_Future<Null> :async_future = new asy::_Future::•<Null>();
     core::bool* :is_sync = false;
     Null :return_value;
@@ -484,7 +484,7 @@
     :is_sync = true;
     return :async_future;
   }
-  function returnAsync6() → asy::Future<core::int?> /* originally async */ {
+  function returnAsync6() → asy::Future<core::int?> /* futureValueType= core::int? */ /* originally async */ {
     final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
     core::bool* :is_sync = false;
     FutureOr<core::int?>? :return_value;
@@ -511,7 +511,7 @@
     :is_sync = true;
     return :async_future;
   }
-  function returnAsync7() → asy::Future<core::int?> /* originally async */ {
+  function returnAsync7() → asy::Future<core::int?> /* futureValueType= core::int? */ /* originally async */ {
     final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
     core::bool* :is_sync = false;
     core::int? :return_value;
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect
index 60fc699..015e678 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect
@@ -92,19 +92,19 @@
 String returnMixed(bool b) /*error*/ {
        ^" in null;
 }
-static method returnAsync1() → asy::Future<dynamic> async {}
-static method returnAsync2() → FutureOr<dynamic> async {}
-static method returnAsync3() → FutureOr<core::int> async {
+static method returnAsync1() → asy::Future<dynamic> async /* futureValueType= dynamic */ {}
+static method returnAsync2() → FutureOr<dynamic> async /* futureValueType= dynamic */ {}
+static method returnAsync3() → FutureOr<core::int> async /* futureValueType= core::int */ {
   return invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:27:15: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
 FutureOr<int> returnAsync3() async {} // error
               ^" in null;
 }
-static method returnAsync4() → FutureOr<core::int?> async {}
-static method returnAsync5() → dynamic async {}
-static method returnAsync6() → asy::Future<core::int?> async {
+static method returnAsync4() → FutureOr<core::int?> async /* futureValueType= core::int? */ {}
+static method returnAsync5() → dynamic async /* futureValueType= dynamic */ {}
+static method returnAsync6() → asy::Future<core::int?> async /* futureValueType= core::int? */ {
   return null;
 }
-static method returnAsync7() → asy::Future<core::int?> async {}
+static method returnAsync7() → asy::Future<core::int?> async /* futureValueType= core::int? */ {}
 static method yieldSync() → core::Iterable<dynamic> sync* {}
 static method yieldAsync() → asy::Stream<dynamic> async* {}
 static method caseReturn1(self::Enum e) → self::Enum {
@@ -164,19 +164,19 @@
   String returnMixed(bool b) /* error */ {
   ^" in null;
   }
-  function returnAsync1() → asy::Future<dynamic> async {}
-  function returnAsync2() → FutureOr<dynamic> async {}
-  function returnAsync3() → FutureOr<core::int> async {
+  function returnAsync1() → asy::Future<dynamic> async /* futureValueType= dynamic */ {}
+  function returnAsync2() → FutureOr<dynamic> async /* futureValueType= dynamic */ {}
+  function returnAsync3() → FutureOr<core::int> async /* futureValueType= core::int */ {
     return invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:83:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
   FutureOr<int> returnAsync3() async {} // error
   ^" in null;
   }
-  function returnAsync4() → FutureOr<core::int?> async {}
-  function returnAsync5() → asy::Future<Null> async {}
-  function returnAsync6() → asy::Future<core::int?> async {
+  function returnAsync4() → FutureOr<core::int?> async /* futureValueType= core::int? */ {}
+  function returnAsync5() → asy::Future<Null> async /* futureValueType= Null */ {}
+  function returnAsync6() → asy::Future<core::int?> async /* futureValueType= core::int? */ {
     return null;
   }
-  function returnAsync7() → asy::Future<core::int?> async {}
+  function returnAsync7() → asy::Future<core::int?> async /* futureValueType= core::int? */ {}
   function yieldSync() → core::Iterable<dynamic> sync* {}
   function yieldAsync() → asy::Stream<dynamic> async* {}
   function caseReturn1(self::Enum e) → self::Enum {
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.modular.expect
index 60fc699..015e678 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.modular.expect
@@ -92,19 +92,19 @@
 String returnMixed(bool b) /*error*/ {
        ^" in null;
 }
-static method returnAsync1() → asy::Future<dynamic> async {}
-static method returnAsync2() → FutureOr<dynamic> async {}
-static method returnAsync3() → FutureOr<core::int> async {
+static method returnAsync1() → asy::Future<dynamic> async /* futureValueType= dynamic */ {}
+static method returnAsync2() → FutureOr<dynamic> async /* futureValueType= dynamic */ {}
+static method returnAsync3() → FutureOr<core::int> async /* futureValueType= core::int */ {
   return invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:27:15: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
 FutureOr<int> returnAsync3() async {} // error
               ^" in null;
 }
-static method returnAsync4() → FutureOr<core::int?> async {}
-static method returnAsync5() → dynamic async {}
-static method returnAsync6() → asy::Future<core::int?> async {
+static method returnAsync4() → FutureOr<core::int?> async /* futureValueType= core::int? */ {}
+static method returnAsync5() → dynamic async /* futureValueType= dynamic */ {}
+static method returnAsync6() → asy::Future<core::int?> async /* futureValueType= core::int? */ {
   return null;
 }
-static method returnAsync7() → asy::Future<core::int?> async {}
+static method returnAsync7() → asy::Future<core::int?> async /* futureValueType= core::int? */ {}
 static method yieldSync() → core::Iterable<dynamic> sync* {}
 static method yieldAsync() → asy::Stream<dynamic> async* {}
 static method caseReturn1(self::Enum e) → self::Enum {
@@ -164,19 +164,19 @@
   String returnMixed(bool b) /* error */ {
   ^" in null;
   }
-  function returnAsync1() → asy::Future<dynamic> async {}
-  function returnAsync2() → FutureOr<dynamic> async {}
-  function returnAsync3() → FutureOr<core::int> async {
+  function returnAsync1() → asy::Future<dynamic> async /* futureValueType= dynamic */ {}
+  function returnAsync2() → FutureOr<dynamic> async /* futureValueType= dynamic */ {}
+  function returnAsync3() → FutureOr<core::int> async /* futureValueType= core::int */ {
     return invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:83:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
   FutureOr<int> returnAsync3() async {} // error
   ^" in null;
   }
-  function returnAsync4() → FutureOr<core::int?> async {}
-  function returnAsync5() → asy::Future<Null> async {}
-  function returnAsync6() → asy::Future<core::int?> async {
+  function returnAsync4() → FutureOr<core::int?> async /* futureValueType= core::int? */ {}
+  function returnAsync5() → asy::Future<Null> async /* futureValueType= Null */ {}
+  function returnAsync6() → asy::Future<core::int?> async /* futureValueType= core::int? */ {
     return null;
   }
-  function returnAsync7() → asy::Future<core::int?> async {}
+  function returnAsync7() → asy::Future<core::int?> async /* futureValueType= core::int? */ {}
   function yieldSync() → core::Iterable<dynamic> sync* {}
   function yieldAsync() → asy::Stream<dynamic> async* {}
   function caseReturn1(self::Enum e) → self::Enum {
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
index 09a90f2..43cc638 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
@@ -92,7 +92,7 @@
 String returnMixed(bool b) /*error*/ {
        ^" in null;
 }
-static method returnAsync1() → asy::Future<dynamic> /* originally async */ {
+static method returnAsync1() → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -116,7 +116,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnAsync2() → FutureOr<dynamic> /* originally async */ {
+static method returnAsync2() → FutureOr<dynamic> /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -140,7 +140,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnAsync3() → FutureOr<core::int> /* originally async */ {
+static method returnAsync3() → FutureOr<core::int> /* futureValueType= core::int */ /* originally async */ {
   final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
   core::bool* :is_sync = false;
   FutureOr<core::int>? :return_value;
@@ -169,7 +169,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnAsync4() → FutureOr<core::int?> /* originally async */ {
+static method returnAsync4() → FutureOr<core::int?> /* futureValueType= core::int? */ /* originally async */ {
   final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
   core::bool* :is_sync = false;
   core::int? :return_value;
@@ -193,7 +193,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnAsync5() → dynamic /* originally async */ {
+static method returnAsync5() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -217,7 +217,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnAsync6() → asy::Future<core::int?> /* originally async */ {
+static method returnAsync6() → asy::Future<core::int?> /* futureValueType= core::int? */ /* originally async */ {
   final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
   core::bool* :is_sync = false;
   FutureOr<core::int?>? :return_value;
@@ -244,7 +244,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method returnAsync7() → asy::Future<core::int?> /* originally async */ {
+static method returnAsync7() → asy::Future<core::int?> /* futureValueType= core::int? */ /* originally async */ {
   final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
   core::bool* :is_sync = false;
   core::int? :return_value;
@@ -363,7 +363,7 @@
   String returnMixed(bool b) /* error */ {
   ^" in null;
   }
-  function returnAsync1() → asy::Future<dynamic> /* originally async */ {
+  function returnAsync1() → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
     final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     dynamic :return_value;
@@ -387,7 +387,7 @@
     :is_sync = true;
     return :async_future;
   }
-  function returnAsync2() → FutureOr<dynamic> /* originally async */ {
+  function returnAsync2() → FutureOr<dynamic> /* futureValueType= dynamic */ /* originally async */ {
     final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     dynamic :return_value;
@@ -411,7 +411,7 @@
     :is_sync = true;
     return :async_future;
   }
-  function returnAsync3() → FutureOr<core::int> /* originally async */ {
+  function returnAsync3() → FutureOr<core::int> /* futureValueType= core::int */ /* originally async */ {
     final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
     core::bool* :is_sync = false;
     FutureOr<core::int>? :return_value;
@@ -440,7 +440,7 @@
     :is_sync = true;
     return :async_future;
   }
-  function returnAsync4() → FutureOr<core::int?> /* originally async */ {
+  function returnAsync4() → FutureOr<core::int?> /* futureValueType= core::int? */ /* originally async */ {
     final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -464,7 +464,7 @@
     :is_sync = true;
     return :async_future;
   }
-  function returnAsync5() → asy::Future<Null> /* originally async */ {
+  function returnAsync5() → asy::Future<Null> /* futureValueType= Null */ /* originally async */ {
     final asy::_Future<Null> :async_future = new asy::_Future::•<Null>();
     core::bool* :is_sync = false;
     Null :return_value;
@@ -488,7 +488,7 @@
     :is_sync = true;
     return :async_future;
   }
-  function returnAsync6() → asy::Future<core::int?> /* originally async */ {
+  function returnAsync6() → asy::Future<core::int?> /* futureValueType= core::int? */ /* originally async */ {
     final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
     core::bool* :is_sync = false;
     FutureOr<core::int?>? :return_value;
@@ -515,7 +515,7 @@
     :is_sync = true;
     return :async_future;
   }
-  function returnAsync7() → asy::Future<core::int?> /* originally async */ {
+  function returnAsync7() → asy::Future<core::int?> /* futureValueType= core::int? */ /* originally async */ {
     final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
     core::bool* :is_sync = false;
     core::int? :return_value;
diff --git a/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.expect
index fd8e4a3..6608d90 100644
--- a/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.expect
@@ -2,10 +2,10 @@
 import self as self;
 import "dart:async" as asy;
 
-static method returnFutureOfVoid() → asy::Future<void>* async {}
+static method returnFutureOfVoid() → asy::Future<void>* async /* futureValueType= void */ {}
 static method returnVoid() → void {}
-static method returnVoidAsync() → void async {}
-static method main() → dynamic async {
+static method returnVoidAsync() → void async /* futureValueType= void */ {}
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await self::returnVoid();
   await self::returnFutureOfVoid();
   await self::returnVoidAsync();
diff --git a/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.modular.expect
index fd8e4a3..6608d90 100644
--- a/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.modular.expect
@@ -2,10 +2,10 @@
 import self as self;
 import "dart:async" as asy;
 
-static method returnFutureOfVoid() → asy::Future<void>* async {}
+static method returnFutureOfVoid() → asy::Future<void>* async /* futureValueType= void */ {}
 static method returnVoid() → void {}
-static method returnVoidAsync() → void async {}
-static method main() → dynamic async {
+static method returnVoidAsync() → void async /* futureValueType= void */ {}
+static method main() → dynamic async /* futureValueType= dynamic */ {
   await self::returnVoid();
   await self::returnFutureOfVoid();
   await self::returnVoidAsync();
diff --git a/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.transformed.expect
index 19c9552..5dcce49 100644
--- a/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/issue41602.dart.weak.transformed.expect
@@ -4,7 +4,7 @@
 import "dart:core" as core;
 import "dart:_internal" as _in;
 
-static method returnFutureOfVoid() → asy::Future<void>* /* originally async */ {
+static method returnFutureOfVoid() → asy::Future<void>* /* futureValueType= void */ /* originally async */ {
   final asy::_Future<void>* :async_future = new asy::_Future::•<void>();
   core::bool* :is_sync = false;
   void :return_value;
@@ -29,7 +29,7 @@
   return :async_future;
 }
 static method returnVoid() → void {}
-static method returnVoidAsync() → void /* originally async */ {
+static method returnVoidAsync() → void /* futureValueType= void */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -53,7 +53,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.expect
index bebc221..f52e2c9 100644
--- a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.expect
@@ -7,7 +7,7 @@
 import "org-dartlang-testcase:///typedef_from_opt_in_lib.dart";
 
 static method method1() → (typ::Request*) →* FutureOr<typ::Response*>*
-  return (typ::Request* r) → asy::Future<typ::Response*>* async => new typ::Response::•();
+  return (typ::Request* r) → asy::Future<typ::Response*>* async /* futureValueType= typ::Response* */ => new typ::Response::•();
 static method method2() → (core::int*) →* core::int*
   return (core::int* r) → core::int* => 0;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.modular.expect b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.modular.expect
index bebc221..f52e2c9 100644
--- a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.modular.expect
@@ -7,7 +7,7 @@
 import "org-dartlang-testcase:///typedef_from_opt_in_lib.dart";
 
 static method method1() → (typ::Request*) →* FutureOr<typ::Response*>*
-  return (typ::Request* r) → asy::Future<typ::Response*>* async => new typ::Response::•();
+  return (typ::Request* r) → asy::Future<typ::Response*>* async /* futureValueType= typ::Response* */ => new typ::Response::•();
 static method method2() → (core::int*) →* core::int*
   return (core::int* r) → core::int* => 0;
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.transformed.expect
index 055f5af..05711ed 100644
--- a/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/typedef_from_opt_in.dart.weak.transformed.expect
@@ -7,7 +7,7 @@
 import "org-dartlang-testcase:///typedef_from_opt_in_lib.dart";
 
 static method method1() → (typ::Request*) →* FutureOr<typ::Response*>*
-  return (typ::Request* r) → asy::Future<typ::Response*>* /* originally async */ {
+  return (typ::Request* r) → asy::Future<typ::Response*>* /* futureValueType= typ::Response* */ /* originally async */ {
     final asy::_Future<typ::Response*>* :async_future = new asy::_Future::•<typ::Response*>();
     core::bool* :is_sync = false;
     typ::Response? :return_value;
diff --git a/pkg/front_end/testcases/regress/issue_34850.dart.weak.expect b/pkg/front_end/testcases/regress/issue_34850.dart.weak.expect
index ad3a1ce..9e29266 100644
--- a/pkg/front_end/testcases/regress/issue_34850.dart.weak.expect
+++ b/pkg/front_end/testcases/regress/issue_34850.dart.weak.expect
@@ -57,12 +57,12 @@
   return null;
 }
 static method Future<List extends core::Object* = dynamic>() → invalid-type {}
-static method f2() → dynamic async 
+static method f2() → dynamic async /* futureValueType= dynamic */ 
   return null;
-static method f3() → invalid-type async {
+static method f3() → invalid-type async /* futureValueType= invalid-type */ {
   return null;
 }
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   core::print(self::f1());
   core::print(await self::f2());
   core::print(await self::f3());
diff --git a/pkg/front_end/testcases/regress/issue_34850.dart.weak.modular.expect b/pkg/front_end/testcases/regress/issue_34850.dart.weak.modular.expect
index ad3a1ce..9e29266 100644
--- a/pkg/front_end/testcases/regress/issue_34850.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/regress/issue_34850.dart.weak.modular.expect
@@ -57,12 +57,12 @@
   return null;
 }
 static method Future<List extends core::Object* = dynamic>() → invalid-type {}
-static method f2() → dynamic async 
+static method f2() → dynamic async /* futureValueType= dynamic */ 
   return null;
-static method f3() → invalid-type async {
+static method f3() → invalid-type async /* futureValueType= invalid-type */ {
   return null;
 }
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   core::print(self::f1());
   core::print(await self::f2());
   core::print(await self::f3());
diff --git a/pkg/front_end/testcases/regress/issue_34850.dart.weak.transformed.expect b/pkg/front_end/testcases/regress/issue_34850.dart.weak.transformed.expect
index 4463725..6ded2e6 100644
--- a/pkg/front_end/testcases/regress/issue_34850.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34850.dart.weak.transformed.expect
@@ -59,7 +59,7 @@
   return null;
 }
 static method Future<List extends core::Object* = dynamic>() → invalid-type {}
-static method f2() → dynamic /* originally async */ {
+static method f2() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
@@ -86,7 +86,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method f3() → invalid-type /* originally async */ {
+static method f3() → invalid-type /* futureValueType= invalid-type */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
@@ -113,7 +113,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/front_end/testcases/regress/issue_37681.dart.weak.expect b/pkg/front_end/testcases/regress/issue_37681.dart.weak.expect
index c92257e..668dece 100644
--- a/pkg/front_end/testcases/regress/issue_37681.dart.weak.expect
+++ b/pkg/front_end/testcases/regress/issue_37681.dart.weak.expect
@@ -18,8 +18,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
-static method main() → dynamic async {
-  function f_async() → core::int* async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
+  function f_async() → core::int* async /* futureValueType= core::int* */ {
     return 42;
   }
   core::print(await f_async(){() →* core::int*});
diff --git a/pkg/front_end/testcases/regress/issue_37681.dart.weak.modular.expect b/pkg/front_end/testcases/regress/issue_37681.dart.weak.modular.expect
index c92257e..668dece 100644
--- a/pkg/front_end/testcases/regress/issue_37681.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/regress/issue_37681.dart.weak.modular.expect
@@ -18,8 +18,8 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
-static method main() → dynamic async {
-  function f_async() → core::int* async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
+  function f_async() → core::int* async /* futureValueType= core::int* */ {
     return 42;
   }
   core::print(await f_async(){() →* core::int*});
diff --git a/pkg/front_end/testcases/regress/issue_37681.dart.weak.transformed.expect b/pkg/front_end/testcases/regress/issue_37681.dart.weak.transformed.expect
index 2048398..9edac46 100644
--- a/pkg/front_end/testcases/regress/issue_37681.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_37681.dart.weak.transformed.expect
@@ -19,7 +19,7 @@
 import "dart:core" as core;
 import "dart:_internal" as _in;
 
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -35,7 +35,7 @@
     try {
       #L1:
       {
-        function f_async() → core::int* /* originally async */ {
+        function f_async() → core::int* /* futureValueType= core::int* */ /* originally async */ {
           final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
           core::bool* :is_sync = false;
           dynamic :return_value;
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.expect
index d565d03..358bace 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.expect
@@ -52,7 +52,7 @@
 import "dart:async" show FutureOr;
 import "dart:collection" show LinkedHashMap, LinkedHashSet;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   core::Map<core::int*, core::bool*>* m = <core::int*, core::bool*>{};
   core::Set<core::int*>* s = block {
     final core::Set<core::int*>* #t1 = col::LinkedHashSet::•<core::int*>();
@@ -85,17 +85,17 @@
   col::LinkedHashSet<core::int*>* flhs2 = await self::lhsfun2();
   col::LinkedHashMap<core::int*, core::bool*>* flhm2 = await self::lhmfun2();
 }
-static method mapfun() → asy::Future<core::Map<core::int*, core::bool*>*>* async 
+static method mapfun() → asy::Future<core::Map<core::int*, core::bool*>*>* async /* futureValueType= core::Map<core::int*, core::bool*>* */ 
   return <core::int*, core::bool*>{};
-static method setfun() → asy::Future<core::Set<core::int*>*>* async 
+static method setfun() → asy::Future<core::Set<core::int*>*>* async /* futureValueType= core::Set<core::int*>* */ 
   return block {
     final core::Set<core::int*>* #t4 = col::LinkedHashSet::•<core::int*>();
   } =>#t4;
-static method iterablefun() → asy::Future<core::Iterable<core::int*>*>* async 
+static method iterablefun() → asy::Future<core::Iterable<core::int*>*>* async /* futureValueType= core::Iterable<core::int*>* */ 
   return block {
     final core::Set<core::int*>* #t5 = col::LinkedHashSet::•<core::int*>();
   } =>#t5;
-static method lhsfun() → asy::Future<col::LinkedHashSet<core::int*>*>* async 
+static method lhsfun() → asy::Future<col::LinkedHashSet<core::int*>*>* async /* futureValueType= col::LinkedHashSet<core::int*>* */ 
   return invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Future<Set<dynamic>>' isn't of expected type 'Future<LinkedHashSet<int>>'.
  - 'Future' is from 'dart:async'.
  - 'Set' is from 'dart:core'.
@@ -105,7 +105,7 @@
                                              ^" in block {
     final core::Set<dynamic>* #t6 = col::LinkedHashSet::•<dynamic>();
   } =>#t6;
-static method lhmfun() → asy::Future<col::LinkedHashMap<core::int*, core::bool*>*>* async 
+static method lhmfun() → asy::Future<col::LinkedHashMap<core::int*, core::bool*>*>* async /* futureValueType= col::LinkedHashMap<core::int*, core::bool*>* */ 
   return invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Future<Map<dynamic, dynamic>>' isn't of expected type 'Future<LinkedHashMap<int, bool>>'.
  - 'Future' is from 'dart:async'.
  - 'Map' is from 'dart:core'.
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.modular.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.modular.expect
index d565d03..358bace 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.modular.expect
@@ -52,7 +52,7 @@
 import "dart:async" show FutureOr;
 import "dart:collection" show LinkedHashMap, LinkedHashSet;
 
-static method main() → dynamic async {
+static method main() → dynamic async /* futureValueType= dynamic */ {
   core::Map<core::int*, core::bool*>* m = <core::int*, core::bool*>{};
   core::Set<core::int*>* s = block {
     final core::Set<core::int*>* #t1 = col::LinkedHashSet::•<core::int*>();
@@ -85,17 +85,17 @@
   col::LinkedHashSet<core::int*>* flhs2 = await self::lhsfun2();
   col::LinkedHashMap<core::int*, core::bool*>* flhm2 = await self::lhmfun2();
 }
-static method mapfun() → asy::Future<core::Map<core::int*, core::bool*>*>* async 
+static method mapfun() → asy::Future<core::Map<core::int*, core::bool*>*>* async /* futureValueType= core::Map<core::int*, core::bool*>* */ 
   return <core::int*, core::bool*>{};
-static method setfun() → asy::Future<core::Set<core::int*>*>* async 
+static method setfun() → asy::Future<core::Set<core::int*>*>* async /* futureValueType= core::Set<core::int*>* */ 
   return block {
     final core::Set<core::int*>* #t4 = col::LinkedHashSet::•<core::int*>();
   } =>#t4;
-static method iterablefun() → asy::Future<core::Iterable<core::int*>*>* async 
+static method iterablefun() → asy::Future<core::Iterable<core::int*>*>* async /* futureValueType= core::Iterable<core::int*>* */ 
   return block {
     final core::Set<core::int*>* #t5 = col::LinkedHashSet::•<core::int*>();
   } =>#t5;
-static method lhsfun() → asy::Future<col::LinkedHashSet<core::int*>*>* async 
+static method lhsfun() → asy::Future<col::LinkedHashSet<core::int*>*>* async /* futureValueType= col::LinkedHashSet<core::int*>* */ 
   return invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:32:46: Error: The set literal type 'Future<Set<dynamic>>' isn't of expected type 'Future<LinkedHashSet<int>>'.
  - 'Future' is from 'dart:async'.
  - 'Set' is from 'dart:core'.
@@ -105,7 +105,7 @@
                                              ^" in block {
     final core::Set<dynamic>* #t6 = col::LinkedHashSet::•<dynamic>();
   } =>#t6;
-static method lhmfun() → asy::Future<col::LinkedHashMap<core::int*, core::bool*>*>* async 
+static method lhmfun() → asy::Future<col::LinkedHashMap<core::int*, core::bool*>*>* async /* futureValueType= col::LinkedHashMap<core::int*, core::bool*>* */ 
   return invalid-expression "pkg/front_end/testcases/set_literals/disambiguation_rule.dart:33:52: Error: The map literal type 'Future<Map<dynamic, dynamic>>' isn't of expected type 'Future<LinkedHashMap<int, bool>>'.
  - 'Future' is from 'dart:async'.
  - 'Map' is from 'dart:core'.
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.transformed.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.transformed.expect
index 1578723..b7585e0 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.weak.transformed.expect
@@ -53,7 +53,7 @@
 import "dart:async" show FutureOr;
 import "dart:collection" show LinkedHashMap, LinkedHashSet;
 
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -120,7 +120,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method mapfun() → asy::Future<core::Map<core::int*, core::bool*>*>* /* originally async */ {
+static method mapfun() → asy::Future<core::Map<core::int*, core::bool*>*>* /* futureValueType= core::Map<core::int*, core::bool*>* */ /* originally async */ {
   final asy::_Future<core::Map<core::int*, core::bool*>*>* :async_future = new asy::_Future::•<core::Map<core::int*, core::bool*>*>();
   core::bool* :is_sync = false;
   core::Map<core::int*, core::bool*>? :return_value;
@@ -147,7 +147,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method setfun() → asy::Future<core::Set<core::int*>*>* /* originally async */ {
+static method setfun() → asy::Future<core::Set<core::int*>*>* /* futureValueType= core::Set<core::int*>* */ /* originally async */ {
   final asy::_Future<core::Set<core::int*>*>* :async_future = new asy::_Future::•<core::Set<core::int*>*>();
   core::bool* :is_sync = false;
   core::Set<core::int*>? :return_value;
@@ -176,7 +176,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method iterablefun() → asy::Future<core::Iterable<core::int*>*>* /* originally async */ {
+static method iterablefun() → asy::Future<core::Iterable<core::int*>*>* /* futureValueType= core::Iterable<core::int*>* */ /* originally async */ {
   final asy::_Future<core::Iterable<core::int*>*>* :async_future = new asy::_Future::•<core::Iterable<core::int*>*>();
   core::bool* :is_sync = false;
   core::Iterable<core::int*>? :return_value;
@@ -205,7 +205,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method lhsfun() → asy::Future<col::LinkedHashSet<core::int*>*>* /* originally async */ {
+static method lhsfun() → asy::Future<col::LinkedHashSet<core::int*>*>* /* futureValueType= col::LinkedHashSet<core::int*>* */ /* originally async */ {
   final asy::_Future<col::LinkedHashSet<core::int*>*>* :async_future = new asy::_Future::•<col::LinkedHashSet<core::int*>*>();
   core::bool* :is_sync = false;
   FutureOr<col::LinkedHashSet<core::int*>*>* :return_value;
@@ -240,7 +240,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method lhmfun() → asy::Future<col::LinkedHashMap<core::int*, core::bool*>*>* /* originally async */ {
+static method lhmfun() → asy::Future<col::LinkedHashMap<core::int*, core::bool*>*>* /* futureValueType= col::LinkedHashMap<core::int*, core::bool*>* */ /* originally async */ {
   final asy::_Future<col::LinkedHashMap<core::int*, core::bool*>*>* :async_future = new asy::_Future::•<col::LinkedHashMap<core::int*, core::bool*>*>();
   core::bool* :is_sync = false;
   FutureOr<col::LinkedHashMap<core::int*, core::bool*>*>* :return_value;
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index cbf0d44..28d8c84 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -3673,6 +3673,10 @@
   /// here the return types are `Future<Foo>` and `FutureOr<Foo>` for `method1`
   /// and `method2`, respectively, but the future value type is in both cases
   /// `Foo`.
+  ///
+  /// For pre-nnbd libraries, this is set to `flatten(T)` of the return type
+  /// `T`, which can be seen as the pre-nnbd equivalent of the future value
+  /// type.
   DartType? futureValueType;
 
   void Function()? lazyBuilder;
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index dafccc6..94b7cf2 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -787,6 +787,11 @@
     if (function.asyncMarker != AsyncMarker.Sync) {
       writeSpaced(getAsyncMarkerKeyword(function.asyncMarker));
     }
+    if (function.futureValueType != null) {
+      writeSpaced("/* futureValueType=");
+      writeNode(function.futureValueType);
+      writeSpaced("*/");
+    }
     if (function.dartAsyncMarker != AsyncMarker.Sync &&
         function.dartAsyncMarker != function.asyncMarker) {
       writeSpaced("/* originally");
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index 051bc3a..858e978 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -440,7 +440,6 @@
     AsyncMarker savedAsyncMarker = currentAsyncMarker;
     currentAsyncMarker = node.asyncMarker;
     if (!isOutline &&
-        currentMember!.isNonNullableByDefault &&
         node.asyncMarker == AsyncMarker.Async &&
         node.futureValueType == null) {
       problem(node,
diff --git a/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect b/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect
index a881185..ec6468f 100644
--- a/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect
+++ b/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect
@@ -45,7 +45,7 @@
 
   import "#pkg/vm/testcases/transformations/deferred_loading/a.dart" as a;
 
-  static method j() → dynamic /* originally async */ {
+  static method j() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     dynamic :return_value;
@@ -76,7 +76,7 @@
 
   import "#pkg/vm/testcases/transformations/deferred_loading/g.dart" as g;
 
-  static method h() → dynamic /* originally async */ {
+  static method h() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     dynamic :return_value;
@@ -108,7 +108,7 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/j.dart" deferred as j;
   import "#pkg/vm/testcases/transformations/deferred_loading/b.dart" as b;
 
-  static method i() → dynamic /* originally async */ {
+  static method i() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
@@ -144,7 +144,7 @@
 
   import "#pkg/vm/testcases/transformations/deferred_loading/h.dart" as h;
 
-  static method g() → dynamic /* originally async */ {
+  static method g() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     dynamic :return_value;
@@ -176,7 +176,7 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/g.dart" deferred as g;
   import "#pkg/vm/testcases/transformations/deferred_loading/i.dart" deferred as i;
 
-  static method f() → dynamic /* originally async */ {
+  static method f() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
@@ -216,7 +216,7 @@
 
   import "#pkg/vm/testcases/transformations/deferred_loading/g.dart" deferred as g;
 
-  static method e() → dynamic /* originally async */ {
+  static method e() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
@@ -253,7 +253,7 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/b.dart" as b;
   import "#pkg/vm/testcases/transformations/deferred_loading/f.dart" deferred as f;
 
-  static method c() → dynamic /* originally async */ {
+  static method c() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
@@ -289,7 +289,7 @@
 
   import "#pkg/vm/testcases/transformations/deferred_loading/e.dart" as e;
 
-  static method d() → dynamic /* originally async */ {
+  static method d() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
@@ -322,7 +322,7 @@
 
   import "#pkg/vm/testcases/transformations/deferred_loading/c.dart" as c;
 
-  static method b() → dynamic /* originally async */ {
+  static method b() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
@@ -355,7 +355,7 @@
 
   import "#pkg/vm/testcases/transformations/deferred_loading/d.dart" deferred as d;
 
-  static method a() → dynamic /* originally async */ {
+  static method a() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
@@ -392,7 +392,7 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/a.dart";
   import "#pkg/vm/testcases/transformations/deferred_loading/b.dart";
 
-  static method main() → dynamic /* originally async */ {
+  static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
     final dart.async::_Future<dynamic> :async_future = new dart.async::_Future::•<dynamic>();
     dart.core::bool* :is_sync = false;
     dynamic :return_value;
diff --git a/pkg/vm/testcases/transformations/ffi/finalizable_async.dart.expect b/pkg/vm/testcases/transformations/ffi/finalizable_async.dart.expect
index e098162..2adb29e 100644
--- a/pkg/vm/testcases/transformations/ffi/finalizable_async.dart.expect
+++ b/pkg/vm/testcases/transformations/ffi/finalizable_async.dart.expect
@@ -11,7 +11,7 @@
   synthetic constructor •() → self::MyFinalizable
     : super core::Object::•()
     ;
-  method use() → asy::Future<core::int> /* originally async */ {
+  method use() → asy::Future<core::int> /* futureValueType= core::int */ /* originally async */ {
     final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
     core::bool* :is_sync = false;
     FutureOr<core::int>? :return_value;
@@ -41,7 +41,7 @@
     :is_sync = true;
     return :async_future;
   }
-  method use2() → asy::Future<core::int> /* originally async */ {
+  method use2() → asy::Future<core::int> /* futureValueType= core::int */ /* originally async */ {
     final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
     core::bool* :is_sync = false;
     core::int? :return_value;
@@ -83,7 +83,7 @@
     } =>:expressionValueWrappedFinalizable;
   }
 }
-static method doSomething() → asy::Future<core::int> /* originally async */ {
+static method doSomething() → asy::Future<core::int> /* futureValueType= core::int */ /* originally async */ {
   final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
   core::bool* :is_sync = false;
   core::int? :return_value;
@@ -110,7 +110,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method useFinalizableAsync(ffi::Finalizable finalizable) → asy::Future<core::int> /* originally async */ {
+static method useFinalizableAsync(ffi::Finalizable finalizable) → asy::Future<core::int> /* futureValueType= core::int */ /* originally async */ {
   final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
   core::bool* :is_sync = false;
   FutureOr<core::int>? :return_value;
@@ -163,7 +163,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method main() → void /* originally async */ {
+static method main() → void /* futureValueType= void */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/vm/testcases/transformations/ffi/finalizable_async_star.dart.expect b/pkg/vm/testcases/transformations/ffi/finalizable_async_star.dart.expect
index 18fae35..74e5fe6 100644
--- a/pkg/vm/testcases/transformations/ffi/finalizable_async_star.dart.expect
+++ b/pkg/vm/testcases/transformations/ffi/finalizable_async_star.dart.expect
@@ -84,7 +84,7 @@
   :controller_stream = :controller.{asy::_AsyncStarStreamController::stream}{asy::Stream<core::int>};
   return :controller_stream;
 }
-static method main() → void /* originally async */ {
+static method main() → void /* futureValueType= void */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
index da5be5f..0d6b3b9 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
@@ -7,7 +7,7 @@
   synthetic constructor •() → self::A
     : super core::Object::•()
     ;
-[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method bar(dynamic x) → asy::Future<dynamic> /* originally async */ {
+[@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method bar(dynamic x) → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
     final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
     core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
@@ -42,7 +42,7 @@
 }
 static method foo() → dynamic
   return new self::A::•();
-static method baz() → asy::Future<dynamic> /* originally async */ {
+static method baz() → asy::Future<dynamic> /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
@@ -69,7 +69,7 @@
   :is_sync = true;
   return :async_future;
 }
-static method main() → dynamic /* originally async */ {
+static method main() → dynamic /* futureValueType= dynamic */ /* originally async */ {
   final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
   core::bool* :is_sync = false;
   dynamic :return_value;
diff --git a/runtime/vm/type_testing_stubs_test.cc b/runtime/vm/type_testing_stubs_test.cc
index 6d3d94b..2a0f8e9 100644
--- a/runtime/vm/type_testing_stubs_test.cc
+++ b/runtime/vm/type_testing_stubs_test.cc
@@ -2272,7 +2272,7 @@
 //
 // To ensure that the register is clobbered on all architectures, we set things
 // up by generating the following classes:
-// * B<X>, an generic abstract class which is implemented by the others.
+// * B<X>, a generic abstract class which is implemented by the others.
 // * I, implements B<String>, has a single int field x, and is
 //   used to create the checked instance.
 // * G<Y>, which implements B<Y> and has no fields (so its TAV field
@@ -2284,26 +2284,33 @@
 // We'll carefully set things up so that the following equation between their
 // class ids holds:
 //
-//   G =  I - C.
+//   G = I - C.
 //
 // Thus, when we create a TTS for B<int> and check it against an instance V
 // of I. The cid for I will be loaded into a register R, and then two
 // check blocks will be generated:
 //
-//   * A check for the cid range [C-D], hich has the side effect of
+//   * A check for the cid range [C-D], which has the side effect of
 //     subtracting the cid of C from the contents of R (here, the cid of I).
 //
 //   * A check that R contains the cid for G.
 //
 // Thus, if the cid of I is not reloaded into R before the second check, and
-// the equation earlier holds,we'll get a false positive that V is an instance
+// the equation earlier holds, we'll get a false positive that V is an instance
 // of G, so the code will then try to load the instance type arguments from V
 // as if it was an instance of G. This means the contents of x will be loaded
 // and attempted to be used as a TypeArgumentsPtr, which will cause a crash
 // during the checks that the instantiation of Y is int.
 ISOLATE_UNIT_TEST_CASE(TTS_Regress_CidRangeChecks) {
-  // Bump this appropriately if the EXPECT_EQ below fails.
-  const intptr_t kNumUnrelated = 1186;
+  // We create the classes in this order: B, G, C, D, U..., I. We need
+  // G = I - C => G + C = I
+  //           => G + C = D + N + 1 (where N is the number of U classes)
+  //           => (B + 1) + C = (C + 1) + N + 1
+  //           => B - 1 = N.
+  // The cid for B will be the next allocated cid, which is the number of
+  // non-top-level cids in the current class table.
+  ClassTable* const class_table = IsolateGroup::Current()->class_table();
+  const intptr_t kNumUnrelated = class_table->NumCids() - 1;
   TextBuffer buffer(1024);
   buffer.AddString(R"(
       abstract class B<X> {}
@@ -2329,6 +2336,8 @@
   const auto& class_b = Class::Handle(GetClass(root_library, "B"));
   const auto& class_g = Class::Handle(GetClass(root_library, "G"));
   const auto& class_c = Class::Handle(GetClass(root_library, "C"));
+  const auto& class_d = Class::Handle(GetClass(root_library, "D"));
+  const auto& class_u0 = Class::Handle(GetClass(root_library, "U0"));
   const auto& class_i = Class::Handle(GetClass(root_library, "I"));
   const auto& obj_i = Object::Handle(Invoke(root_library, "createI"));
   {
@@ -2336,6 +2345,12 @@
     ClassFinalizer::FinalizeClass(class_g);
   }
 
+  // Double-check assumptions from calculating kNumUnrelated.
+  EXPECT_EQ(kNumUnrelated, class_b.id() - 1);
+  EXPECT_EQ(class_b.id() + 1, class_g.id());
+  EXPECT_EQ(class_c.id() + 1, class_d.id());
+  EXPECT_EQ(class_d.id() + 1, class_u0.id());
+  EXPECT_EQ(class_u0.id() + kNumUnrelated, class_i.id());
   EXPECT_EQ(class_g.id(), class_i.id() - class_c.id());
 
   const auto& tav_null = Object::null_type_arguments();
diff --git a/tools/VERSION b/tools/VERSION
index 7ea497f3..ebc26f2 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 247
+PRERELEASE 248
 PRERELEASE_PATCH 0
\ No newline at end of file