[cfe] Use flatten(T) as future value type for pre-nnbd async functions

Change-Id: I38d537112e66c08bb06bc2493b3126b5f8f797b7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239022
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
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 69e37784..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/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/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/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/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/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/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..9486b2b2 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..9486b2b2 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/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/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,