Version 2.12.0-23.0.dev

Merge commit '27ca552ddb25b650d3c1c767ed10adf4f06ff34a' into 'dev'
diff --git a/DEPS b/DEPS
index 88473d8..702b16d 100644
--- a/DEPS
+++ b/DEPS
@@ -39,7 +39,7 @@
 
   # Checked-in SDK version. The checked-in SDK is a Dart SDK distribution in a
   # cipd package used to run Dart scripts in the build and test infrastructure.
-  "sdk_tag": "version:2.11.0-190.0.dev",
+  "sdk_tag": "version:2.12.0-0.0.dev",
 
   # co19 is a cipd package. Use update.sh in tests/co19[_2] to update these
   # hashes. It requires access to the dart-build-access group, which EngProd
@@ -145,7 +145,7 @@
   "source_map_stack_trace_rev": "1c3026f69d9771acf2f8c176a1ab750463309cce",
   "source_maps-0.9.4_rev": "38524",
   "source_maps_rev": "53eb92ccfe6e64924054f83038a534b959b12b3e",
-  "source_span_rev": "cc7c4288a83f71ecef3414199947b52a8c112c65",
+  "source_span_rev": "49ff31eabebed0da0ae6634124f8ba5c6fbf57f1",
   "sse_tag": "e5cf68975e8e87171a3dc297577aa073454a91dc",
   "stack_trace_tag": "c9c867fa9d5b9c8a059e33d3efe759698aa49d60",
   "stagehand_tag": "v3.3.9",
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes.dart
index ddece0f..5d95d3b 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes.dart
@@ -131,9 +131,11 @@
   }
 
   FormattedMessage withFormatting(String formatted, int line, int column,
-      Severity severity, List<FormattedMessage> relatedInformation) {
+      Severity severity, List<FormattedMessage> relatedInformation,
+      {List<Uri> involvedFiles}) {
     return new FormattedMessage(
-        this, formatted, line, column, severity, relatedInformation);
+        this, formatted, line, column, severity, relatedInformation,
+        involvedFiles: involvedFiles);
   }
 
   @override
@@ -173,11 +175,16 @@
 
   final List<FormattedMessage> relatedInformation;
 
+  final List<Uri> involvedFiles;
+
   const FormattedMessage(this.locatedMessage, this.formatted, this.line,
-      this.column, this.severity, this.relatedInformation);
+      this.column, this.severity, this.relatedInformation,
+      {this.involvedFiles});
 
   Code<dynamic> get code => locatedMessage.code;
 
+  String get codeName => code.name;
+
   String get message => locatedMessage.message;
 
   String get tip => locatedMessage.tip;
@@ -212,7 +219,9 @@
       "ansiFormatted": ansiFormatted.toList(),
       "plainTextFormatted": plainTextFormatted.toList(),
       "severity": severity.index,
-      "uri": uri.toString(),
+      "uri": uri?.toString(),
+      "involvedFiles": involvedFiles?.map((u) => u.toString())?.toList(),
+      "codeName": code.name,
     };
   }
 
@@ -234,8 +243,12 @@
 
   final Uri uri;
 
-  DiagnosticMessageFromJson(
-      this.ansiFormatted, this.plainTextFormatted, this.severity, this.uri);
+  final List<Uri> involvedFiles;
+
+  final String codeName;
+
+  DiagnosticMessageFromJson(this.ansiFormatted, this.plainTextFormatted,
+      this.severity, this.uri, this.involvedFiles, this.codeName);
 
   factory DiagnosticMessageFromJson.fromJson(String jsonString) {
     Map<String, Object> decoded = json.decode(jsonString);
@@ -244,10 +257,16 @@
     List<String> plainTextFormatted =
         new List<String>.from(decoded["plainTextFormatted"]);
     Severity severity = Severity.values[decoded["severity"]];
-    Uri uri = Uri.parse(decoded["uri"]);
+    Uri uri = decoded["uri"] == null ? null : Uri.parse(decoded["uri"]);
+    List<Uri> involvedFiles = decoded["involvedFiles"] == null
+        ? null
+        : new List<String>.from(decoded["involvedFiles"])
+            .map((e) => Uri.parse(e))
+            .toList();
+    String codeName = decoded["codeName"];
 
-    return new DiagnosticMessageFromJson(
-        ansiFormatted, plainTextFormatted, severity, uri);
+    return new DiagnosticMessageFromJson(ansiFormatted, plainTextFormatted,
+        severity, uri, involvedFiles, codeName);
   }
 
   Map<String, Object> toJson() {
@@ -256,7 +275,9 @@
       "ansiFormatted": ansiFormatted.toList(),
       "plainTextFormatted": plainTextFormatted.toList(),
       "severity": severity.index,
-      "uri": uri.toString(),
+      "uri": uri?.toString(),
+      "involvedFiles": involvedFiles?.map((u) => u.toString())?.toList(),
+      "codeName": codeName,
     };
   }
 
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/diagnostic_message.dart b/pkg/_fe_analyzer_shared/lib/src/messages/diagnostic_message.dart
index a1d5838..7146258 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/diagnostic_message.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/diagnostic_message.dart
@@ -34,13 +34,19 @@
   Iterable<String> get plainTextFormatted;
 
   Severity get severity;
+
+  Iterable<Uri> get involvedFiles;
+
+  String get codeName;
 }
 
 /// This method is subject to change.
 Uri getMessageUri(DiagnosticMessage message) {
   return message is FormattedMessage
       ? message.uri
-      : message is DiagnosticMessageFromJson ? message.uri : null;
+      : message is DiagnosticMessageFromJson
+          ? message.uri
+          : null;
 }
 
 /// This method is subject to change.
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
index 452db16..78ae593 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix/data_driven/modify_parameters.dart
@@ -195,7 +195,7 @@
     if (newNamed.isNotEmpty) {
       int offset;
       var needsInitialComma = false;
-      if (arguments.isEmpty) {
+      if (remainingArguments.isEmpty && argumentsToInsert.isEmpty) {
         offset = argumentList.rightParenthesis.offset;
       } else {
         offset = arguments[arguments.length - 1].end;
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index 6da76ec..015b081 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -631,7 +631,7 @@
 ''');
   }
 
-  Future<void> test_expression_updateParameters() {
+  Future<void> test_expression_updateParameters() async {
     addTestFile('''
 main() {
   int a = 1;
@@ -641,15 +641,15 @@
 }
 ''');
     _setOffsetLengthForString('a + b');
-    return getRefactoringResult(_computeChange).then((result) {
-      ExtractMethodFeedback feedback = result.feedback;
-      var parameters = feedback.parameters;
-      parameters[0].name = 'aaa';
-      parameters[1].name = 'bbb';
-      parameters[1].type = 'num';
-      parameters.insert(0, parameters.removeLast());
-      options.parameters = parameters;
-      return assertSuccessfulRefactoring(_sendExtractRequest, '''
+    var result = await getRefactoringResult(_computeChange);
+    ExtractMethodFeedback feedback = result.feedback;
+    var parameters = feedback.parameters;
+    parameters[0].name = 'aaa';
+    parameters[1].name = 'bbb';
+    parameters[1].type = 'num';
+    parameters.insert(0, parameters.removeLast());
+    options.parameters = parameters;
+    return assertSuccessfulRefactoring(_sendExtractRequest, '''
 main() {
   int a = 1;
   int b = 2;
@@ -659,7 +659,6 @@
 
 int res(num bbb, int aaa) => aaa + bbb;
 ''');
-    });
   }
 
   Future<void> test_init_fatalError_invalidStatement() {
diff --git a/pkg/analysis_server/test/integration/analysis/get_hover_test.dart b/pkg/analysis_server/test/integration/analysis/get_hover_test.dart
index 18b3976..385d923 100644
--- a/pkg/analysis_server/test/integration/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_hover_test.dart
@@ -131,53 +131,62 @@
     });
   }
 
-  Future<void> test_getHover() {
+  Future<void> test_getHover() async {
     writeFile(pathname, text);
     standardAnalysisSetup();
 
     // Note: analysis.getHover doesn't wait for analysis to complete--it simply
     // returns the latest results that are available at the time that the
     // request is made.  So wait for analysis to finish before testing anything.
-    return analysisFinished.then((_) {
-      var tests = <Future>[];
-      tests.add(checkHover('topLevelVar;', 11, ['List', 'topLevelVar'],
-          'top level variable', ['List']));
-      tests.add(checkHover(
-          'func(', 4, ['func', 'int', 'param'], 'function', null,
-          docRegexp: 'Documentation for func'));
-      tests.add(checkHover('int param', 3, ['int'], 'class', null,
-          isCore: true, docRegexp: '.*'));
-      tests.add(checkHover('param)', 5, ['int', 'param'], 'parameter', ['int'],
-          isLocal: true, docRegexp: 'Documentation for func'));
-      tests.add(checkHover('num localVar', 3, ['num'], 'class', null,
-          isCore: true, docRegexp: '.*'));
-      tests.add(checkHover(
-          'localVar =', 8, ['num', 'localVar'], 'local variable', ['num'],
-          isLocal: true));
-      tests.add(checkHover('topLevelVar.length;', 11, ['List', 'topLevelVar'],
-          'top level variable', ['List']));
-      tests.add(checkHover(
-          'length;', 6, ['get', 'length', 'int'], 'getter', null,
-          isCore: true, docRegexp: '.*'));
-      tests.add(checkHover(
-          'length =', 6, ['set', 'length', 'int'], 'setter', null,
-          isCore: true, docRegexp: '.*'));
-      tests.add(checkHover('param;', 5, ['int', 'param'], 'parameter', ['int'],
-          isLocal: true,
-          docRegexp: 'Documentation for func',
-          parameterRegexps: ['.*']));
-      tests.add(checkHover('add(', 3, ['add'], 'method', ['dynamic', 'void'],
-          isCore: true, docRegexp: '.*'));
-      tests.add(checkHover(
-          'localVar)', 8, ['num', 'localVar'], 'local variable', ['num'],
-          isLocal: true, parameterRegexps: ['.*']));
-      tests.add(checkHover(
-          'func(35', 4, ['func', 'int', 'param'], 'function', ['int', 'void'],
-          docRegexp: 'Documentation for func'));
-      tests.add(checkHover('35', 2, null, null, ['int'],
-          isLiteral: true, parameterRegexps: ['int', 'param']));
-      tests.add(checkNoHover('comment'));
-      return Future.wait(tests);
-    });
+    await analysisFinished;
+
+    await checkHover('topLevelVar;', 11, ['List', 'topLevelVar'],
+        'top level variable', ['List']);
+
+    await checkHover('func(', 4, ['func', 'int', 'param'], 'function', null,
+        docRegexp: 'Documentation for func');
+
+    await checkHover('int param', 3, ['int'], 'class', null,
+        isCore: true, docRegexp: '.*');
+
+    await checkHover('param)', 5, ['int', 'param'], 'parameter', ['int'],
+        isLocal: true, docRegexp: 'Documentation for func');
+
+    await checkHover('num localVar', 3, ['num'], 'class', null,
+        isCore: true, docRegexp: '.*');
+
+    await checkHover(
+        'localVar =', 8, ['num', 'localVar'], 'local variable', ['num'],
+        isLocal: true);
+
+    await checkHover('topLevelVar.length;', 11, ['List', 'topLevelVar'],
+        'top level variable', ['List']);
+
+    await checkHover('length;', 6, ['get', 'length', 'int'], 'getter', null,
+        isCore: true, docRegexp: '.*');
+
+    await checkHover('length =', 6, ['set', 'length', 'int'], 'setter', null,
+        isCore: true, docRegexp: '.*');
+
+    await checkHover('param;', 5, ['int', 'param'], 'parameter', ['int'],
+        isLocal: true,
+        docRegexp: 'Documentation for func',
+        parameterRegexps: ['.*']);
+
+    await checkHover('add(', 3, ['add'], 'method', ['dynamic', 'void'],
+        isCore: true, docRegexp: '.*');
+
+    await checkHover(
+        'localVar)', 8, ['num', 'localVar'], 'local variable', ['num'],
+        isLocal: true, parameterRegexps: ['.*']);
+
+    await checkHover(
+        'func(35', 4, ['func', 'int', 'param'], 'function', ['int', 'void'],
+        docRegexp: 'Documentation for func');
+
+    await checkHover('35', 2, null, null, ['int'],
+        isLiteral: true, parameterRegexps: ['int', 'param']);
+
+    await checkNoHover('comment');
   }
 }
diff --git a/pkg/analysis_server/test/integration/server/set_subscriptions_test.dart b/pkg/analysis_server/test/integration/server/set_subscriptions_test.dart
index 20f1d5f..9a7078b 100644
--- a/pkg/analysis_server/test/integration/server/set_subscriptions_test.dart
+++ b/pkg/analysis_server/test/integration/server/set_subscriptions_test.dart
@@ -28,7 +28,7 @@
 @reflectiveTest
 class SetSubscriptionsTest extends AbstractAnalysisServerIntegrationTest {
   @failingTest
-  Future<void> test_setSubscriptions() {
+  Future<void> test_setSubscriptions() async {
     // This test times out on the bots and has been disabled to keep them green.
     // We need to discover the cause and re-enable it.
 
@@ -46,28 +46,28 @@
         analysisBegun.complete();
       }
     });
-    return sendServerSetSubscriptions([]).then((_) {
-      var pathname = sourcePath('test.dart');
-      writeFile(pathname, '''
+    await sendServerSetSubscriptions([]);
+
+    var pathname = sourcePath('test.dart');
+    writeFile(pathname, '''
 main() {
   var x;
 }''');
-      standardAnalysisSetup(subscribeStatus: false);
-      // Analysis should begin, but no server.status notification should be
-      // received.
-      return analysisBegun.future.then((_) {
-        expect(statusReceived, isFalse);
-        return sendServerSetSubscriptions([ServerService.STATUS]).then((_) {
-          // Tickle test.dart just in case analysis has already completed.
-          writeFile(pathname, '''
+    standardAnalysisSetup(subscribeStatus: false);
+    // Analysis should begin, but no server.status notification should be
+    // received.
+    await analysisBegun.future;
+
+    expect(statusReceived, isFalse);
+    await sendServerSetSubscriptions([ServerService.STATUS]);
+
+    // Tickle test.dart just in case analysis has already completed.
+    writeFile(pathname, '''
 main() {
   var y;
 }''');
-          // Analysis should eventually complete, and we should be notified
-          // about it.
-          return analysisFinished;
-        });
-      });
-    });
+    // Analysis should eventually complete, and we should be notified
+    // about it.
+    await analysisFinished;
   }
 }
diff --git a/pkg/analysis_server/test/integration/server/status_test.dart b/pkg/analysis_server/test/integration/server/status_test.dart
index 48c7013..1fdf46b 100644
--- a/pkg/analysis_server/test/integration/server/status_test.dart
+++ b/pkg/analysis_server/test/integration/server/status_test.dart
@@ -18,7 +18,7 @@
 
 @reflectiveTest
 class StatusTest extends AbstractAnalysisServerIntegrationTest {
-  Future<void> test_status() {
+  Future<void> test_status() async {
     // After we kick off analysis, we should get one server.status message with
     // analyzing=true, and another server.status message after that with
     // analyzing=false.
@@ -42,9 +42,9 @@
     standardAnalysisSetup();
     expect(analysisBegun.isCompleted, isFalse);
     expect(analysisFinished.isCompleted, isFalse);
-    return analysisBegun.future.then((_) {
-      expect(analysisFinished.isCompleted, isFalse);
-      return analysisFinished.future;
-    });
+    await analysisBegun.future;
+
+    expect(analysisFinished.isCompleted, isFalse);
+    await analysisFinished.future;
   }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
index b065182..2e53eb1 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/flutter_use_case_test.dart
@@ -502,6 +502,104 @@
   }
 
   Future<void>
+      test_material_BottomNavigationBarItem_unnamedConstructor_deprecated() async {
+    setPackageContent('''
+class BottomNavigationBarItem {
+  BottomNavigationBarItem({String label, @deprecated Text title});
+}
+class Text {
+  Text(String text);
+}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+  - title: 'Replaced title with label'
+    date: 2020-09-24
+    element:
+      uris: ['$importUri']
+      constructor: ''
+      inClass: 'BottomNavigationBarItem'
+    changes:
+      - kind: 'addParameter'
+        index: 0
+        name: 'label'
+        style: required_named
+        argumentValue:
+          expression: '{% label %}'
+          variables:
+            label:
+              kind: fragment
+              value: 'arguments[title].arguments[0]'
+      - kind: 'removeParameter'
+        name: 'title'
+''');
+    await resolveTestCode('''
+import '$importUri';
+
+void f() {
+  BottomNavigationBarItem(title: Text('x'));
+}
+''');
+    await assertHasFix('''
+import '$importUri';
+
+void f() {
+  BottomNavigationBarItem(label: 'x');
+}
+''');
+  }
+
+  Future<void>
+      test_material_BottomNavigationBarItem_unnamedConstructor_removed() async {
+    setPackageContent('''
+class BottomNavigationBarItem {
+  BottomNavigationBarItem({String label});
+}
+class Text {
+  Text(String text);
+}
+''');
+    addPackageDataFile('''
+version: 1
+transforms:
+  - title: 'Replaced title with label'
+    date: 2020-09-24
+    element:
+      uris: ['$importUri']
+      constructor: ''
+      inClass: 'BottomNavigationBarItem'
+    changes:
+      - kind: 'addParameter'
+        index: 0
+        name: 'label'
+        style: required_named
+        argumentValue:
+          expression: '{% label %}'
+          variables:
+            label:
+              kind: fragment
+              value: 'arguments[title].arguments[0]'
+      - kind: 'removeParameter'
+        name: 'title'
+''');
+    await resolveTestCode('''
+import '$importUri';
+
+void f() {
+  BottomNavigationBarItem(title: Text('x'));
+}
+''');
+    await assertHasFix('''
+import '$importUri';
+
+void f() {
+  BottomNavigationBarItem(label: 'x');
+}
+''');
+  }
+
+  Future<void>
       test_material_Scaffold_resizeToAvoidBottomPadding_deprecated() async {
     setPackageContent('''
 class Scaffold {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart b/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart
index b953b90..028cda4 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/data_driven/modify_parameters_test.dart
@@ -480,6 +480,37 @@
 ''');
   }
 
+  Future<void> test_mixed_replaced_deprecated() async {
+    setPackageContent('''
+class C {
+  @deprecated
+  void m1({int a}) {}
+  void m2({int b}) {}
+}
+''');
+    setPackageData(_modify([
+      'C',
+      'm1'
+    ], [
+      AddParameter(0, 'b', true, false, codeTemplate('0')),
+      RemoveParameter(NamedParameterReference('a')),
+    ], newName: 'm2'));
+    await resolveTestCode('''
+import '$importUri';
+
+void f(C c) {
+  c.m1(a: 1);
+}
+''');
+    await assertHasFix('''
+import '$importUri';
+
+void f(C c) {
+  c.m2(b: 0);
+}
+''');
+  }
+
   Future<void> test_remove_first_optionalNamed_deprecated() async {
     setPackageContent('''
 class C {
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index fad1f0f8..afc24a3 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -1306,7 +1306,13 @@
       // We have something like `List.of(elements)`.
       TypeInformation baseType =
           _listBaseType(arguments, defaultGrowable: true);
-      return baseType;
+      // TODO(sra): Use static type to bound the element type, preferably as a
+      // narrowing of all inputs.
+      TypeInformation elementType = _types.dynamicType;
+      return _inferrer.concreteTypes.putIfAbsent(
+          node,
+          () => _types.allocateList(
+              baseType, node, _analyzedMember, elementType));
     }
     if (_isConstructorOfTypedArraySubclass(constructor)) {
       // We have something like `Uint32List(len)`.
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 3e327fb..fb0b04b 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -3856,8 +3856,8 @@
 
     // This could be a List factory constructor that returned a fresh list and
     // we have a call-site-specific type from type inference.
-    var inferredListType = globalInferenceResults.typeOfNewList(invocation);
-    AbstractValue resultType = inferredListType ?? typeMask;
+    var allocatedListType = globalInferenceResults.typeOfNewList(invocation);
+    AbstractValue resultType = allocatedListType ?? typeMask;
 
     // TODO(johnniwinther): Remove this when type arguments are passed to
     // constructors like calling a generic method.
@@ -3870,7 +3870,11 @@
     _pushStaticInvocation(function, arguments, resultType, typeArguments,
         sourceInformation: sourceInformation, instanceType: instanceType);
 
-    if (inferredListType != null) {
+    if (allocatedListType != null) {
+      HInstruction newInstance = stack.last.nonCheck();
+      if (newInstance is HInvokeStatic) {
+        newInstance.setAllocation(true);
+      }
       // Is the constructor call one from which we can extract the length
       // argument?
       bool isFixedList = false;
@@ -3891,8 +3895,6 @@
       }
 
       if (isFixedList) {
-        HInstruction newInstance = stack.last;
-        newInstance = newInstance.nonCheck();
         if (newInstance is HInvokeStatic || newInstance is HForeignCode) {
           graph.allocatedFixedLists.add(newInstance);
         }
diff --git a/pkg/compiler/test/inference/data/list2.dart b/pkg/compiler/test/inference/data/list2.dart
index b11b756..16b21d8 100644
--- a/pkg/compiler/test/inference/data/list2.dart
+++ b/pkg/compiler/test/inference/data/list2.dart
@@ -92,30 +92,30 @@
 
 // -------- List.of --------
 
-/*member: listOfDefault:[exact=JSExtendableArray]*/
+/*member: listOfDefault:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
 get listOfDefault => List.of(data);
 
-/*member: listOfGrowable:[exact=JSExtendableArray]*/
+/*member: listOfGrowable:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
 get listOfGrowable => List.of(data, growable: true);
 
-/*member: listOfFixed:[exact=JSFixedArray]*/
+/*member: listOfFixed:Container([exact=JSFixedArray], element: [null|subclass=Object], length: null)*/
 get listOfFixed => List.of(data, growable: false);
 
-/*member: listOfEither:[subclass=JSMutableArray]*/
+/*member: listOfEither:Container([subclass=JSMutableArray], element: [null|subclass=Object], length: null)*/
 get listOfEither => List.of(data, growable: boolFlag);
 
 // -------- List.from --------
 
-/*member: listFromDefault:[exact=JSExtendableArray]*/
+/*member: listFromDefault:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
 get listFromDefault => List.from(data);
 
-/*member: listFromGrowable:[exact=JSExtendableArray]*/
+/*member: listFromGrowable:Container([exact=JSExtendableArray], element: [null|subclass=Object], length: null)*/
 get listFromGrowable => List.from(data, growable: true);
 
-/*member: listFromFixed:[exact=JSFixedArray]*/
+/*member: listFromFixed:Container([exact=JSFixedArray], element: [null|subclass=Object], length: null)*/
 get listFromFixed => List.from(data, growable: false);
 
-/*member: listFromEither:[subclass=JSMutableArray]*/
+/*member: listFromEither:Container([subclass=JSMutableArray], element: [null|subclass=Object], length: null)*/
 get listFromEither => List.from(data, growable: boolFlag);
 
 // -------- List.unmodifiable --------
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index 6b7cfdc..84d9d95 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -45,8 +45,9 @@
 
   // The Analytics instance used to report information back to Google Analytics;
   // see lib/src/analytics.dart.
-  Analytics analytics =
-      createAnalyticsInstance(args.contains('--disable-dartdev-analytics'));
+  final analytics = createAnalyticsInstance(
+    args.contains('--disable-dartdev-analytics'),
+  );
 
   // If we have not printed the analyticsNoticeOnFirstRunMessage to stdout,
   // the user is on a terminal, and the machine is not a bot, then print the
@@ -80,7 +81,7 @@
   }
 
   try {
-    final runner = DartdevRunner(args);
+    final runner = DartdevRunner(args, analytics);
 
     // Run can't be called with the '--disable-dartdev-analytics' flag; remove
     // it if it is contained in args.
@@ -152,6 +153,8 @@
 }
 
 class DartdevRunner extends CommandRunner<int> {
+  final Analytics analytics;
+
   @override
   final ArgParser argParser =
       ArgParser(usageLineLength: dartdevUsageLineLength);
@@ -159,7 +162,8 @@
   static const String dartdevDescription =
       'A command-line utility for Dart development';
 
-  DartdevRunner(List<String> args) : super('dart', '$dartdevDescription.') {
+  DartdevRunner(List<String> args, this.analytics)
+      : super('dart', '$dartdevDescription.') {
     final bool verbose = args.contains('-v') || args.contains('--verbose');
 
     argParser.addFlag('verbose',
@@ -238,19 +242,17 @@
     final path = commandNames.join('/');
     // Send the screen view to analytics
     unawaited(
-      analyticsInstance.sendScreenView(path),
+      analytics.sendScreenView(path),
     );
 
     try {
       final exitCode = await super.runCommand(topLevelResults);
 
-      if (path != null &&
-          analyticsInstance != null &&
-          analyticsInstance.enabled) {
+      if (path != null && analytics.enabled) {
         // Send the event to analytics
         unawaited(
           sendUsageEvent(
-            analyticsInstance,
+            analytics,
             path,
             exitCode: exitCode,
             commandFlags:
@@ -268,9 +270,9 @@
       return exitCode;
     } finally {
       stopwatch.stop();
-      if (analyticsInstance.enabled) {
+      if (analytics.enabled) {
         unawaited(
-          analyticsInstance.sendTiming(
+          analytics.sendTiming(
             path ?? '',
             stopwatch.elapsedMilliseconds,
             category: 'commands',
diff --git a/pkg/dartdev/lib/src/analytics.dart b/pkg/dartdev/lib/src/analytics.dart
index 9f3095f..f8e8ffc 100644
--- a/pkg/dartdev/lib/src/analytics.dart
+++ b/pkg/dartdev/lib/src/analytics.dart
@@ -5,6 +5,7 @@
 import 'dart:convert';
 import 'dart:io';
 
+import 'package:meta/meta.dart';
 import 'package:path/path.dart' as path;
 import 'package:telemetry/telemetry.dart' as telemetry show isRunningOnBot;
 import 'package:usage/src/usage_impl.dart';
@@ -40,21 +41,15 @@
 const String eventCategory = 'dartdev';
 const String exitCodeParam = 'exitCode';
 
-Analytics _instance;
+/// Disabled [Analytics], exposed for testing only
+@visibleForTesting
+Analytics get disabledAnalytics => DisabledAnalytics(_trackingId, _appName);
 
-Analytics get analyticsInstance => _instance;
-
-/// Create and return an [Analytics] instance, this value is cached and returned
-/// on subsequent calls.
+/// Create and return an [Analytics] instance.
 Analytics createAnalyticsInstance(bool disableAnalytics) {
-  if (_instance != null) {
-    return _instance;
-  }
-
   if (Platform.environment['_DARTDEV_LOG_ANALYTICS'] != null) {
     // Used for testing what analytics messages are sent.
-    _instance = _LoggingAnalytics();
-    return _instance;
+    return _LoggingAnalytics();
   }
 
   if (disableAnalytics) {
@@ -62,16 +57,14 @@
     // handled here.
     // Also, stdout.hasTerminal is checked, if there is no terminal we infer that
     // a machine is running dartdev so we return analytics shouldn't be set.
-    _instance = DisabledAnalytics(_trackingId, _appName);
-    return _instance;
+    return DisabledAnalytics(_trackingId, _appName);
   }
 
-  var settingsDir = getDartStorageDirectory();
+  final settingsDir = getDartStorageDirectory();
   if (settingsDir == null) {
     // Some systems don't support user home directories; for those, fail
     // gracefully by returning a disabled analytics object.
-    _instance = DisabledAnalytics(_trackingId, _appName);
-    return _instance;
+    return DisabledAnalytics(_trackingId, _appName);
   }
 
   if (!settingsDir.existsSync()) {
@@ -80,21 +73,19 @@
     } catch (e) {
       // If we can't create the directory for the analytics settings, fail
       // gracefully by returning a disabled analytics object.
-      _instance = DisabledAnalytics(_trackingId, _appName);
-      return _instance;
+      return DisabledAnalytics(_trackingId, _appName);
     }
   }
 
-  var readmeFile =
+  final readmeFile =
       File('${settingsDir.absolute.path}${path.separator}$_readmeFileName');
   if (!readmeFile.existsSync()) {
     readmeFile.createSync();
     readmeFile.writeAsStringSync(_readmeFileContents);
   }
 
-  var settingsFile = File(path.join(settingsDir.path, _settingsFileName));
-  _instance = DartdevAnalytics(_trackingId, settingsFile, _appName);
-  return _instance;
+  final settingsFile = File(path.join(settingsDir.path, _settingsFileName));
+  return DartdevAnalytics(_trackingId, settingsFile, _appName);
 }
 
 /// The directory used to store the analytics settings file.
@@ -146,6 +137,7 @@
   }
 }
 
+@visibleForTesting
 class DisabledAnalytics extends AnalyticsMock {
   @override
   final String trackingId;
diff --git a/pkg/dartdev/lib/src/commands/fix.dart b/pkg/dartdev/lib/src/commands/fix.dart
index 18a92a0..3419c75 100644
--- a/pkg/dartdev/lib/src/commands/fix.dart
+++ b/pkg/dartdev/lib/src/commands/fix.dart
@@ -17,14 +17,20 @@
   static const String cmdName = 'fix';
 
   // This command is hidden as its currently experimental.
-  FixCommand() : super(cmdName, 'Fix Dart source code.', hidden: true);
+  FixCommand() : super(cmdName, 'Fix Dart source code.', hidden: true) {
+    argParser.addFlag('dry-run',
+        abbr: 'n',
+        defaultsTo: false,
+        help: 'Show which files would be modified but make no changes.');
+  }
 
   @override
   FutureOr<int> run() async {
     log.stdout('\n*** The `fix` command is provisional and subject to change '
         'or removal in future releases. ***\n');
 
-    if (argResults.rest.length > 1) {
+    var dryRun = argResults['dry-run'];
+    if (argResults.rest.length - (dryRun ? 1 : 0) > 1) {
       usageException('Only one file or directory is expected.');
     }
 
@@ -64,11 +70,25 @@
     if (edits.isEmpty) {
       log.stdout('Nothing to fix!');
     } else {
-      progress = log.progress('Applying fixes');
-      var fileCount = await _applyFixes(edits);
-      progress.finish(showTiming: true);
-      if (fileCount > 0) {
-        log.stdout('Fixed $fileCount ${pluralize("file", fileCount)}.');
+      if (dryRun) {
+        log.stdout("Running 'dart fix' without '--dry-run' would apply changes "
+            'in the following files:');
+        var files = <String>{};
+        for (var edit in edits) {
+          var file = edit.file;
+          files.add(path.relative(file, from: dir.path));
+        }
+        var paths = files.toList()..sort();
+        for (var path in paths) {
+          log.stdout(path);
+        }
+      } else {
+        progress = log.progress('Applying fixes');
+        var fileCount = await _applyFixes(edits);
+        progress.finish(showTiming: true);
+        if (fileCount > 0) {
+          log.stdout('Fixed $fileCount ${pluralize("file", fileCount)}.');
+        }
       }
     }
 
diff --git a/pkg/dartdev/test/commands/fix_test.dart b/pkg/dartdev/test/commands/fix_test.dart
index 8371019..5450742 100644
--- a/pkg/dartdev/test/commands/fix_test.dart
+++ b/pkg/dartdev/test/commands/fix_test.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'dart:io';
+
 import 'package:test/test.dart';
 
 import '../utils.dart';
@@ -42,6 +44,27 @@
     expect(result.stdout, contains('Fixed 1 file.'));
   });
 
+  test('dry-run', () {
+    p = project(
+      mainSrc: '''
+var x = "";
+''',
+      analysisOptions: '''
+linter:
+  rules:
+    - prefer_single_quotes
+''',
+    );
+    var result = p.runSync('fix', ['--dry-run', '.'], workingDir: p.dirPath);
+    expect(result.exitCode, 0);
+    expect(result.stderr, isEmpty);
+    expect(
+        result.stdout,
+        contains("Running 'dart fix' without '--dry-run' "
+            'would apply changes in the following files:'));
+    expect(result.stdout, contains('lib${Platform.pathSeparator}main.dart'));
+  });
+
   test('.', () {
     p = project(
       mainSrc: '''
diff --git a/pkg/dartdev/test/commands/flag_test.dart b/pkg/dartdev/test/commands/flag_test.dart
index 70660b4..7bef6a24 100644
--- a/pkg/dartdev/test/commands/flag_test.dart
+++ b/pkg/dartdev/test/commands/flag_test.dart
@@ -6,6 +6,7 @@
 
 import 'package:args/command_runner.dart';
 import 'package:dartdev/dartdev.dart';
+import 'package:dartdev/src/analytics.dart' show disabledAnalytics;
 import 'package:test/test.dart';
 
 import '../utils.dart';
@@ -19,7 +20,7 @@
   // For each command description, assert that the values are not empty, don't
   // have trailing white space and end with a period.
   test('description formatting', () {
-    DartdevRunner(['--disable-dartdev-analytics'])
+    DartdevRunner(['--disable-dartdev-analytics'], disabledAnalytics)
         .commands
         .forEach((String commandKey, Command command) {
       expect(commandKey, isNotEmpty);
@@ -31,7 +32,7 @@
 
   // Assert that all found usageLineLengths are the same and null
   test('argParser usageLineLength', () {
-    DartdevRunner(['--disable-dartdev-analytics'])
+    DartdevRunner(['--disable-dartdev-analytics'], disabledAnalytics)
         .commands
         .forEach((String commandKey, Command command) {
       if (command.argParser != null) {
diff --git a/pkg/dartdev/test/commands/help_test.dart b/pkg/dartdev/test/commands/help_test.dart
index 2cc0bfb..65f75a5 100644
--- a/pkg/dartdev/test/commands/help_test.dart
+++ b/pkg/dartdev/test/commands/help_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:args/command_runner.dart';
 import 'package:dartdev/dartdev.dart';
+import 'package:dartdev/src/analytics.dart' show disabledAnalytics;
 import 'package:test/test.dart';
 
 import '../utils.dart';
@@ -21,7 +22,7 @@
   List<String> _commandsNotTested = <String>[
     'help', // `dart help help` is redundant
   ];
-  DartdevRunner(['--disable-dartdev-analytics'])
+  DartdevRunner(['--disable-dartdev-analytics'], disabledAnalytics)
       .commands
       .forEach((String commandKey, Command command) {
     if (!_commandsNotTested.contains(commandKey)) {
@@ -46,7 +47,7 @@
   });
 
   test('(--help flags also have -h abbr)', () {
-    DartdevRunner(['--disable-dartdev-analytics'])
+    DartdevRunner(['--disable-dartdev-analytics'], disabledAnalytics)
         .commands
         .forEach((String commandKey, Command command) {
       var helpOption = command.argParser.options['help'];
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index 93c5853..baa6b72 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -207,7 +207,8 @@
         this.ticker = new Ticker(isVerbose: options?.verbose ?? false);
 
   FormattedMessage format(
-      LocatedMessage message, Severity severity, List<LocatedMessage> context) {
+      LocatedMessage message, Severity severity, List<LocatedMessage> context,
+      {List<Uri> involvedFiles}) {
     int offset = message.charOffset;
     Uri uri = message.uri;
     Location location = offset == -1 ? null : getLocation(uri, offset);
@@ -221,11 +222,12 @@
       }
     }
     return message.withFormatting(formatted, location?.line ?? -1,
-        location?.column ?? -1, severity, formattedContext);
+        location?.column ?? -1, severity, formattedContext,
+        involvedFiles: involvedFiles);
   }
 
   void report(LocatedMessage message, Severity severity,
-      {List<LocatedMessage> context}) {
+      {List<LocatedMessage> context, List<Uri> involvedFiles}) {
     if (command_line_reporting.isHidden(severity)) return;
     if (command_line_reporting.isCompileTimeError(severity)) {
       CompilerContext.current.logError(message, severity);
@@ -233,7 +235,8 @@
     if (CompilerContext.current.options.setExitCodeOnProblem) {
       exitCode = 1;
     }
-    reportDiagnosticMessage(format(message, severity, context));
+    reportDiagnosticMessage(
+        format(message, severity, context, involvedFiles: involvedFiles));
     if (command_line_reporting.shouldThrowOn(severity)) {
       if (fatalDiagnosticCount++ < _raw.skipForDebugging) {
         // Skip this one. The interesting one comes later.
diff --git a/pkg/front_end/lib/src/fasta/compiler_context.dart b/pkg/front_end/lib/src/fasta/compiler_context.dart
index e65531a..e64cd29 100644
--- a/pkg/front_end/lib/src/fasta/compiler_context.dart
+++ b/pkg/front_end/lib/src/fasta/compiler_context.dart
@@ -65,8 +65,9 @@
 
   /// Report [message], for example, by printing it.
   void report(LocatedMessage message, Severity severity,
-      {List<LocatedMessage> context}) {
-    options.report(message, severity, context: context);
+      {List<LocatedMessage> context, List<Uri> involvedFiles}) {
+    options.report(message, severity,
+        context: context, involvedFiles: involvedFiles);
   }
 
   /// Report [message], for example, by printing it.
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 73c5550..906d131 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -8,6 +8,7 @@
 import 'package:front_end/src/api_prototype/front_end.dart';
 import 'package:front_end/src/base/nnbd_mode.dart';
 import 'package:front_end/src/fasta/fasta_codes.dart';
+import 'package:front_end/src/fasta/source/source_loader.dart';
 import 'package:kernel/binary/ast_from_binary.dart'
     show
         BinaryBuilderWithMetadata,
@@ -1379,27 +1380,44 @@
     }
 
     // Report old problems that wasn't reported again.
-    for (List<DiagnosticMessageFromJson> messages
-        in remainingComponentProblems.values) {
+    Set<Uri> strongModeNNBDPackageOptOutUris;
+    for (MapEntry<Uri, List<DiagnosticMessageFromJson>> entry
+        in remainingComponentProblems.entries) {
+      List<DiagnosticMessageFromJson> messages = entry.value;
       for (int i = 0; i < messages.length; i++) {
         DiagnosticMessageFromJson message = messages[i];
+        if (message.codeName == "StrongModeNNBDPackageOptOut") {
+          // Special case this: Don't issue them here; instead collect them
+          // to get their uris and re-issue a new error.
+          strongModeNNBDPackageOptOutUris ??= {};
+          strongModeNNBDPackageOptOutUris.add(entry.key);
+          continue;
+        }
         if (issuedProblems.add(message.toJsonString())) {
           context.options.reportDiagnosticMessage(message);
         }
       }
     }
+    if (strongModeNNBDPackageOptOutUris != null) {
+      // Get the builders for these uris; then call
+      // `SourceLoader.giveCombinedErrorForNonStrongLibraries` on them to issue
+      // a new error.
+      Set<LibraryBuilder> builders = {};
+      SourceLoader loader = userCode.loader;
+      for (LibraryBuilder builder in loader.builders.values) {
+        if (strongModeNNBDPackageOptOutUris.contains(builder.fileUri)) {
+          builders.add(builder);
+        }
+      }
+      FormattedMessage message = loader.giveCombinedErrorForNonStrongLibraries(
+          builders,
+          emitNonPackageErrors: false);
+      issuedProblems.add(message.toJsonString());
+      // The problem was issued by the call so don't re-issue it here.
+    }
 
     // Save any new component-problems.
-    if (componentWithDill?.problemsAsJson != null) {
-      for (String jsonString in componentWithDill.problemsAsJson) {
-        DiagnosticMessageFromJson message =
-            new DiagnosticMessageFromJson.fromJson(jsonString);
-        List<DiagnosticMessageFromJson> messages =
-            remainingComponentProblems[message.uri] ??=
-                new List<DiagnosticMessageFromJson>();
-        messages.add(message);
-      }
-    }
+    _addProblemsAsJsonToRemainingProblems(componentWithDill?.problemsAsJson);
     return new List<String>.from(issuedProblems);
   }
 
@@ -1657,14 +1675,36 @@
 
   /// Internal method.
   void saveComponentProblems(IncrementalCompilerData data) {
-    if (data.component.problemsAsJson != null) {
-      for (String jsonString in data.component.problemsAsJson) {
+    List<String> problemsAsJson = data.component.problemsAsJson;
+    _addProblemsAsJsonToRemainingProblems(problemsAsJson);
+  }
+
+  void _addProblemsAsJsonToRemainingProblems(List<String> problemsAsJson) {
+    if (problemsAsJson != null) {
+      for (String jsonString in problemsAsJson) {
         DiagnosticMessageFromJson message =
             new DiagnosticMessageFromJson.fromJson(jsonString);
-        List<DiagnosticMessageFromJson> messages =
-            remainingComponentProblems[message.uri] ??=
-                new List<DiagnosticMessageFromJson>();
-        messages.add(message);
+        assert(message.uri != null ||
+            (message.involvedFiles != null &&
+                message.involvedFiles.isNotEmpty));
+        if (message.uri != null) {
+          List<DiagnosticMessageFromJson> messages =
+              remainingComponentProblems[message.uri] ??=
+                  new List<DiagnosticMessageFromJson>();
+          messages.add(message);
+        }
+        if (message.involvedFiles != null) {
+          // This indexes the same message under several uris - this way it will
+          // be issued as long as it's a problem. It will because of
+          // deduplication when we re-issue these (in reissueComponentProblems)
+          // only be reported once.
+          for (Uri uri in message.involvedFiles) {
+            List<DiagnosticMessageFromJson> messages =
+                remainingComponentProblems[uri] ??=
+                    new List<DiagnosticMessageFromJson>();
+            messages.add(message);
+          }
+        }
       }
     }
   }
diff --git a/pkg/front_end/lib/src/fasta/loader.dart b/pkg/front_end/lib/src/fasta/loader.dart
index cb9e306..cfdb636 100644
--- a/pkg/front_end/lib/src/fasta/loader.dart
+++ b/pkg/front_end/lib/src/fasta/loader.dart
@@ -280,11 +280,13 @@
       {bool wasHandled: false,
       List<LocatedMessage> context,
       Severity severity,
-      bool problemOnLibrary: false}) {
+      bool problemOnLibrary: false,
+      List<Uri> involvedFiles}) {
     return addMessage(message, charOffset, length, fileUri, severity,
         wasHandled: wasHandled,
         context: context,
-        problemOnLibrary: problemOnLibrary);
+        problemOnLibrary: problemOnLibrary,
+        involvedFiles: involvedFiles);
   }
 
   /// All messages reported by the compiler (errors, warnings, etc.) are routed
@@ -302,7 +304,8 @@
       Uri fileUri, Severity severity,
       {bool wasHandled: false,
       List<LocatedMessage> context,
-      bool problemOnLibrary: false}) {
+      bool problemOnLibrary: false,
+      List<Uri> involvedFiles}) {
     severity = target.fixSeverity(severity, message, fileUri);
     if (severity == Severity.ignored) return null;
     String trace = """
@@ -321,13 +324,14 @@
     }
     target.context.report(
         message.withLocation(fileUri, charOffset, length), severity,
-        context: context);
+        context: context, involvedFiles: involvedFiles);
     if (severity == Severity.error) {
       (wasHandled ? handledErrors : unhandledErrors)
           .add(message.withLocation(fileUri, charOffset, length));
     }
     FormattedMessage formattedMessage = target.createFormattedMessage(
-        message, charOffset, length, fileUri, context, severity);
+        message, charOffset, length, fileUri, context, severity,
+        involvedFiles: involvedFiles);
     if (!problemOnLibrary) {
       allComponentProblems.add(formattedMessage);
     }
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index c9a3615..16123b0 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -355,55 +355,9 @@
       // config we include each library uri in the message. For non-package
       // libraries with no corresponding package config we generate a message
       // per library.
-      Map<String, List<LibraryBuilder>> libraryByPackage = {};
-      Map<Package, Version> enableNonNullableVersionByPackage = {};
-      for (LibraryBuilder libraryBuilder in _strongOptOutLibraries) {
-        Package package =
-            target.uriTranslator.getPackage(libraryBuilder.importUri);
-
-        if (package != null &&
-            package.languageVersion != null &&
-            package.languageVersion is! InvalidLanguageVersion) {
-          Version enableNonNullableVersion =
-              enableNonNullableVersionByPackage[package] ??=
-                  target.getExperimentEnabledVersionInLibrary(
-                      ExperimentalFlag.nonNullable,
-                      new Uri(scheme: 'package', path: package.name));
-          Version version = new Version(
-              package.languageVersion.major, package.languageVersion.minor);
-          if (version < enableNonNullableVersion) {
-            (libraryByPackage[package?.name] ??= []).add(libraryBuilder);
-            continue;
-          }
-        }
-        if (libraryBuilder.importUri.scheme == 'package') {
-          (libraryByPackage[null] ??= []).add(libraryBuilder);
-        } else {
-          // Emit a message that doesn't mention running 'pub'.
-          addProblem(messageStrongModeNNBDButOptOut, -1, noLength,
-              libraryBuilder.fileUri);
-        }
-      }
-      if (libraryByPackage.isNotEmpty) {
-        List<String> dependencies = [];
-        libraryByPackage.forEach((String name, List<LibraryBuilder> libraries) {
-          if (name != null) {
-            dependencies.add('package:$name');
-          } else {
-            for (LibraryBuilder libraryBuilder in libraries) {
-              dependencies.add(libraryBuilder.importUri.toString());
-            }
-          }
-        });
-        // Emit a message that suggests to run 'pub' to check for opted in
-        // versions of the packages.
-        addProblem(
-            templateStrongModeNNBDPackageOptOut.withArguments(dependencies),
-            -1,
-            -1,
-            null);
-        _strongOptOutLibraries = null;
-      }
+      giveCombinedErrorForNonStrongLibraries(_strongOptOutLibraries,
+          emitNonPackageErrors: true);
+      _strongOptOutLibraries = null;
     }
     if (_nnbdMismatchLibraries != null) {
       for (MapEntry<LibraryBuilder, Message> entry
@@ -414,6 +368,68 @@
     }
   }
 
+  FormattedMessage giveCombinedErrorForNonStrongLibraries(
+      Set<LibraryBuilder> libraries,
+      {bool emitNonPackageErrors}) {
+    Map<String, List<LibraryBuilder>> libraryByPackage = {};
+    Map<Package, Version> enableNonNullableVersionByPackage = {};
+    for (LibraryBuilder libraryBuilder in libraries) {
+      final Package package =
+          target.uriTranslator.getPackage(libraryBuilder.importUri);
+
+      if (package != null &&
+          package.languageVersion != null &&
+          package.languageVersion is! InvalidLanguageVersion) {
+        Version enableNonNullableVersion =
+            enableNonNullableVersionByPackage[package] ??=
+                target.getExperimentEnabledVersionInLibrary(
+                    ExperimentalFlag.nonNullable,
+                    new Uri(scheme: 'package', path: package.name));
+        Version version = new Version(
+            package.languageVersion.major, package.languageVersion.minor);
+        if (version < enableNonNullableVersion) {
+          (libraryByPackage[package.name] ??= []).add(libraryBuilder);
+          continue;
+        }
+      }
+      if (libraryBuilder.importUri.scheme == 'package') {
+        (libraryByPackage[null] ??= []).add(libraryBuilder);
+      } else {
+        if (emitNonPackageErrors) {
+          // Emit a message that doesn't mention running 'pub'.
+          addProblem(messageStrongModeNNBDButOptOut, -1, noLength,
+              libraryBuilder.fileUri);
+        }
+      }
+    }
+    if (libraryByPackage.isNotEmpty) {
+      List<Uri> involvedFiles = [];
+      List<String> dependencies = [];
+      libraryByPackage.forEach((String name, List<LibraryBuilder> libraries) {
+        if (name != null) {
+          dependencies.add('package:$name');
+          for (LibraryBuilder libraryBuilder in libraries) {
+            involvedFiles.add(libraryBuilder.fileUri);
+          }
+        } else {
+          for (LibraryBuilder libraryBuilder in libraries) {
+            dependencies.add(libraryBuilder.importUri.toString());
+            involvedFiles.add(libraryBuilder.fileUri);
+          }
+        }
+      });
+      // Emit a message that suggests to run 'pub' to check for opted in
+      // versions of the packages.
+      return addProblem(
+          templateStrongModeNNBDPackageOptOut.withArguments(dependencies),
+          -1,
+          -1,
+          null,
+          involvedFiles: involvedFiles);
+    }
+    return null;
+  }
+
   List<int> getSource(List<int> bytes) {
     // bytes is 0-terminated. We don't want that included.
     if (bytes is Uint8List) {
@@ -1537,7 +1553,9 @@
 
 _awaitHelper(object, thenCallback, errorCallback, awaiter) {}
 
-_completeOnAsyncReturn(completer, value) {}
+_completeOnAsyncReturn(_future, value, async_jump_var) {}
+
+_completeOnAsyncError(_future, e, st, async_jump_var) {}
 
 class _AsyncStarStreamController {
   add(event) {}
@@ -1568,14 +1586,10 @@
 class FutureOr {
 }
 
-class _AsyncAwaitCompleter implements Completer {
-  get future => null;
+class _Future {
+  void _completeError(Object error, StackTrace stackTrace) {}
 
-  complete([value]) {}
-
-  completeError(error, [stackTrace]) {}
-
-  void start(void Function() f) {}
+  void _asyncCompleteError(Object error, StackTrace stackTrace) {}
 }
 
 class Stream {}
diff --git a/pkg/front_end/lib/src/fasta/target_implementation.dart b/pkg/front_end/lib/src/fasta/target_implementation.dart
index 60b0625..264ad8e 100644
--- a/pkg/front_end/lib/src/fasta/target_implementation.dart
+++ b/pkg/front_end/lib/src/fasta/target_implementation.dart
@@ -180,12 +180,14 @@
       int length,
       Uri fileUri,
       List<LocatedMessage> messageContext,
-      Severity severity) {
+      Severity severity,
+      {List<Uri> involvedFiles}) {
     ProcessedOptions processedOptions = context.options;
     return processedOptions.format(
         message.withLocation(fileUri, charOffset, length),
         severity,
-        messageContext);
+        messageContext,
+        involvedFiles: involvedFiles);
   }
 
   Severity fixSeverity(Severity severity, Message message, Uri fileUri) {
diff --git a/pkg/front_end/test/messages_json_test.dart b/pkg/front_end/test/messages_json_test.dart
index f2a9cf2..e0f5620 100644
--- a/pkg/front_end/test/messages_json_test.dart
+++ b/pkg/front_end/test/messages_json_test.dart
@@ -8,27 +8,36 @@
 import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
 
 import 'package:front_end/src/fasta/fasta_codes.dart'
-    show DiagnosticMessageFromJson, FormattedMessage, LocatedMessage;
+    show
+        Code,
+        DiagnosticMessageFromJson,
+        FormattedMessage,
+        LocatedMessage,
+        Message;
 
 /// Test that turning a message into json and back again retains the wanted
 /// information.
 main() {
   for (int i = 0; i < Severity.values.length; i++) {
     Severity severity = Severity.values[i];
+    Code code = new Code("MyCodeName", null);
+    Message message = new Message(code);
     LocatedMessage locatedMessage1 =
-        new LocatedMessage(Uri.parse("what:ever/fun_1.dart"), 117, 2, null);
+        new LocatedMessage(Uri.parse("what:ever/fun_1.dart"), 117, 2, message);
     FormattedMessage formattedMessage2 = new FormattedMessage(
         null, "Formatted string #2", 13, 2, Severity.error, []);
     FormattedMessage formattedMessage3 = new FormattedMessage(
         null, "Formatted string #3", 313, 32, Severity.error, []);
 
     FormattedMessage formattedMessage1 = new FormattedMessage(
-        locatedMessage1,
-        "Formatted string",
-        42,
-        86,
-        severity,
-        [formattedMessage2, formattedMessage3]);
+        locatedMessage1, "Formatted string", 42, 86, severity, [
+      formattedMessage2,
+      formattedMessage3
+    ], involvedFiles: [
+      Uri.parse("what:ever/foo.dart"),
+      Uri.parse("what:ever/bar.dart")
+    ]);
+    expect(formattedMessage1.codeName, "MyCodeName");
 
     DiagnosticMessageFromJson diagnosticMessageFromJson =
         new DiagnosticMessageFromJson.fromJson(
@@ -62,6 +71,19 @@
 
   expect(a.severity, b.severity);
   expect(getMessageUri(a), getMessageUri(b));
+
+  List<Uri> uriList1 = a.involvedFiles?.toList();
+  List<Uri> uriList2 = b.involvedFiles?.toList();
+  expect(uriList1?.length, uriList2?.length);
+  if (uriList1 != null) {
+    for (int i = 0; i < uriList1.length; i++) {
+      expect(uriList1[i], uriList2[i]);
+    }
+  }
+
+  String string1 = a.codeName;
+  String string2 = b.codeName;
+  expect(string1, string2);
 }
 
 void expect(Object actual, Object expect) {
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index fcf1279..20db3c3 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -279,6 +279,7 @@
 decl
 decoupled
 decreases
+deduplication
 deemed
 deepest
 deeply
diff --git a/pkg/front_end/testcases/extensions/async_extensions.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/async_extensions.dart.strong.transformed.expect
index f4de67a..36fe6ad 100644
--- a/pkg/front_end/testcases/extensions/async_extensions.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/async_extensions.dart.strong.transformed.expect
@@ -26,7 +26,8 @@
 static method Extension|get#syncStarMethod(final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|syncStarMethod(#this);
 static method Extension|asyncMethod(final core::int* #this) → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -37,17 +38,18 @@
     try {
       #L1:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method Extension|get#asyncMethod(final core::int* #this) → () →* dynamic
   return () → dynamic => self::Extension|asyncMethod(#this);
diff --git a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.transformed.expect
index c510c9c..580ca3c 100644
--- a/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/deferred_explicit_access.dart.strong.transformed.expect
@@ -15,7 +15,8 @@
 import "org-dartlang-testcase:///deferred_explicit_access_lib.dart" deferred as prefix;
 
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -38,17 +39,18 @@
         self::expect(87, let final core::Object* #t11 = CheckLibraryIsLoaded(prefix) in def::Extension|staticProperty = 87);
         self::expect(87, let final core::Object* #t12 = CheckLibraryIsLoaded(prefix) in def::Extension|staticMethod());
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!expected.{core::Object::==}(actual))
@@ -100,4 +102,4 @@
 Evaluated: VariableGet @ org-dartlang-testcase:///deferred_explicit_access.dart:12:31 -> IntConstant(0)
 Evaluated: VariableGet @ org-dartlang-testcase:///deferred_explicit_access.dart:12:45 -> IntConstant(42)
 Evaluated: VariableGet @ org-dartlang-testcase:///deferred_explicit_access.dart:12:45 -> IntConstant(42)
-Extra constant evaluation: evaluated: 95, effectively constant: 3
+Extra constant evaluation: evaluated: 96, effectively constant: 3
diff --git a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.transformed.expect
index 25a9778..187e9da 100644
--- a/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extensions/deferred_import_hidden.dart.strong.transformed.expect
@@ -7,7 +7,8 @@
 import "org-dartlang-testcase:///deferred_explicit_access_lib.dart" deferred as prefix hide Extension;
 
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -29,17 +30,18 @@
         self::expect(87, let final core::Object* #t7 = CheckLibraryIsLoaded(prefix) in def::topLevelProperty);
         self::expect(87, let final core::Object* #t8 = CheckLibraryIsLoaded(prefix) in def::topLevelMethod());
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!expected.{core::Object::==}(actual))
diff --git a/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect b/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect
index 056a35a..3382485 100644
--- a/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/async_function.dart.strong.transformed.expect
@@ -8,7 +8,8 @@
 
 static field core::List<core::String*>* stringList = <core::String*>["bar"];
 static method asyncString() → asy::Future<core::String*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
+  final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
+  core::bool* :is_sync = false;
   FutureOr<core::String*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -22,20 +23,22 @@
         :return_value = "foo";
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method asyncString2() → asy::Future<core::String*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
+  final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
+  core::bool* :is_sync = false;
   FutureOr<core::String*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -49,17 +52,18 @@
         :return_value = self::asyncString();
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method syncStarString() → core::Iterable<core::String*>* /* originally sync* */ {
   function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
@@ -183,7 +187,8 @@
   return :controller_stream;
 }
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -198,15 +203,16 @@
         [yield] let dynamic #t2 = asy::_awaitHelper(self::asyncString(), :async_op_then, :async_op_error, :async_op) in null;
         core::String* str = _in::unsafeCast<core::String*>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect b/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect
index 672a96f..772b468 100644
--- a/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/async_nested.dart.strong.transformed.expect
@@ -28,7 +28,8 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static method main() → void /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -62,17 +63,18 @@
           throw "Expected '${expected}' but got '${actual}'";
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/general/await.dart.strong.transformed.expect b/pkg/front_end/testcases/general/await.dart.strong.transformed.expect
index 7d6f5ee..9bac1f2 100644
--- a/pkg/front_end/testcases/general/await.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/await.dart.strong.transformed.expect
@@ -5,7 +5,8 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -20,15 +21,16 @@
         [yield] let dynamic #t1 = asy::_awaitHelper("Hello, World!", :async_op_then, :async_op_error, :async_op) in null;
         core::print(_in::unsafeCast<core::String*>(:result));
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect b/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect
index addb806..d6a8b95 100644
--- a/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/await_complex.dart.strong.transformed.expect
@@ -57,7 +57,8 @@
 static method dummy() → dynamic
   return 1;
 static method staticMembers() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -100,20 +101,22 @@
         core::num* e = _in::unsafeCast<core::int*>(:async_temporary_5).{core::num::+}(:result as{TypeError,ForDynamic} core::num);
         self::expect(5, e);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method topLevelMembers() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -151,20 +154,22 @@
         core::num* e = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num);
         self::expect(5, e);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method instanceMembers() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -203,20 +208,22 @@
         core::num* e = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num);
         self::expect(5, e);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method others() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -255,20 +262,22 @@
         core::num* e = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num);
         self::expect(2, e);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method conditionals() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -327,20 +336,22 @@
         on dynamic catch(final dynamic e) {
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method asserts() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -400,20 +411,22 @@
           }
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method controlFlow() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -546,7 +559,8 @@
                 }
               }
               [yield] let dynamic #t51 = asy::_awaitHelper((() → asy::Future<dynamic>* /* originally async */ {
-                final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+                final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+                core::bool* :is_sync = false;
                 FutureOr<dynamic>* :return_value;
                 dynamic :async_stack_trace;
                 (dynamic) →* dynamic :async_op_then;
@@ -562,21 +576,23 @@
                       :return_value = :result;
                       break #L13;
                     }
-                    asy::_completeOnAsyncReturn(:async_completer, :return_value);
+                    asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
                     return;
                   }
                   on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-                    :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+                    asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
                   }
                 :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-                :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-                return :async_completer.{asy::Completer::future};
+                :async_op.call();
+                :is_sync = true;
+                return :async_future;
               }).call(), :async_op_then, :async_op_error, :async_op) in null;
               self::expect(42, :result);
               [yield] let dynamic #t53 = asy::_awaitHelper((() → asy::Future<dynamic>* /* originally async */ {
-                final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+                final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+                core::bool* :is_sync = false;
                 FutureOr<dynamic>* :return_value;
                 dynamic :async_stack_trace;
                 (dynamic) →* dynamic :async_op_then;
@@ -590,17 +606,18 @@
                       :return_value = func.call<dynamic>(42);
                       break #L14;
                     }
-                    asy::_completeOnAsyncReturn(:async_completer, :return_value);
+                    asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
                     return;
                   }
                   on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-                    :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+                    asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
                   }
                 :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-                :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-                return :async_completer.{asy::Completer::future};
+                :async_op.call();
+                :is_sync = true;
+                return :async_future;
               }).call(), :async_op_then, :async_op_error, :async_op) in null;
               self::expect(42, :result);
               function testStream1() → asy::Stream<core::int*>* /* originally async* */ {
@@ -685,20 +702,22 @@
           }
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method future<T extends core::Object* = dynamic>(self::future::T* value) → FutureOr<self::future::T*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<self::future::T*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::future::T*>();
+  final asy::_Future<self::future::T*>* :async_future = new asy::_Future::•<self::future::T*>();
+  core::bool* :is_sync = false;
   FutureOr<self::future::T*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -712,17 +731,18 @@
         :return_value = value;
         break #L17;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method id<T extends core::Object* = dynamic>(self::id::T* value) → FutureOr<self::id::T*>*
   return value;
@@ -762,7 +782,8 @@
   return :controller_stream;
 }
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -791,17 +812,18 @@
           :result;
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!expected.{core::Object::==}(actual))
diff --git a/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect b/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect
index 7c1f7a3..fe03b1d 100644
--- a/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/await_in_cascade.dart.strong.transformed.expect
@@ -11,7 +11,8 @@
     : super core::Object::•()
     ;
   method m() → asy::Future<core::List<core::int*>*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
+    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;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -29,20 +30,22 @@
           :return_value = block {} =>#t1;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   method _m() → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -56,17 +59,18 @@
           :return_value = 42;
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   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
@@ -80,7 +84,8 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -95,17 +100,18 @@
         [yield] let dynamic #t3 = asy::_awaitHelper(new self::C::•().{self::C::m}(), :async_op_then, :async_op_error, :async_op) in null;
         self::expect(42, _in::unsafeCast<core::List<core::int*>*>(:result).{core::Iterable::first});
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!expected.{core::Object::==}(actual))
diff --git a/pkg/front_end/testcases/general/bug33196.dart.strong.transformed.expect b/pkg/front_end/testcases/general/bug33196.dart.strong.transformed.expect
index 79fa612..fe416ab 100644
--- a/pkg/front_end/testcases/general/bug33196.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/bug33196.dart.strong.transformed.expect
@@ -10,7 +10,8 @@
   core::print(result.{core::Object::runtimeType});
 }
 static method returnsString() → FutureOr<core::String*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
+  final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
+  core::bool* :is_sync = false;
   FutureOr<core::String*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -24,15 +25,16 @@
         :return_value = "oh no";
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect b/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect
index a6aaad8..389811c 100644
--- a/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/bug33206.dart.strong.transformed.expect
@@ -41,7 +41,8 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static method f1() → asy::Future<core::List<core::Object*>*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::List<core::Object*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::Object*>*>();
+  final asy::_Future<core::List<core::Object*>*>* :async_future = new asy::_Future::•<core::List<core::Object*>*>();
+  core::bool* :is_sync = false;
   FutureOr<core::List<core::Object*>*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -55,22 +56,24 @@
         :return_value = <core::Object*>[1];
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method f2() → core::List<core::Object*>*
   return <core::Object*>[2];
 static method f3() → asy::Future<core::Object*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::Object*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::Object*>();
+  final asy::_Future<core::Object*>* :async_future = new asy::_Future::•<core::Object*>();
+  core::bool* :is_sync = false;
   FutureOr<core::Object*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -84,20 +87,22 @@
         :return_value = 3;
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method foo() → asy::Future<self::X*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<self::X*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::X*>();
+  final asy::_Future<self::X*>* :async_future = new asy::_Future::•<self::X*>();
+  core::bool* :is_sync = false;
   FutureOr<self::X*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -120,20 +125,22 @@
         :return_value = new self::X::•(_in::unsafeCast<self::Y*>(:async_temporary_0), _in::unsafeCast<core::Object*>(:result));
         break #L3;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → asy::Future<void>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<void>* :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
+  final asy::_Future<void>* :async_future = new asy::_Future::•<void>();
+  core::bool* :is_sync = false;
   FutureOr<void>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -148,15 +155,16 @@
         [yield] let dynamic #t4 = asy::_awaitHelper(self::foo(), :async_op_then, :async_op_error, :async_op) in null;
         core::print(_in::unsafeCast<self::X*>(:result));
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.strong.transformed.expect b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.strong.transformed.expect
index 8df91fe..ad4521b 100644
--- a/pkg/front_end/testcases/general/check_deferred_before_args2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/check_deferred_before_args2.dart.strong.transformed.expect
@@ -8,7 +8,8 @@
 
 static method main() → dynamic {}
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -24,17 +25,18 @@
         [yield] let dynamic #t2 = asy::_awaitHelper(LoadLibrary(lib), :async_op_then, :async_op_error, :async_op) in null;
         def::m(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 
 library;
diff --git a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
index bda30e7..1b11b50 100644
--- a/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/control_flow_collection_inference.dart.strong.transformed.expect
@@ -2339,7 +2339,8 @@
   } =>#t337;
 }
 static method testForElementErrors(core::Map<core::int*, core::int*>* map, core::List<core::int*>* list) → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -2886,17 +2887,18 @@
           #t433.{core::Map::[]=}("baz", null);
         } =>#t433;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method testForElementErrorsNotAsync(asy::Stream<core::int*>* stream) → dynamic {
   block {
diff --git a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.transformed.expect b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.transformed.expect
index 1d43883..caf60f4 100644
--- a/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/error_recovery/empty_await_for.dart.strong.transformed.expect
@@ -17,7 +17,8 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -60,15 +61,16 @@
             }
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/general/flutter_issue64155.dart.strong.transformed.expect b/pkg/front_end/testcases/general/flutter_issue64155.dart.strong.transformed.expect
index b2d6c42..23d120e 100644
--- a/pkg/front_end/testcases/general/flutter_issue64155.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/flutter_issue64155.dart.strong.transformed.expect
@@ -6,7 +6,8 @@
 
 abstract class TestMixin<R extends core::Object* = dynamic, T extends core::Object* = dynamic> extends core::Object /*isMixinDeclaration*/  {
   method test(generic-covariant-impl asy::Future<self::TestMixin::R*>* fetch) → asy::Future<self::TestMixin::T*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<self::TestMixin::T*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::TestMixin::T*>();
+    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;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -38,17 +39,18 @@
           :return_value = result;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   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
@@ -124,7 +126,8 @@
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
   method test(generic-covariant-impl asy::Future<self::Response<core::String*>*>* fetch) → asy::Future<core::String*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
+    final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
+    core::bool* :is_sync = false;
     FutureOr<core::String*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -156,17 +159,18 @@
           :return_value = result;
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 class Class1 extends self::_Class1&Object&TestMixin {
@@ -193,7 +197,8 @@
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
   method test(generic-covariant-impl asy::Future<self::PagingResponse<core::String*>*>* fetch) → asy::Future<core::String*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
+    final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
+    core::bool* :is_sync = false;
     FutureOr<core::String*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -225,17 +230,18 @@
           :return_value = result;
           break #L3;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 class Class2 extends self::_Class2&Object&TestMixin {
diff --git a/pkg/front_end/testcases/general/future_or_test.dart.strong.transformed.expect b/pkg/front_end/testcases/general/future_or_test.dart.strong.transformed.expect
index 64daac2..a4ac3f4 100644
--- a/pkg/front_end/testcases/general/future_or_test.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/future_or_test.dart.strong.transformed.expect
@@ -28,7 +28,8 @@
     : super core::Object::•()
     ;
   method bar() → asy::Future<dynamic>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+    final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+    core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -42,17 +43,18 @@
           :return_value = this.{self::B::a}.{self::A::foo}();
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   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
@@ -71,7 +73,8 @@
     : super core::Object::•()
     ;
   method baz() → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -85,17 +88,18 @@
           :return_value = this.{self::C::b}.{self::B::bar}() as{TypeError} FutureOr<core::int*>*;
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   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_return.dart.strong.transformed.expect b/pkg/front_end/testcases/general/future_return.dart.strong.transformed.expect
index b739d5b..6f96292 100644
--- a/pkg/front_end/testcases/general/future_return.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/future_return.dart.strong.transformed.expect
@@ -43,7 +43,8 @@
 static method returnDynamic() → dynamic
   return new self::Class::•();
 static method returnClass() → self::Class* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -57,20 +58,22 @@
         :return_value = new self::Class::•();
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnFutureClass() → asy::Future<self::Class*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<self::Class*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::Class*>();
+  final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
+  core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -84,20 +87,22 @@
         :return_value = new self::Class::•();
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnFutureOrClass() → FutureOr<self::Class*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<self::Class*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::Class*>();
+  final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
+  core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -111,20 +116,22 @@
         :return_value = new self::Class::•();
         break #L3;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnClassFromDynamic() → self::Class* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -138,20 +145,22 @@
         :return_value = self::returnDynamic() as{TypeError} FutureOr<self::Class*>*;
         break #L4;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnFutureClassDynamic() → asy::Future<self::Class*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<self::Class*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::Class*>();
+  final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
+  core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -165,20 +174,22 @@
         :return_value = self::returnDynamic() as{TypeError} FutureOr<self::Class*>*;
         break #L5;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnFutureOrClassDynamic() → FutureOr<self::Class*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<self::Class*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::Class*>();
+  final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
+  core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -192,20 +203,22 @@
         :return_value = self::returnDynamic() as{TypeError} FutureOr<self::Class*>*;
         break #L6;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnClassFromFutureClass() → self::Class* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -219,20 +232,22 @@
         :return_value = self::returnFutureClass();
         break #L7;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnFutureClassFromFutureClass() → asy::Future<self::Class*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<self::Class*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::Class*>();
+  final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
+  core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -246,20 +261,22 @@
         :return_value = self::returnFutureClass();
         break #L8;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnFutureOrClassFromFutureClass() → FutureOr<self::Class*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<self::Class*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::Class*>();
+  final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
+  core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -273,20 +290,22 @@
         :return_value = self::returnFutureClass();
         break #L9;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnClassFromFutureOrClass() → self::Class* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -300,20 +319,22 @@
         :return_value = self::returnFutureOrClass();
         break #L10;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnFutureClassFromFutureOrClass() → asy::Future<self::Class*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<self::Class*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::Class*>();
+  final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
+  core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -327,20 +348,22 @@
         :return_value = self::returnFutureOrClass();
         break #L11;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnFutureOrClassFromFutureOrClass() → FutureOr<self::Class*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<self::Class*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::Class*>();
+  final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
+  core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -354,20 +377,22 @@
         :return_value = self::returnFutureOrClass();
         break #L12;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -404,15 +429,16 @@
         [yield] let dynamic #t12 = asy::_awaitHelper(self::returnFutureOrClassFromFutureOrClass(), :async_op_then, :async_op_error, :async_op) in null;
         _in::unsafeCast<self::Class*>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect
index 5fe56f9..2b93494 100644
--- a/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/issue40662.dart.strong.transformed.expect
@@ -9,7 +9,8 @@
   self::expect(1.{core::int::unary-}(), b.{core::List::[]}(0).{core::num::-}(2));
 }
 static method foo(core::int* x) → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -38,20 +39,22 @@
         :return_value = self::bar(_in::unsafeCast<core::int*>(:async_temporary_3), :async_temporary_2);
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → void /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -67,17 +70,18 @@
         :return_value = :result;
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!expected.{core::Object::==}(actual))
@@ -88,4 +92,4 @@
 Extra constant evaluation status:
 Evaluated: MethodInvocation @ org-dartlang-testcase:///issue40662.dart:8:10 -> IntConstant(-1)
 Evaluated: MethodInvocation @ org-dartlang-testcase:///issue40662.dart:9:10 -> IntConstant(-1)
-Extra constant evaluation: evaluated: 99, effectively constant: 2
+Extra constant evaluation: evaluated: 101, effectively constant: 2
diff --git a/pkg/front_end/testcases/general/issue42615.dart.strong.transformed.expect b/pkg/front_end/testcases/general/issue42615.dart.strong.transformed.expect
index 768d8b1..5550a8f 100644
--- a/pkg/front_end/testcases/general/issue42615.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/issue42615.dart.strong.transformed.expect
@@ -24,7 +24,8 @@
   return null;
 static method main() → dynamic {
   new self::Class::•<dynamic>(a: () → FutureOr<core::List<dynamic>*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::List<dynamic>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<dynamic>*>();
+    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;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -38,17 +39,18 @@
           :return_value = self::method() as{TypeError} FutureOr<core::List<dynamic>*>*;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
 }
 
diff --git a/pkg/front_end/testcases/general/no_such_method_forwarder.dart.strong.transformed.expect b/pkg/front_end/testcases/general/no_such_method_forwarder.dart.strong.transformed.expect
index e981ad6..13f8db4 100644
--- a/pkg/front_end/testcases/general/no_such_method_forwarder.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/no_such_method_forwarder.dart.strong.transformed.expect
@@ -9,7 +9,8 @@
     : super core::Object::•()
     ;
   method _foo() → void /* originally async */ {
-    final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+    final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+    core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -25,17 +26,18 @@
           _in::unsafeCast<core::Null?>(:result);
           core::print("hello");
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   method foo() → void
     return this.{self::X::_foo}();
diff --git a/pkg/front_end/testcases/general/regression_flutter51828.dart.strong.transformed.expect b/pkg/front_end/testcases/general/regression_flutter51828.dart.strong.transformed.expect
index c0ef0a7..bc31717 100644
--- a/pkg/front_end/testcases/general/regression_flutter51828.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/regression_flutter51828.dart.strong.transformed.expect
@@ -9,7 +9,8 @@
     : super core::Object::•()
     ;
   method foo(dynamic x) → asy::Future<void>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<void>* :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
+    final asy::_Future<void>* :async_future = new asy::_Future::•<void>();
+    core::bool* :is_sync = false;
     FutureOr<void>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -20,17 +21,18 @@
       try {
         #L1:
         {}
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   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
@@ -48,7 +50,8 @@
     : super core::Object::•()
     ;
   method bar(dynamic x) → asy::Future<void>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<void>* :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
+    final asy::_Future<void>* :async_future = new asy::_Future::•<void>();
+    core::bool* :is_sync = false;
     FutureOr<void>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -59,17 +62,18 @@
       try {
         #L2:
         {}
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   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
@@ -83,7 +87,8 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -105,15 +110,16 @@
         :return_value = <asy::Future<void>*>[_in::unsafeCast<asy::Future<void>*>(:async_temporary_1), _in::unsafeCast<self::B*>(:async_temporary_0).{self::B::bar}(_in::unsafeCast<core::Null?>(:result))];
         break #L3;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/general/stream_future.dart.strong.transformed.expect b/pkg/front_end/testcases/general/stream_future.dart.strong.transformed.expect
index c529245..97bf589 100644
--- a/pkg/front_end/testcases/general/stream_future.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/stream_future.dart.strong.transformed.expect
@@ -35,7 +35,8 @@
 static method returnClass() → self::Class*
   return new self::Class::•();
 static method returnFutureDynamic() → asy::Future<dynamic>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -49,20 +50,22 @@
         :return_value = new self::Class::•();
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnFutureClass() → asy::Future<self::Class*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<self::Class*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::Class*>();
+  final asy::_Future<self::Class*>* :async_future = new asy::_Future::•<self::Class*>();
+  core::bool* :is_sync = false;
   FutureOr<self::Class*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -76,17 +79,18 @@
         :return_value = new self::Class::•();
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method error() → asy::Stream<FutureOr<self::Class*>*>* /* originally async* */ {
   asy::_AsyncStarStreamController<FutureOr<self::Class*>*>* :controller;
@@ -171,7 +175,8 @@
   return :controller_stream;
 }
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -210,15 +215,16 @@
             }
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect
index 056a35a..3382485 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_function.dart.weak.transformed.expect
@@ -8,7 +8,8 @@
 
 static field core::List<core::String*>* stringList = <core::String*>["bar"];
 static method asyncString() → asy::Future<core::String*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
+  final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
+  core::bool* :is_sync = false;
   FutureOr<core::String*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -22,20 +23,22 @@
         :return_value = "foo";
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method asyncString2() → asy::Future<core::String*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
+  final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
+  core::bool* :is_sync = false;
   FutureOr<core::String*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -49,17 +52,18 @@
         :return_value = self::asyncString();
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method syncStarString() → core::Iterable<core::String*>* /* originally sync* */ {
   function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
@@ -183,7 +187,8 @@
   return :controller_stream;
 }
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -198,15 +203,16 @@
         [yield] let dynamic #t2 = asy::_awaitHelper(self::asyncString(), :async_op_then, :async_op_error, :async_op) in null;
         core::String* str = _in::unsafeCast<core::String*>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect
index 672a96f..772b468 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/async_nested.dart.weak.transformed.expect
@@ -28,7 +28,8 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static method main() → void /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -62,17 +63,18 @@
           throw "Expected '${expected}' but got '${actual}'";
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.weak.transformed.expect
index 7d6f5ee..9bac1f2 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await.dart.weak.transformed.expect
@@ -5,7 +5,8 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -20,15 +21,16 @@
         [yield] let dynamic #t1 = asy::_awaitHelper("Hello, World!", :async_op_then, :async_op_error, :async_op) in null;
         core::print(_in::unsafeCast<core::String*>(:result));
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect
index addb806..d6a8b95 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_complex.dart.weak.transformed.expect
@@ -57,7 +57,8 @@
 static method dummy() → dynamic
   return 1;
 static method staticMembers() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -100,20 +101,22 @@
         core::num* e = _in::unsafeCast<core::int*>(:async_temporary_5).{core::num::+}(:result as{TypeError,ForDynamic} core::num);
         self::expect(5, e);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method topLevelMembers() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -151,20 +154,22 @@
         core::num* e = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num);
         self::expect(5, e);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method instanceMembers() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -203,20 +208,22 @@
         core::num* e = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num);
         self::expect(5, e);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method others() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -255,20 +262,22 @@
         core::num* e = _in::unsafeCast<core::int*>(:async_temporary_4).{core::num::+}(:result as{TypeError,ForDynamic} core::num);
         self::expect(2, e);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method conditionals() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -327,20 +336,22 @@
         on dynamic catch(final dynamic e) {
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method asserts() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -400,20 +411,22 @@
           }
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method controlFlow() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -546,7 +559,8 @@
                 }
               }
               [yield] let dynamic #t51 = asy::_awaitHelper((() → asy::Future<dynamic>* /* originally async */ {
-                final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+                final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+                core::bool* :is_sync = false;
                 FutureOr<dynamic>* :return_value;
                 dynamic :async_stack_trace;
                 (dynamic) →* dynamic :async_op_then;
@@ -562,21 +576,23 @@
                       :return_value = :result;
                       break #L13;
                     }
-                    asy::_completeOnAsyncReturn(:async_completer, :return_value);
+                    asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
                     return;
                   }
                   on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-                    :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+                    asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
                   }
                 :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-                :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-                return :async_completer.{asy::Completer::future};
+                :async_op.call();
+                :is_sync = true;
+                return :async_future;
               }).call(), :async_op_then, :async_op_error, :async_op) in null;
               self::expect(42, :result);
               [yield] let dynamic #t53 = asy::_awaitHelper((() → asy::Future<dynamic>* /* originally async */ {
-                final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+                final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+                core::bool* :is_sync = false;
                 FutureOr<dynamic>* :return_value;
                 dynamic :async_stack_trace;
                 (dynamic) →* dynamic :async_op_then;
@@ -590,17 +606,18 @@
                       :return_value = func.call<dynamic>(42);
                       break #L14;
                     }
-                    asy::_completeOnAsyncReturn(:async_completer, :return_value);
+                    asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
                     return;
                   }
                   on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-                    :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+                    asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
                   }
                 :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
                 :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
                 :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-                :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-                return :async_completer.{asy::Completer::future};
+                :async_op.call();
+                :is_sync = true;
+                return :async_future;
               }).call(), :async_op_then, :async_op_error, :async_op) in null;
               self::expect(42, :result);
               function testStream1() → asy::Stream<core::int*>* /* originally async* */ {
@@ -685,20 +702,22 @@
           }
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method future<T extends core::Object* = dynamic>(self::future::T* value) → FutureOr<self::future::T*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<self::future::T*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::future::T*>();
+  final asy::_Future<self::future::T*>* :async_future = new asy::_Future::•<self::future::T*>();
+  core::bool* :is_sync = false;
   FutureOr<self::future::T*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -712,17 +731,18 @@
         :return_value = value;
         break #L17;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method id<T extends core::Object* = dynamic>(self::id::T* value) → FutureOr<self::id::T*>*
   return value;
@@ -762,7 +782,8 @@
   return :controller_stream;
 }
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -791,17 +812,18 @@
           :result;
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!expected.{core::Object::==}(actual))
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect
index 7c1f7a3..fe03b1d 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/await_in_cascade.dart.weak.transformed.expect
@@ -11,7 +11,8 @@
     : super core::Object::•()
     ;
   method m() → asy::Future<core::List<core::int*>*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
+    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;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -29,20 +30,22 @@
           :return_value = block {} =>#t1;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   method _m() → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -56,17 +59,18 @@
           :return_value = 42;
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   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
@@ -80,7 +84,8 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -95,17 +100,18 @@
         [yield] let dynamic #t3 = asy::_awaitHelper(new self::C::•().{self::C::m}(), :async_op_then, :async_op_error, :async_op) in null;
         self::expect(42, _in::unsafeCast<core::List<core::int*>*>(:result).{core::Iterable::first});
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method expect(dynamic expected, dynamic actual) → dynamic {
   if(!expected.{core::Object::==}(actual))
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.weak.transformed.expect
index 79fa612..fe416ab 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33196.dart.weak.transformed.expect
@@ -10,7 +10,8 @@
   core::print(result.{core::Object::runtimeType});
 }
 static method returnsString() → FutureOr<core::String*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::String*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::String*>();
+  final asy::_Future<core::String*>* :async_future = new asy::_Future::•<core::String*>();
+  core::bool* :is_sync = false;
   FutureOr<core::String*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -24,15 +25,16 @@
         :return_value = "oh no";
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect
index a6aaad8..389811c 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/bug33206.dart.weak.transformed.expect
@@ -41,7 +41,8 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static method f1() → asy::Future<core::List<core::Object*>*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::List<core::Object*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::Object*>*>();
+  final asy::_Future<core::List<core::Object*>*>* :async_future = new asy::_Future::•<core::List<core::Object*>*>();
+  core::bool* :is_sync = false;
   FutureOr<core::List<core::Object*>*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -55,22 +56,24 @@
         :return_value = <core::Object*>[1];
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method f2() → core::List<core::Object*>*
   return <core::Object*>[2];
 static method f3() → asy::Future<core::Object*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::Object*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::Object*>();
+  final asy::_Future<core::Object*>* :async_future = new asy::_Future::•<core::Object*>();
+  core::bool* :is_sync = false;
   FutureOr<core::Object*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -84,20 +87,22 @@
         :return_value = 3;
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method foo() → asy::Future<self::X*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<self::X*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::X*>();
+  final asy::_Future<self::X*>* :async_future = new asy::_Future::•<self::X*>();
+  core::bool* :is_sync = false;
   FutureOr<self::X*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -120,20 +125,22 @@
         :return_value = new self::X::•(_in::unsafeCast<self::Y*>(:async_temporary_0), _in::unsafeCast<core::Object*>(:result));
         break #L3;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → asy::Future<void>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<void>* :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
+  final asy::_Future<void>* :async_future = new asy::_Future::•<void>();
+  core::bool* :is_sync = false;
   FutureOr<void>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -148,15 +155,16 @@
         [yield] let dynamic #t4 = asy::_awaitHelper(self::foo(), :async_op_then, :async_op_error, :async_op) in null;
         core::print(_in::unsafeCast<self::X*>(:result));
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.weak.transformed.expect
index 8df91fe..ad4521b 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/check_deferred_before_args2.dart.weak.transformed.expect
@@ -8,7 +8,8 @@
 
 static method main() → dynamic {}
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -24,17 +25,18 @@
         [yield] let dynamic #t2 = asy::_awaitHelper(LoadLibrary(lib), :async_op_then, :async_op_error, :async_op) in null;
         def::m(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 
 library;
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect
index 2746526..0b06074 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/control_flow_collection_inference.dart.weak.transformed.expect
@@ -2339,7 +2339,8 @@
   } =>#t337;
 }
 static method testForElementErrors(core::Map<core::int*, core::int*>* map, core::List<core::int*>* list) → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -2886,17 +2887,18 @@
           #t433.{core::Map::[]=}("baz", null);
         } =>#t433;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method testForElementErrorsNotAsync(asy::Stream<core::int*>* stream) → dynamic {
   block {
diff --git a/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.weak.transformed.expect b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.weak.transformed.expect
index 64daac2..a4ac3f4 100644
--- a/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general_nnbd_opt_out/future_or_test.dart.weak.transformed.expect
@@ -28,7 +28,8 @@
     : super core::Object::•()
     ;
   method bar() → asy::Future<dynamic>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+    final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+    core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -42,17 +43,18 @@
           :return_value = this.{self::B::a}.{self::A::foo}();
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   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
@@ -71,7 +73,8 @@
     : super core::Object::•()
     ;
   method baz() → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -85,17 +88,18 @@
           :return_value = this.{self::C::b}.{self::B::bar}() as{TypeError} FutureOr<core::int*>*;
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   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/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml
new file mode 100644
index 0000000..e20ec17
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml
@@ -0,0 +1,150 @@
+# Copyright (c) 2020, 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.md file.
+
+# If issuing a "compiling with strong mode but [...]" error, we should be able
+# to get rid of it if the error is fixed.
+
+type: newworld
+worlds:
+  - entry: package:baz/main.dart
+    experiments: non-nullable
+    nnbdMode: strong
+    errors: true
+    sources:
+      .dart_tool/package_config.json: |
+        {
+          "configVersion": 2,
+          "packages": [
+            {
+              "name": "foo",
+              "rootUri": "../foo",
+              "packageUri": "lib/",
+              "languageVersion": "2.8"
+            },
+            {
+              "name": "bar",
+              "rootUri": "../bar",
+              "packageUri": "lib/",
+              "languageVersion": "2.8"
+            },
+            {
+              "name": "baz",
+              "rootUri": "../baz",
+              "packageUri": ""
+            }
+          ]
+        }
+      foo/lib/foo.dart: |
+        // This file is in weak mode.
+        int x = null;
+      bar/lib/bar.dart: |
+        // This file is in weak mode.
+        int y = null;
+      baz/main.dart: |
+        // This file wants to be strong.
+        import "package:foo/foo.dart" as foo;
+        import "package:bar/bar.dart" as bar;
+        main() {
+          print(foo.x);
+          print(bar.y);
+        }
+    expectedLibraryCount: 3
+
+  # Update "nothing" so we still want the error.
+  - entry: package:baz/main.dart
+    experiments: non-nullable
+    nnbdMode: strong
+    worldType: updated
+    expectInitializeFromDill: false
+    errors: true
+    invalidate:
+      - baz/main.dart
+    sources:
+      baz/main.dart: |
+        // This file wants to be strong.
+        import "package:foo/foo.dart" as foo;
+        import "package:bar/bar.dart" as bar;
+        main() {
+          print(foo.x);
+          print(bar.y);
+          print("done");
+        }
+    expectedLibraryCount: 3
+
+
+  # Update ONE package to be strong.
+  - entry: package:baz/main.dart
+    experiments: non-nullable
+    nnbdMode: strong
+    worldType: updated
+    expectInitializeFromDill: false
+    errors: true
+    invalidate:
+      # .dart_tool/package_config.json is invalidated implicitly.
+      - foo/lib/foo.dart
+    sources:
+      .dart_tool/package_config.json: |
+        {
+          "configVersion": 2,
+          "packages": [
+            {
+              "name": "foo",
+              "rootUri": "../foo",
+              "packageUri": "lib/"
+            },
+            {
+              "name": "bar",
+              "rootUri": "../bar",
+              "packageUri": "lib/",
+              "languageVersion": "2.8"
+            },
+            {
+              "name": "baz",
+              "rootUri": "../baz",
+              "packageUri": ""
+            }
+          ]
+        }
+      foo/lib/foo.dart: |
+        // This file is in strong mode.
+        int x = 42;
+    expectedLibraryCount: 3
+
+  # Update the last package to be strong.
+  - entry: package:baz/main.dart
+    experiments: non-nullable
+    nnbdMode: strong
+    worldType: updated
+    expectInitializeFromDill: false
+    errors: false
+    invalidate:
+      # .dart_tool/package_config.json is invalidated implicitly.
+      - bar/lib/bar.dart
+    sources:
+      .dart_tool/package_config.json: |
+        {
+          "configVersion": 2,
+          "packages": [
+            {
+              "name": "foo",
+              "rootUri": "../foo",
+              "packageUri": "lib/"
+            },
+            {
+              "name": "bar",
+              "rootUri": "../bar",
+              "packageUri": "lib/"
+            },
+            {
+              "name": "baz",
+              "rootUri": "../baz",
+              "packageUri": ""
+            }
+          ]
+        }
+      bar/lib/bar.dart: |
+        // This file is in strong mode.
+        int y = 42;
+    expectedLibraryCount: 3
+
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.1.expect
new file mode 100644
index 0000000..cdbc8c9
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.1.expect
@@ -0,0 +1,31 @@
+main = main::main;
+//
+// Problems in component:
+//
+// Error: This project cannot run with sound null safety, because one or more project dependencies do not
+// support null safety:
+//
+//  - package:foo
+//  - package:bar
+//
+// Run 'pub outdated --mode=null-safety' to determine if versions of your
+// dependencies supporting null safety are available.
+//
+library from "package:bar/bar.dart" as bar {
+
+  static field dart.core::int* y = null;
+}
+library from "package:baz/main.dart" as main {
+
+  import "package:foo/foo.dart" as foo;
+  import "package:bar/bar.dart" as bar;
+
+  static method main() → dynamic {
+    dart.core::print(foo::x);
+    dart.core::print(bar::y);
+  }
+}
+library from "package:foo/foo.dart" as foo {
+
+  static field dart.core::int* x = null;
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.2.expect
new file mode 100644
index 0000000..d574728
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.2.expect
@@ -0,0 +1,32 @@
+main = main::main;
+//
+// Problems in component:
+//
+// Error: This project cannot run with sound null safety, because one or more project dependencies do not
+// support null safety:
+//
+//  - package:foo
+//  - package:bar
+//
+// Run 'pub outdated --mode=null-safety' to determine if versions of your
+// dependencies supporting null safety are available.
+//
+library from "package:bar/bar.dart" as bar {
+
+  static field dart.core::int* y = null;
+}
+library from "package:baz/main.dart" as main {
+
+  import "package:foo/foo.dart" as foo;
+  import "package:bar/bar.dart" as bar;
+
+  static method main() → dynamic {
+    dart.core::print(foo::x);
+    dart.core::print(bar::y);
+    dart.core::print("done");
+  }
+}
+library from "package:foo/foo.dart" as foo {
+
+  static field dart.core::int* x = null;
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.3.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.3.expect
new file mode 100644
index 0000000..caa2322
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.3.expect
@@ -0,0 +1,31 @@
+main = main::main;
+//
+// Problems in component:
+//
+// Error: This project cannot run with sound null safety, because one or more project dependencies do not
+// support null safety:
+//
+//  - package:bar
+//
+// Run 'pub outdated --mode=null-safety' to determine if versions of your
+// dependencies supporting null safety are available.
+//
+library from "package:bar/bar.dart" as bar {
+
+  static field dart.core::int* y = null;
+}
+library from "package:baz/main.dart" as main {
+
+  import "package:foo/foo.dart" as foo;
+  import "package:bar/bar.dart" as bar;
+
+  static method main() → dynamic {
+    dart.core::print(foo::x);
+    dart.core::print(bar::y);
+    dart.core::print("done");
+  }
+}
+library from "package:foo/foo.dart" as foo {
+
+  static field dart.core::int x = 42;
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.4.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.4.expect
new file mode 100644
index 0000000..d960f32
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/can_get_rid_of_nnbd_issue_error.yaml.world.4.expect
@@ -0,0 +1,20 @@
+main = main::main;
+library from "package:bar/bar.dart" as bar {
+
+  static field dart.core::int y = 42;
+}
+library from "package:baz/main.dart" as main {
+
+  import "package:foo/foo.dart" as foo;
+  import "package:bar/bar.dart" as bar;
+
+  static method main() → dynamic {
+    dart.core::print(foo::x);
+    dart.core::print(bar::y);
+    dart.core::print("done");
+  }
+}
+library from "package:foo/foo.dart" as foo {
+
+  static field dart.core::int x = 42;
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.1.expect
index fedb19b..7c5af72 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.1.expect
@@ -2,7 +2,8 @@
 library from "org-dartlang-test:///libA.dart" as libA {
 
   static method whatever() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -19,17 +20,18 @@
           :return_value = "hello";
           break #L1;
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 library from "org-dartlang-test:///main.dart" as main {
@@ -54,7 +56,8 @@
     abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
   }
   static method main() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -70,17 +73,18 @@
           :result;
           dart.core::print(#C2);
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 constants  {
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.2.expect
index 7adfc8a..4b0f955 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_3.yaml.world.2.expect
@@ -2,7 +2,8 @@
 library from "org-dartlang-test:///libA.dart" as libA {
 
   static method whatever() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -19,17 +20,18 @@
           :return_value = "hello";
           break #L1;
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 library from "org-dartlang-test:///main.dart" as main {
@@ -54,7 +56,8 @@
     abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
   }
   static method main() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -71,17 +74,18 @@
           dart.core::print(#C2);
           dart.core::print("Done");
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 constants  {
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.1.expect
index 959ae9a..692ae81 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.1.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.1.expect
@@ -20,7 +20,8 @@
     abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
   }
   static method main() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -36,20 +37,22 @@
           :result;
           dart.core::print(#C2);
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   static method /* from org-dartlang-test:///myPart.dart */ whatever() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -66,17 +69,18 @@
           :return_value = "hello";
           break #L2;
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 constants  {
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.2.expect
index cd3593e..884a62e 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.2.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.2.expect
@@ -20,7 +20,8 @@
     abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
   }
   static method main() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -36,20 +37,22 @@
           :result;
           dart.core::print(#C2);
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   static method /* from org-dartlang-test:///myPart.dart */ whatever() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -66,17 +69,18 @@
           :return_value = "hello!!!";
           break #L2;
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 constants  {
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.3.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.3.expect
index 588647a..5287c01 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.3.expect
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/no_outline_change_5.yaml.world.3.expect
@@ -20,7 +20,8 @@
     abstract member-signature get runtimeType() → dart.core::Type*; -> dart.core::Object::runtimeType
   }
   static method main() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -37,20 +38,22 @@
           dart.core::print(#C2);
           dart.core::print("Done!");
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   static method /* from org-dartlang-test:///myPart.dart */ whatever() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -67,17 +70,18 @@
           :return_value = "hello!!!";
           break #L2;
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 constants  {
diff --git a/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
index 0903294..487e430 100644
--- a/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
@@ -27,7 +27,8 @@
   abstract member-signature method timeout(core::Duration* timeLimit, {generic-covariant-impl () →* FutureOr<core::int*>* onTimeout = #C1}) → asy::Future<core::int*>*; -> asy::Future::timeout
 }
 static method test() → void /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -50,7 +51,8 @@
         FutureOr<self::MyFuture*>* x8;
         self::MyFuture* x9;
         function test0() → asy::Future<core::int*>* /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+          final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+          core::bool* :is_sync = false;
           FutureOr<core::int*>* :return_value;
           dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
@@ -64,20 +66,22 @@
                 :return_value = x0;
                 break #L2;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         function test1() → asy::Future<core::int*>* /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+          final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+          core::bool* :is_sync = false;
           FutureOr<core::int*>* :return_value;
           dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
@@ -91,20 +95,22 @@
                 :return_value = x1;
                 break #L3;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         function test2() → asy::Future<asy::Future<core::int*>*>* /* originally async */ {
-          final asy::_AsyncAwaitCompleter<asy::Future<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<asy::Future<core::int*>*>();
+          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;
           dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
@@ -118,20 +124,22 @@
                 :return_value = x2;
                 break #L4;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         function test3() → asy::Future<FutureOr<core::int*>*>* /* originally async */ {
-          final asy::_AsyncAwaitCompleter<FutureOr<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<FutureOr<core::int*>*>();
+          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;
           dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
@@ -145,20 +153,22 @@
                 :return_value = x3;
                 break #L5;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         function test4() → asy::Future<self::MyFuture*>* /* originally async */ {
-          final asy::_AsyncAwaitCompleter<self::MyFuture*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::MyFuture*>();
+          final asy::_Future<self::MyFuture*>* :async_future = new asy::_Future::•<self::MyFuture*>();
+          core::bool* :is_sync = false;
           FutureOr<self::MyFuture*>* :return_value;
           dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
@@ -172,20 +182,22 @@
                 :return_value = x4;
                 break #L6;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         function test5() → asy::Future<core::int*>* /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+          final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+          core::bool* :is_sync = false;
           FutureOr<core::int*>* :return_value;
           dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
@@ -199,20 +211,22 @@
                 :return_value = x5;
                 break #L7;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         function test6() → asy::Future<asy::Future<core::int*>*>* /* originally async */ {
-          final asy::_AsyncAwaitCompleter<asy::Future<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<asy::Future<core::int*>*>();
+          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;
           dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
@@ -226,20 +240,22 @@
                 :return_value = x6;
                 break #L8;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         function test7() → asy::Future<FutureOr<core::int*>*>* /* originally async */ {
-          final asy::_AsyncAwaitCompleter<FutureOr<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<FutureOr<core::int*>*>();
+          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;
           dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
@@ -253,20 +269,22 @@
                 :return_value = x7;
                 break #L9;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         function test8() → asy::Future<self::MyFuture*>* /* originally async */ {
-          final asy::_AsyncAwaitCompleter<self::MyFuture*>* :async_completer = new asy::_AsyncAwaitCompleter::•<self::MyFuture*>();
+          final asy::_Future<self::MyFuture*>* :async_future = new asy::_Future::•<self::MyFuture*>();
+          core::bool* :is_sync = false;
           FutureOr<self::MyFuture*>* :return_value;
           dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
@@ -280,20 +298,22 @@
                 :return_value = x8;
                 break #L10;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         function test9() → asy::Future<core::int*>* /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+          final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+          core::bool* :is_sync = false;
           FutureOr<core::int*>* :return_value;
           dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
@@ -307,17 +327,18 @@
                 :return_value = x9;
                 break #L11;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         [yield] let dynamic #t1 = asy::_awaitHelper(x0, :async_op_then, :async_op_error, :async_op) in null;
         core::int* y0 = _in::unsafeCast<core::int*>(:result);
@@ -340,17 +361,18 @@
         [yield] let dynamic #t10 = asy::_awaitHelper(x9, :async_op_then, :async_op_error, :async_op) in null;
         core::int* y9 = _in::unsafeCast<core::int*>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.transformed.expect
index bcf04f1..e19b6bd 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_flatten.dart.strong.transformed.expect
@@ -8,7 +8,8 @@
 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 */ {
-  final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+  final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+  core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -22,17 +23,18 @@
         :return_value = self::futureInt;
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 };
 static method main() → dynamic {
   self::f;
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.strong.transformed.expect
index 8aa532e..e7ca87d 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future.dart.strong.transformed.expect
@@ -4,7 +4,8 @@
 import "dart:core" as core;
 
 static field () →* asy::Future<core::int*>* f = () → asy::Future<core::int*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+  final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+  core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -18,17 +19,18 @@
         :return_value = 0;
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 };
 static method main() → dynamic {
   self::f;
diff --git a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.transformed.expect
index 5aaec68..191fffb 100644
--- a/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_closure_return_type_future_or.dart.strong.transformed.expect
@@ -8,7 +8,8 @@
 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 */ {
-  final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+  final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+  core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -22,17 +23,18 @@
         :return_value = self::futureOrInt;
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 };
 static method main() → dynamic {
   self::f;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.transformed.expect
index f140096..04cb4b4 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_futures.dart.strong.transformed.expect
@@ -9,7 +9,8 @@
 
 static method test() → dynamic {
   () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::num*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::num*>();
+    final asy::_Future<core::num*>* :async_future = new asy::_Future::•<core::num*>();
+    core::bool* :is_sync = false;
     FutureOr<core::num*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -29,17 +30,18 @@
             break #L1;
           }
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
   asy::Future<core::num*>* g = f.call();
   asy::Future<core::int*>* h = f.call() as{TypeError} asy::Future<core::int*>*;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.transformed.expect
index 50d95e7..a7b9b3d 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_all_returns_are_values.dart.strong.transformed.expect
@@ -9,7 +9,8 @@
 
 static method test() → dynamic {
   () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::num*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::num*>();
+    final asy::_Future<core::num*>* :async_future = new asy::_Future::•<core::num*>();
+    core::bool* :is_sync = false;
     FutureOr<core::num*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -29,17 +30,18 @@
             break #L1;
           }
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
   asy::Future<core::num*>* g = f.call();
   asy::Future<core::int*>* h = f.call() as{TypeError} asy::Future<core::int*>*;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.transformed.expect
index d86bf2b..398dba4 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_async_mix_of_values_and_futures.dart.strong.transformed.expect
@@ -9,7 +9,8 @@
 
 static method test() → dynamic {
   () →* asy::Future<core::num*>* f = () → asy::Future<core::num*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::num*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::num*>();
+    final asy::_Future<core::num*>* :async_future = new asy::_Future::•<core::num*>();
+    core::bool* :is_sync = false;
     FutureOr<core::num*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -29,17 +30,18 @@
             break #L1;
           }
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
   asy::Future<core::num*>* g = f.call();
   asy::Future<core::int*>* h = f.call() as{TypeError} asy::Future<core::int*>*;
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
index 2c79978..1bde8d4 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async.dart.strong.transformed.expect
@@ -7,7 +7,8 @@
 import "dart:async";
 
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -20,7 +21,8 @@
       #L1:
       {
         () →* asy::Future<core::Null?>* f = () → asy::Future<core::Null?>* /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::Null?>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::Null?>();
+          final asy::_Future<core::Null?>* :async_future = new asy::_Future::•<core::Null?>();
+          core::bool* :is_sync = false;
           FutureOr<core::Null?>* :return_value;
           dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
@@ -34,32 +36,34 @@
                 :return_value = null;
                 break #L2;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         };
         asy::Future<dynamic>* y = f.call();
         asy::Future<core::String*>* z = f.call();
         [yield] let dynamic #t1 = asy::_awaitHelper(f.call(), :async_op_then, :async_op_error, :async_op) in null;
         core::String* s = _in::unsafeCast<core::Null?>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
index 4f7a9d4..c83accd 100644
--- a/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/block_bodied_lambdas_infer_bottom_async_star.dart.strong.transformed.expect
@@ -7,7 +7,8 @@
 import "dart:async";
 
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -59,15 +60,16 @@
         [yield] let dynamic #t1 = asy::_awaitHelper(f.call().{asy::Stream::first}, :async_op_then, :async_op_error, :async_op) in null;
         core::String* s = _in::unsafeCast<core::Null?>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect
index 07cc11f..c861eee 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_async_await.dart.strong.transformed.expect
@@ -7,7 +7,8 @@
 import "dart:async";
 
 static method main() → asy::Future<dynamic>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -25,15 +26,16 @@
         [yield] let dynamic #t2 = asy::_awaitHelper(asy::Future::value<core::List<core::int*>*>(<core::int*>[d as{TypeError,ForDynamic} core::int*]), :async_op_then, :async_op_error, :async_op) in null;
         core::List<core::int*>* l1 = _in::unsafeCast<core::List<core::int*>*>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect
index fbb47dd..30e4086 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_for_each.dart.strong.transformed.expect
@@ -60,7 +60,8 @@
 static method F<T extends core::Object* = dynamic>() → self::F::T*
   return null;
 static method f() → asy::Future<dynamic>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -226,20 +227,22 @@
             }
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → asy::Future<dynamic>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -318,17 +321,18 @@
             }
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 
 constants  {
diff --git a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect
index 27dd152..7e9c9e0 100644
--- a/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/for_each_downcast_iterable.dart.strong.transformed.expect
@@ -5,7 +5,8 @@
 import "dart:_internal" as _in;
 
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -83,16 +84,17 @@
             }
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
index 15b315a..d5ab080 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
@@ -36,7 +36,8 @@
 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 */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -52,20 +53,22 @@
           :return_value = _in::unsafeCast<core::int*>(:result);
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -81,20 +84,22 @@
           :return_value = _in::unsafeCast<core::int*>(:result);
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -108,20 +113,22 @@
           :return_value = 3;
           break #L3;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -135,24 +142,26 @@
           :return_value = 3;
           break #L4;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(3));
   asy::Future<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* {
     return asy::Future::value<core::int*>(3);
   });
   asy::Future<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -166,20 +175,22 @@
           :return_value = asy::Future::value<core::int*>(3);
           break #L5;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -193,17 +204,18 @@
           :return_value = asy::Future::value<core::int*>(3);
           break #L6;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
index e5e7002..4e59f53 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
@@ -36,7 +36,8 @@
 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 */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -52,20 +53,22 @@
           :return_value = _in::unsafeCast<core::int*>(:result);
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -81,20 +84,22 @@
           :return_value = _in::unsafeCast<core::int*>(:result);
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -108,20 +113,22 @@
           :return_value = 3;
           break #L3;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -135,24 +142,26 @@
           :return_value = 3;
           break #L4;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>(3));
   asy::Future<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* {
     return new self::MyFuture::value<core::int*>(3);
   });
   asy::Future<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -166,20 +175,22 @@
           :return_value = new self::MyFuture::value<core::int*>(3);
           break #L5;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -193,17 +204,18 @@
           :return_value = new self::MyFuture::value<core::int*>(3);
           break #L6;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
index 9e2db60..d64e850 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.strong.transformed.expect
@@ -36,7 +36,8 @@
 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 */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -52,20 +53,22 @@
           :return_value = _in::unsafeCast<core::int*>(:result);
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -81,20 +84,22 @@
           :return_value = _in::unsafeCast<core::int*>(:result);
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -108,20 +113,22 @@
           :return_value = 3;
           break #L3;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -135,24 +142,26 @@
           :return_value = 3;
           break #L4;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   self::MyFuture<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(3));
   self::MyFuture<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* {
     return asy::Future::value<core::int*>(3);
   });
   self::MyFuture<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -166,20 +175,22 @@
           :return_value = asy::Future::value<core::int*>(3);
           break #L5;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -193,17 +204,18 @@
           :return_value = asy::Future::value<core::int*>(3);
           break #L6;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
index c37addd..656e9a7 100644
--- a/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_4.dart.strong.transformed.expect
@@ -36,7 +36,8 @@
 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 */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -52,20 +53,22 @@
           :return_value = _in::unsafeCast<core::int*>(:result);
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -81,20 +84,22 @@
           :return_value = _in::unsafeCast<core::int*>(:result);
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   self::MyFuture<core::int*>* t3 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -108,20 +113,22 @@
           :return_value = 3;
           break #L3;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   self::MyFuture<core::int*>* t4 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -135,24 +142,26 @@
           :return_value = 3;
           break #L4;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   self::MyFuture<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>(3));
   self::MyFuture<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* {
     return new self::MyFuture::value<core::int*>(3);
   });
   self::MyFuture<core::int*>* t7 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -166,20 +175,22 @@
           :return_value = new self::MyFuture::value<core::int*>(3);
           break #L5;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   self::MyFuture<core::int*>* t8 = f.{self::MyFuture::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -193,17 +204,18 @@
           :return_value = new self::MyFuture::value<core::int*>(3);
           break #L6;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
index 27c8361..5f08a16 100644
--- a/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_5.dart.strong.transformed.expect
@@ -36,7 +36,8 @@
 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 */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -52,20 +53,22 @@
           :return_value = _in::unsafeCast<core::int*>(:result);
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -81,20 +84,22 @@
           :return_value = _in::unsafeCast<core::int*>(:result);
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -108,20 +113,22 @@
           :return_value = 3;
           break #L3;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -135,24 +142,26 @@
           :return_value = 3;
           break #L4;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t5 = f.{asy::Future::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* => new self::MyFuture::value<core::int*>(3));
   asy::Future<core::int*>* t6 = f.{asy::Future::then}<core::int*>((dynamic _) → self::MyFuture<core::int*>* {
     return new self::MyFuture::value<core::int*>(3);
   });
   asy::Future<core::int*>* t7 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -166,20 +175,22 @@
           :return_value = new self::MyFuture::value<core::int*>(3);
           break #L5;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -193,17 +204,18 @@
           :return_value = new self::MyFuture::value<core::int*>(3);
           break #L6;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
index 25b8d87..6e05d10 100644
--- a/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_6.dart.strong.transformed.expect
@@ -36,7 +36,8 @@
 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 */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -52,20 +53,22 @@
           :return_value = _in::unsafeCast<core::int*>(:result);
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -81,20 +84,22 @@
           :return_value = _in::unsafeCast<core::int*>(:result);
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t3 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -108,20 +113,22 @@
           :return_value = 3;
           break #L3;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t4 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -135,24 +142,26 @@
           :return_value = 3;
           break #L4;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t5 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* => asy::Future::value<core::int*>(3));
   asy::Future<core::int*>* t6 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* {
     return asy::Future::value<core::int*>(3);
   });
   asy::Future<core::int*>* t7 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -166,20 +175,22 @@
           :return_value = asy::Future::value<core::int*>(3);
           break #L5;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t8 = f.{asy::Future::then}<core::int*>((dynamic _) → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -193,17 +204,18 @@
           :return_value = asy::Future::value<core::int*>(3);
           break #L6;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
index 9be32a1..97390dc 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional.dart.strong.transformed.expect
@@ -36,7 +36,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*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -59,20 +60,22 @@
           :return_value = :async_temporary_0;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -88,17 +91,18 @@
           :return_value = (_in::unsafeCast<core::bool*>(:result) ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   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*>*);
   asy::Future<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
index 4067e3e..7e7583e 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_2.dart.strong.transformed.expect
@@ -36,7 +36,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*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -59,20 +60,22 @@
           :return_value = :async_temporary_0;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -88,17 +91,18 @@
           :return_value = (_in::unsafeCast<core::bool*>(:result) ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   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*>*);
   asy::Future<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
index 63fe450..b8e8643 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_3.dart.strong.transformed.expect
@@ -36,7 +36,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*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -59,20 +60,22 @@
           :return_value = :async_temporary_0;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -88,17 +91,18 @@
           :return_value = (_in::unsafeCast<core::bool*>(:result) ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   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*>*);
   self::MyFuture<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
index a51edd8..dbf053f 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_4.dart.strong.transformed.expect
@@ -36,7 +36,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*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -59,20 +60,22 @@
           :return_value = :async_temporary_0;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   self::MyFuture<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -88,17 +91,18 @@
           :return_value = (_in::unsafeCast<core::bool*>(:result) ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   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*>*);
   self::MyFuture<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
index 584f94a..f0ab4cd 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_5.dart.strong.transformed.expect
@@ -36,7 +36,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*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -59,20 +60,22 @@
           :return_value = :async_temporary_0;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -88,17 +91,18 @@
           :return_value = (_in::unsafeCast<core::bool*>(:result) ?{core::Object*} 2 : new self::MyFuture::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   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*>*);
   asy::Future<core::int*>* t6 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* {
diff --git a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
index e7d7fe7..27e32cf 100644
--- a/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_conditional_6.dart.strong.transformed.expect
@@ -36,7 +36,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*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -59,20 +60,22 @@
           :return_value = :async_temporary_0;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t2 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -88,17 +91,18 @@
           :return_value = (_in::unsafeCast<core::bool*>(:result) ?{core::Object*} 2 : asy::Future::value<core::int*>(3)) as{TypeError} FutureOr<core::int*>*;
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   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*>*);
   asy::Future<core::int*>* t6 = f.{asy::Future::then}<core::int*>((core::bool* x) → FutureOr<core::int*>* {
diff --git a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
index debc669..0ffe085 100644
--- a/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_ifNull.dart.strong.transformed.expect
@@ -36,7 +36,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*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -60,20 +61,22 @@
           :return_value = :async_temporary_0;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t2 = f.{self::MyFuture::then}<core::int*>((core::int* x) → FutureOr<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -89,17 +92,18 @@
           :return_value = (let final core::int* #t4 = _in::unsafeCast<core::int*>(:result) in #t4.{core::num::==}(null) ?{core::Object*} asy::Future::value<core::int*>(3) : #t4) as{TypeError} FutureOr<core::int*>*;
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   });
   asy::Future<core::int*>* t5 = f.{self::MyFuture::then}<core::int*>((core::int* x) → FutureOr<core::int*>* => (let final core::int* #t5 = x in #t5.{core::num::==}(null) ?{core::Object*} asy::Future::value<core::int*>(3) : #t5) as{TypeError} FutureOr<core::int*>*);
   asy::Future<core::int*>* t6 = f.{self::MyFuture::then}<core::int*>((core::int* x) → FutureOr<core::int*>* {
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
index 19d7f5e..cf08d88 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional.dart.strong.transformed.expect
@@ -33,7 +33,8 @@
     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}))) as{TypeError,ForDynamic} asy::Future<self::MyFuture::T*>*;
 }
 static method g1(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+  final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+  core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -47,20 +48,22 @@
         :return_value = (x ?{core::Object*} 42 : asy::Future::value<core::int*>(42)) as{TypeError} FutureOr<core::int*>*;
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method g2(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+  final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+  core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -74,20 +77,22 @@
         :return_value = (x ?{core::Object*} 42 : asy::Future::value<core::int*>(42)) as{TypeError} FutureOr<core::int*>*;
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method g3(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+  final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+  core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -102,17 +107,18 @@
         :return_value = y as{TypeError} FutureOr<core::int*>*;
         break #L3;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
index fac7441..eae9737 100644
--- a/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_async_conditional_2.dart.strong.transformed.expect
@@ -33,7 +33,8 @@
     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}))) as{TypeError,ForDynamic} asy::Future<self::MyFuture::T*>*;
 }
 static method g1(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+  final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+  core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -47,20 +48,22 @@
         :return_value = (x ?{core::Object*} 42 : new self::MyFuture::value<core::int*>(42)) as{TypeError} FutureOr<core::int*>*;
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method g2(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+  final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+  core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -74,20 +77,22 @@
         :return_value = (x ?{core::Object*} 42 : new self::MyFuture::value<core::int*>(42)) as{TypeError} FutureOr<core::int*>*;
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method g3(core::bool* x) → asy::Future<core::int*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+  final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+  core::bool* :is_sync = false;
   FutureOr<core::int*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -102,17 +107,18 @@
         :return_value = y as{TypeError} FutureOr<core::int*>*;
         break #L3;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
index b3b21ee..b26d359 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards.dart.strong.transformed.expect
@@ -45,7 +45,8 @@
                                               ^" in "hi" as{TypeError} FutureOr<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]);
 static method g2() → asy::Future<core::List<core::int*>*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
+  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;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -59,20 +60,22 @@
         :return_value = <core::int*>[3];
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method g3() → asy::Future<core::List<core::int*>*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
+  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;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -86,17 +89,18 @@
         :return_value = asy::Future::value<core::List<core::int*>*>(<core::int*>[3]);
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
index 08408e4..223a03e 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_2.dart.strong.transformed.expect
@@ -36,7 +36,8 @@
 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"));
 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]);
 static method g2() → asy::Future<core::List<core::int*>*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
+  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;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -50,20 +51,22 @@
         :return_value = <core::int*>[3];
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method g3() → asy::Future<core::List<core::int*>*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
+  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;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -77,17 +80,18 @@
         :return_value = new self::MyFuture::value<core::List<core::int*>*>(<core::int*>[3]);
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
index 1a3f92b..083d7a2 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_3.dart.strong.transformed.expect
@@ -45,7 +45,8 @@
                                               ^" in "hi" as{TypeError} FutureOr<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]);
 static method g2() → asy::Future<core::List<core::int*>*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
+  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;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -59,20 +60,22 @@
         :return_value = <core::int*>[3];
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method g3() → asy::Future<core::List<core::int*>*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
+  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;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -86,17 +89,18 @@
         :return_value = asy::Future::value<core::List<core::int*>*>(<core::int*>[3]);
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
index 578bc3b..31ccfda 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_4.dart.strong.transformed.expect
@@ -36,7 +36,8 @@
 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"));
 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]);
 static method g2() → asy::Future<core::List<core::int*>*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
+  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;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -50,20 +51,22 @@
         :return_value = <core::int*>[3];
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method g3() → asy::Future<core::List<core::int*>*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::List<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::List<core::int*>*>();
+  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;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -77,17 +80,18 @@
         :return_value = new self::MyFuture::value<core::List<core::int*>*>(<core::int*>[3]);
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect
index a3dd074..9eb7030 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_future_return.dart.strong.transformed.expect
@@ -22,7 +22,8 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static method foo() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -39,16 +40,17 @@
         [yield] let dynamic #t1 = asy::_awaitHelper(asy::Future::wait<core::List<self::A*>*>(<asy::Future<core::List<self::A*>*>*>[f1, f2]), :async_op_then, :async_op_error, :async_op) in null;
         core::List<core::List<self::A*>*>* merged = _in::unsafeCast<core::List<core::List<self::A*>*>>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect
index 3529676..b214c57 100644
--- a/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_downwards_generic_method_with_generic_return.dart.strong.transformed.expect
@@ -9,7 +9,8 @@
 static method id<T extends core::Object* = dynamic>(self::id::T* x) → self::id::T*
   return x;
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -25,16 +26,17 @@
         [yield] let dynamic #t1 = asy::_awaitHelper(self::id<FutureOr<core::String*>*>(f), :async_op_then, :async_op_error, :async_op) in null;
         core::String* s = _in::unsafeCast<core::String*>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect
index 129197b..fee2dcd 100644
--- a/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_union_upwards_generic_methods.dart.strong.transformed.expect
@@ -32,7 +32,8 @@
     ;
 }
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -54,15 +55,16 @@
         core::List<self::A*>* list = result;
         list = result2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect
index ef727eb..c1b45ec 100644
--- a/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_local_function_return_type.dart.strong.transformed.expect
@@ -7,7 +7,8 @@
   function f0() → core::int*
     return 42;
   function f1() → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -21,23 +22,25 @@
           :return_value = 42;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function f2() → core::int* {
     return 42;
   }
   function f3() → asy::Future<core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::int*>();
+    final asy::_Future<core::int*>* :async_future = new asy::_Future::•<core::int*>();
+    core::bool* :is_sync = false;
     FutureOr<core::int*>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -51,17 +54,18 @@
           :return_value = 42;
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function f4() → core::Iterable<core::int*>* /* originally sync* */ {
     function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
diff --git a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
index 7490a8d..7ef736b 100644
--- a/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/infer_types_on_loop_indices_for_each_loop_async.dart.strong.transformed.expect
@@ -56,7 +56,8 @@
     : super core::Object::•()
     ;
   method foo(generic-covariant-impl self::Bar::T* t) → dynamic /* originally async */ {
-    final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+    final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+    core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -97,17 +98,18 @@
               }
           }
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   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
@@ -125,7 +127,8 @@
     : super core::Object::•()
     ;
   method foo(generic-covariant-impl self::Baz::S* t) → dynamic /* originally async */ {
-    final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+    final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+    core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -167,17 +170,18 @@
               }
           }
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   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
@@ -242,7 +246,8 @@
   abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
 }
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -440,17 +445,18 @@
             }
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
index 392e13e..273bbbe 100644
--- a/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/local_return_and_yield.dart.strong.transformed.expect
@@ -19,7 +19,8 @@
     return (core::int* x) → core::int* => x;
   }
   function b() → asy::Future<(core::int*) →* core::int*>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<(core::int*) →* core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<(core::int*) →* core::int*>();
+    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;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -36,17 +37,18 @@
                                      ^" in ((dynamic x) → dynamic => x) as{TypeError} FutureOr<(core::int*) →* core::int*>*;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function c() → core::Iterable<(core::int*) →* core::int*>* /* originally sync* */ {
     function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
diff --git a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
index e9c085d..0028ef6 100644
--- a/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/top_level_return_and_yield.dart.strong.transformed.expect
@@ -18,7 +18,8 @@
   return (core::int* x) → core::int* => x;
 }
 static method b() → asy::Future<(core::int*) →* core::int*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<(core::int*) →* core::int*>* :async_completer = new asy::_AsyncAwaitCompleter::•<(core::int*) →* core::int*>();
+  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;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -35,17 +36,18 @@
                                    ^" in ((dynamic x) → dynamic => x) as{TypeError} FutureOr<(core::int*) →* core::int*>*;
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method c() → core::Iterable<(core::int*) →* core::int*>* /* originally sync* */ {
   function :sync_op_gen() → (core::_SyncIterator<dynamic>*, dynamic, dynamic) →* core::bool* {
diff --git a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect
index e6eea03..1af0a51 100644
--- a/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_invalid_iterable.dart.strong.transformed.expect
@@ -28,7 +28,8 @@
 import "dart:_internal" as _in;
 
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -122,16 +123,17 @@
             }
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect
index 0560069..0d9cdbd 100644
--- a/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/for_each_outer_var_type.dart.strong.transformed.expect
@@ -44,7 +44,8 @@
 static method f<T extends core::Object* = dynamic>() → self::f::T*
   return null;
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -201,16 +202,17 @@
             }
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect b/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect
index 88c3483..23a4434 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.strong.transformed.expect
@@ -137,7 +137,8 @@
   } =>#t7;
 }
 static method hest() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -178,20 +179,22 @@
         :return_value = "hest";
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method fisk() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -219,7 +222,8 @@
         core::Function? f;
         function #f#get() → core::Function
           return let final core::Function? #t15 = f in #t15.==(null) ?{core::Function} f = () → asy::Future<dynamic> /* originally async */ {
-            final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+            final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+            core::bool* :is_sync = false;
             FutureOr<dynamic>? :return_value;
             dynamic :async_stack_trace;
             (dynamic) → dynamic :async_op_then;
@@ -235,32 +239,34 @@
                   :return_value = :result;
                   break #L4;
                 }
-                asy::_completeOnAsyncReturn(:async_completer, :return_value);
+                asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
                 return;
               }
               on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-                :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+                asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
               }
             :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
             :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
             :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-            :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-            return :async_completer.{asy::Completer::future};
+            :async_op.call();
+            :is_sync = true;
+            return :async_future;
           } : #t15{core::Function};
         function #f#set(core::Function #t17) → dynamic
           return f = #t17;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
 
@@ -270,4 +276,4 @@
 
 Extra constant evaluation status:
 Evaluated: VariableGet @ org-dartlang-testcase:///later.dart:46:18 -> IntConstant(42)
-Extra constant evaluation: evaluated: 213, effectively constant: 1
+Extra constant evaluation: evaluated: 216, effectively constant: 1
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect b/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect
index 99c24bd..03aa850 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.weak.transformed.expect
@@ -157,7 +157,8 @@
   } =>#t7;
 }
 static method hest() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -198,20 +199,22 @@
         :return_value = "hest";
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method fisk() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -257,7 +260,8 @@
         function #f#get() → core::Function {
           if(!#f#isSet) {
             f = () → asy::Future<dynamic> /* originally async */ {
-              final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+              final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+              core::bool* :is_sync = false;
               FutureOr<dynamic>? :return_value;
               dynamic :async_stack_trace;
               (dynamic) → dynamic :async_op_then;
@@ -273,17 +277,18 @@
                     :return_value = :result;
                     break #L4;
                   }
-                  asy::_completeOnAsyncReturn(:async_completer, :return_value);
+                  asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
                   return;
                 }
                 on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-                  :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+                  asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
                 }
               :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
               :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
               :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-              :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-              return :async_completer.{asy::Completer::future};
+              :async_op.call();
+              :is_sync = true;
+              return :async_future;
             };
             #f#isSet = true;
           }
@@ -294,17 +299,18 @@
           return f = #t14;
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.transformed.expect
index a06a87e..cfe4af3 100644
--- a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.transformed.expect
@@ -6,7 +6,8 @@
 
 abstract class TestMixin<R extends core::Object? = dynamic, T extends core::Object? = dynamic> extends core::Object /*isMixinDeclaration*/  {
   method test(generic-covariant-impl asy::Future<self::TestMixin::R%> fetch) → asy::Future<self::TestMixin::T%> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<self::TestMixin::T%> :async_completer = new asy::_AsyncAwaitCompleter::•<self::TestMixin::T%>();
+    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;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -38,17 +39,18 @@
           :return_value = result;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 class PagingResponse<T extends core::Object? = dynamic> extends core::Object {
@@ -74,7 +76,8 @@
     : super core::Object::•()
     ;
   method test(generic-covariant-impl asy::Future<self::Response<core::String>> fetch) → asy::Future<core::String> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
+    final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
+    core::bool* :is_sync = false;
     FutureOr<core::String>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -106,17 +109,18 @@
           :return_value = result;
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 class Class1 extends self::_Class1&Object&TestMixin {
@@ -133,7 +137,8 @@
     : super core::Object::•()
     ;
   method test(generic-covariant-impl asy::Future<self::PagingResponse<core::String>> fetch) → asy::Future<core::String> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
+    final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
+    core::bool* :is_sync = false;
     FutureOr<core::String>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -165,17 +170,18 @@
           :return_value = result;
           break #L3;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 class Class2 extends self::_Class2&Object&TestMixin {
diff --git a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.transformed.expect
index a06a87e..cfe4af3 100644
--- a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.transformed.expect
@@ -6,7 +6,8 @@
 
 abstract class TestMixin<R extends core::Object? = dynamic, T extends core::Object? = dynamic> extends core::Object /*isMixinDeclaration*/  {
   method test(generic-covariant-impl asy::Future<self::TestMixin::R%> fetch) → asy::Future<self::TestMixin::T%> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<self::TestMixin::T%> :async_completer = new asy::_AsyncAwaitCompleter::•<self::TestMixin::T%>();
+    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;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -38,17 +39,18 @@
           :return_value = result;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 class PagingResponse<T extends core::Object? = dynamic> extends core::Object {
@@ -74,7 +76,8 @@
     : super core::Object::•()
     ;
   method test(generic-covariant-impl asy::Future<self::Response<core::String>> fetch) → asy::Future<core::String> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
+    final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
+    core::bool* :is_sync = false;
     FutureOr<core::String>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -106,17 +109,18 @@
           :return_value = result;
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 class Class1 extends self::_Class1&Object&TestMixin {
@@ -133,7 +137,8 @@
     : super core::Object::•()
     ;
   method test(generic-covariant-impl asy::Future<self::PagingResponse<core::String>> fetch) → asy::Future<core::String> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
+    final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
+    core::bool* :is_sync = false;
     FutureOr<core::String>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -165,17 +170,18 @@
           :return_value = result;
           break #L3;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 class Class2 extends self::_Class2&Object&TestMixin {
diff --git a/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect
index 9d772b9..50e24cb 100644
--- a/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41108.dart.strong.transformed.expect
@@ -13,7 +13,8 @@
 import "dart:_internal" as _in;
 
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -32,17 +33,18 @@
         [yield] let dynamic #t2 = asy::_awaitHelper(self::l(), :async_op_then, :async_op_error, :async_op) in null;
         core::List<dynamic> y = let core::List<dynamic>? #t3 = _in::unsafeCast<core::List<dynamic>?>(:result) in #t3.==(null) ?{core::List<dynamic>} #t3 as{TypeError,ForNonNullableByDefault} core::List<dynamic> : #t3{core::List<dynamic>};
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method l() → asy::Future<core::List<dynamic>>?
   return null;
diff --git a/pkg/front_end/testcases/nnbd/issue41108.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41108.dart.weak.transformed.expect
index c2e4964..8631965 100644
--- a/pkg/front_end/testcases/nnbd/issue41108.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41108.dart.weak.transformed.expect
@@ -13,7 +13,8 @@
 import "dart:_internal" as _in;
 
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -32,17 +33,18 @@
         [yield] let dynamic #t2 = asy::_awaitHelper(self::l(), :async_op_then, :async_op_error, :async_op) in null;
         core::List<dynamic> y = _in::unsafeCast<core::List<dynamic>?>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method l() → asy::Future<core::List<dynamic>>?
   return null;
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.strong.transformed.expect
index 3ac2da4..0d0a5f6 100644
--- a/pkg/front_end/testcases/nnbd/issue41114.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.strong.transformed.expect
@@ -4,7 +4,8 @@
 import "dart:core" as core;
 
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -20,15 +21,16 @@
         core::Iterable<core::String>? i = let final core::Iterable<core::String>? #t2 = b in #t2.{core::Object::==}(null) ?{core::Iterable<core::String>?} a : #t2{core::Iterable<core::String>};
         core::print(i);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue41114.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41114.dart.weak.transformed.expect
index 3ac2da4..0d0a5f6 100644
--- a/pkg/front_end/testcases/nnbd/issue41114.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41114.dart.weak.transformed.expect
@@ -4,7 +4,8 @@
 import "dart:core" as core;
 
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -20,15 +21,16 @@
         core::Iterable<core::String>? i = let final core::Iterable<core::String>? #t2 = b in #t2.{core::Object::==}(null) ?{core::Iterable<core::String>?} a : #t2{core::Iterable<core::String>};
         core::print(i);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect
index 07174dc..2d5c92d 100644
--- a/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect
@@ -56,7 +56,8 @@
     return self::throwing();
   };
   (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
+    final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
+    core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -70,20 +71,22 @@
           :return_value = throw v;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
   (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
+    final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
+    core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -96,20 +99,22 @@
         {
           throw v;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
   (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
+    final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
+    core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -123,20 +128,22 @@
           :return_value = throw v;
           break #L3;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
   (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
+    final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
+    core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -150,20 +157,22 @@
           :return_value = self::throwing();
           break #L4;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
   (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
+    final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
+    core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -176,20 +185,22 @@
         {
           self::throwing();
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
   (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
+    final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
+    core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -203,21 +214,23 @@
           :return_value = self::throwing();
           break #L6;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
 }
 static method errors() → void /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -269,7 +282,8 @@
                             ^" in null;
         };
         (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<core::String> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
+          final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
+          core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -290,20 +304,22 @@
                                     ^" in null;
                 break #L8;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         };
         (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<core::String> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
+          final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
+          core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -325,20 +341,22 @@
                                     ^" in null;
                 break #L9;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         };
         (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<core::String> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
+          final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
+          core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -359,20 +377,22 @@
                                     ^" in null;
                 break #L10;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         };
         (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<core::String> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
+          final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
+          core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -394,28 +414,30 @@
                                     ^" in null;
                 break #L11;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         };
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect
index 73ca4fa..f657157 100644
--- a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect
@@ -57,7 +57,8 @@
     return let final Never #t3 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
   };
   (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
+    final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
+    core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -71,20 +72,22 @@
           :return_value = throw v;
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
   (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
+    final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
+    core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -97,20 +100,22 @@
         {
           throw v;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
   (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
+    final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
+    core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -124,20 +129,22 @@
           :return_value = throw v;
           break #L3;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
   (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
+    final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
+    core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -151,20 +158,22 @@
           :return_value = let final Never #t4 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
           break #L4;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
   (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
+    final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
+    core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -177,20 +186,22 @@
         {
           let final Never #t5 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
   (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<Never> :async_completer = new asy::_AsyncAwaitCompleter::•<Never>();
+    final asy::_Future<Never> :async_future = new asy::_Future::•<Never>();
+    core::bool* :is_sync = false;
     FutureOr<Never>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -204,21 +215,23 @@
           :return_value = let final Never #t6 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
           break #L6;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
 }
 static method errors() → void /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -270,7 +283,8 @@
                             ^" in null;
         };
         (core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<core::String> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
+          final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
+          core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -291,20 +305,22 @@
                                     ^" in null;
                 break #L8;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         };
         (core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<core::String> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
+          final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
+          core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -326,20 +342,22 @@
                                     ^" in null;
                 break #L9;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         };
         (core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<core::String> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
+          final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
+          core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -360,20 +378,22 @@
                                     ^" in null;
                 break #L10;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         };
         (core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<core::String> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::String> :async_completer = new asy::_AsyncAwaitCompleter::•<core::String>();
+          final asy::_Future<core::String> :async_future = new asy::_Future::•<core::String>();
+          core::bool* :is_sync = false;
           FutureOr<core::String>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -395,28 +415,30 @@
                                     ^" in null;
                 break #L11;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         };
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
index e54c5af..049ebe6 100644
--- a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
@@ -34,7 +34,8 @@
 static method getNull() → dynamic
   return null;
 static method getFutureNull() → asy::Future<dynamic> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -48,20 +49,22 @@
         :return_value = null;
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method getFutureBool() → asy::Future<core::bool> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+  core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -75,20 +78,22 @@
         :return_value = true;
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method test1() → asy::Future<core::bool> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+  core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -104,24 +109,26 @@
         :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
         break #L3;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method test2() → asy::Future<core::bool>
   return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
 static method test3() → core::bool
   return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
 static method test4() → asy::Future<core::bool> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+  core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -137,17 +144,18 @@
         :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
         break #L4;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method test5() → asy::Future<core::bool>
   return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be returned from a function with return type 'Future<bool>'.
@@ -157,7 +165,8 @@
 static method test6() → asy::Future<core::bool>
   return self::getFutureBool();
 static method test7() → asy::Future<core::bool> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+  core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -171,20 +180,22 @@
         :return_value = self::getFutureBool();
         break #L5;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -196,7 +207,8 @@
       #L6:
       {
         function test1() → asy::Future<core::bool> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+          core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -212,24 +224,26 @@
                 :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
                 break #L7;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         function test2() → asy::Future<core::bool>
           return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
         function test3() → core::bool
           return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
         function test4() → asy::Future<core::bool> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+          core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -245,17 +259,18 @@
                 :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
                 break #L8;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         function test5() → asy::Future<core::bool>
           return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be returned from a function with return type 'Future<bool>'.
@@ -265,7 +280,8 @@
         function test6() → asy::Future<core::bool>
           return self::getFutureBool();
         function test7() → asy::Future<core::bool> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+          core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -279,23 +295,25 @@
                 :return_value = self::getFutureBool();
                 break #L9;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         asy::Future<core::bool> var1 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
   Future<bool> var1 = (() async => await getNull())(); // error
                                                    ^" in (() → asy::Future<dynamic> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+          final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+          core::bool* :is_sync = false;
           FutureOr<dynamic>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -311,17 +329,18 @@
                 :return_value = :result;
                 break #L10;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
         asy::Future<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
         core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
@@ -329,7 +348,8 @@
  - 'Future' is from 'dart:async'.
   Future<bool> var4 = (() async => await getFutureNull())(); // error
                                                          ^" in (() → asy::Future<dynamic> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+          final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+          core::bool* :is_sync = false;
           FutureOr<dynamic>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -345,17 +365,18 @@
                 :return_value = :result;
                 break #L11;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
         asy::Future<core::bool> var5 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
@@ -363,7 +384,8 @@
                                              ^" in (() → asy::Future<dynamic> => self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
         asy::Future<core::bool> var6 = (() → asy::Future<core::bool> => self::getFutureBool()).call();
         asy::Future<core::bool> var7 = (() → asy::Future<core::bool> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+          core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -377,29 +399,31 @@
                 :return_value = self::getFutureBool();
                 break #L12;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }).call();
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect
index e54c5af..049ebe6 100644
--- a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect
@@ -34,7 +34,8 @@
 static method getNull() → dynamic
   return null;
 static method getFutureNull() → asy::Future<dynamic> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -48,20 +49,22 @@
         :return_value = null;
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method getFutureBool() → asy::Future<core::bool> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+  core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -75,20 +78,22 @@
         :return_value = true;
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method test1() → asy::Future<core::bool> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+  core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -104,24 +109,26 @@
         :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
         break #L3;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method test2() → asy::Future<core::bool>
   return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
 static method test3() → core::bool
   return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
 static method test4() → asy::Future<core::bool> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+  core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -137,17 +144,18 @@
         :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
         break #L4;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method test5() → asy::Future<core::bool>
   return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:18:25: Error: A value of type 'Future<dynamic>' can't be returned from a function with return type 'Future<bool>'.
@@ -157,7 +165,8 @@
 static method test6() → asy::Future<core::bool>
   return self::getFutureBool();
 static method test7() → asy::Future<core::bool> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+  final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+  core::bool* :is_sync = false;
   FutureOr<core::bool>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -171,20 +180,22 @@
         :return_value = self::getFutureBool();
         break #L5;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -196,7 +207,8 @@
       #L6:
       {
         function test1() → asy::Future<core::bool> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+          core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -212,24 +224,26 @@
                 :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
                 break #L7;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         function test2() → asy::Future<core::bool>
           return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
         function test3() → core::bool
           return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
         function test4() → asy::Future<core::bool> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+          core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -245,17 +259,18 @@
                 :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
                 break #L8;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         function test5() → asy::Future<core::bool>
           return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:27:27: Error: A value of type 'Future<dynamic>' can't be returned from a function with return type 'Future<bool>'.
@@ -265,7 +280,8 @@
         function test6() → asy::Future<core::bool>
           return self::getFutureBool();
         function test7() → asy::Future<core::bool> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+          core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -279,23 +295,25 @@
                 :return_value = self::getFutureBool();
                 break #L9;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         asy::Future<core::bool> var1 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
   Future<bool> var1 = (() async => await getNull())(); // error
                                                    ^" in (() → asy::Future<dynamic> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+          final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+          core::bool* :is_sync = false;
           FutureOr<dynamic>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -311,17 +329,18 @@
                 :return_value = :result;
                 break #L10;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
         asy::Future<core::bool> var2 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
         core::bool var3 = (() → dynamic => self::getNull()).call() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
@@ -329,7 +348,8 @@
  - 'Future' is from 'dart:async'.
   Future<bool> var4 = (() async => await getFutureNull())(); // error
                                                          ^" in (() → asy::Future<dynamic> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+          final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+          core::bool* :is_sync = false;
           FutureOr<dynamic>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -345,17 +365,18 @@
                 :return_value = :result;
                 break #L11;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
         asy::Future<core::bool> var5 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
  - 'Future' is from 'dart:async'.
@@ -363,7 +384,8 @@
                                              ^" in (() → asy::Future<dynamic> => self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
         asy::Future<core::bool> var6 = (() → asy::Future<core::bool> => self::getFutureBool()).call();
         asy::Future<core::bool> var7 = (() → asy::Future<core::bool> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::bool> :async_completer = new asy::_AsyncAwaitCompleter::•<core::bool>();
+          final asy::_Future<core::bool> :async_future = new asy::_Future::•<core::bool>();
+          core::bool* :is_sync = false;
           FutureOr<core::bool>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -377,29 +399,31 @@
                 :return_value = self::getFutureBool();
                 break #L12;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }).call();
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
index 89e8bd5..fb81d0d 100644
--- a/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.strong.transformed.expect
@@ -143,7 +143,8 @@
   return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
 }
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -284,16 +285,17 @@
           return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
         }).call();
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
index 89e8bd5..fb81d0d 100644
--- a/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437b.dart.weak.transformed.expect
@@ -143,7 +143,8 @@
   return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
 }
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -284,16 +285,17 @@
           return new core::_SyncIterable::•<core::bool>(:sync_op_gen);
         }).call();
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
index 71bc53a..5bfffb3 100644
--- a/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.strong.transformed.expect
@@ -233,7 +233,8 @@
   return :controller_stream;
 }
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -482,16 +483,17 @@
           return :controller_stream;
         }).call();
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
index 71bc53a..5bfffb3 100644
--- a/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437c.dart.weak.transformed.expect
@@ -233,7 +233,8 @@
   return :controller_stream;
 }
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -482,16 +483,17 @@
           return :controller_stream;
         }).call();
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41602.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41602.dart.strong.transformed.expect
index 303fbeb..1add5c8 100644
--- a/pkg/front_end/testcases/nnbd/issue41602.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41602.dart.strong.transformed.expect
@@ -16,7 +16,8 @@
 import "dart:_internal" as _in;
 
 static method returnFutureOfVoid() → asy::Future<void> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<void> :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
+  final asy::_Future<void> :async_future = new asy::_Future::•<void>();
+  core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -27,21 +28,23 @@
     try {
       #L1:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnVoid() → void {}
 static method returnVoidAsync() → void /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -52,20 +55,22 @@
     try {
       #L2:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -82,20 +87,22 @@
         [yield] let dynamic #t2 = asy::_awaitHelper(self::returnVoidAsync(), :async_op_then, :async_op_error, :async_op) in null;
         _in::unsafeCast<void>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -110,15 +117,16 @@
         [yield] let dynamic #t3 = asy::_awaitHelper(self::returnFutureOfVoid(), :async_op_then, :async_op_error, :async_op) in null;
         _in::unsafeCast<void>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue41602.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41602.dart.weak.transformed.expect
index 303fbeb..1add5c8 100644
--- a/pkg/front_end/testcases/nnbd/issue41602.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41602.dart.weak.transformed.expect
@@ -16,7 +16,8 @@
 import "dart:_internal" as _in;
 
 static method returnFutureOfVoid() → asy::Future<void> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<void> :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
+  final asy::_Future<void> :async_future = new asy::_Future::•<void>();
+  core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -27,21 +28,23 @@
     try {
       #L1:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnVoid() → void {}
 static method returnVoidAsync() → void /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -52,20 +55,22 @@
     try {
       #L2:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method test() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -82,20 +87,22 @@
         [yield] let dynamic #t2 = asy::_awaitHelper(self::returnVoidAsync(), :async_op_then, :async_op_error, :async_op) in null;
         _in::unsafeCast<void>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -110,15 +117,16 @@
         [yield] let dynamic #t3 = asy::_awaitHelper(self::returnFutureOfVoid(), :async_op_then, :async_op_error, :async_op) in null;
         _in::unsafeCast<void>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue41697.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41697.dart.strong.transformed.expect
index 3355e4f..af60f0b 100644
--- a/pkg/front_end/testcases/nnbd/issue41697.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41697.dart.strong.transformed.expect
@@ -35,7 +35,8 @@
     return s.{core::num::+}(1);
   };
   <S extends FutureOr<core::num> = FutureOr<core::num>>(S, FutureOr<core::num>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num> = FutureOr<core::num>>(S s, FutureOr<core::num>t) → asy::Future<core::num> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::num> :async_completer = new asy::_AsyncAwaitCompleter::•<core::num>();
+    final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
+    core::bool* :is_sync = false;
     FutureOr<core::num>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -51,17 +52,18 @@
           :return_value = _in::unsafeCast<core::num>(:result).{core::num::+}(1);
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
 }
 static method test2(self::C<core::num?> c) → dynamic {
@@ -71,7 +73,8 @@
              ^" in s.{core::num::+}(1);
   };
   <S extends FutureOr<core::num?> = FutureOr<core::num?>>(S%, FutureOr<core::num?>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num?> = FutureOr<core::num?>>(S% s, FutureOr<core::num?>t) → asy::Future<core::num> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::num> :async_completer = new asy::_AsyncAwaitCompleter::•<core::num>();
+    final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
+    core::bool* :is_sync = false;
     FutureOr<core::num>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -90,17 +93,18 @@
           :return_value = _in::unsafeCast<core::num?>(:result).{core::num::+}(1);
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
 }
 static method test3<S extends core::num? = core::num?>(self::test3::S% s) → dynamic
diff --git a/pkg/front_end/testcases/nnbd/issue41697.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue41697.dart.weak.transformed.expect
index 3355e4f..af60f0b 100644
--- a/pkg/front_end/testcases/nnbd/issue41697.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41697.dart.weak.transformed.expect
@@ -35,7 +35,8 @@
     return s.{core::num::+}(1);
   };
   <S extends FutureOr<core::num> = FutureOr<core::num>>(S, FutureOr<core::num>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num> = FutureOr<core::num>>(S s, FutureOr<core::num>t) → asy::Future<core::num> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::num> :async_completer = new asy::_AsyncAwaitCompleter::•<core::num>();
+    final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
+    core::bool* :is_sync = false;
     FutureOr<core::num>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -51,17 +52,18 @@
           :return_value = _in::unsafeCast<core::num>(:result).{core::num::+}(1);
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
 }
 static method test2(self::C<core::num?> c) → dynamic {
@@ -71,7 +73,8 @@
              ^" in s.{core::num::+}(1);
   };
   <S extends FutureOr<core::num?> = FutureOr<core::num?>>(S%, FutureOr<core::num?>) → asy::Future<core::num> f2 = c.{self::C::field2} = <S extends FutureOr<core::num?> = FutureOr<core::num?>>(S% s, FutureOr<core::num?>t) → asy::Future<core::num> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::num> :async_completer = new asy::_AsyncAwaitCompleter::•<core::num>();
+    final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
+    core::bool* :is_sync = false;
     FutureOr<core::num>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -90,17 +93,18 @@
           :return_value = _in::unsafeCast<core::num?>(:result).{core::num::+}(1);
           break #L2;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   };
 }
 static method test3<S extends core::num? = core::num?>(self::test3::S% s) → dynamic
diff --git a/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect
index 5fbd656..630569b 100644
--- a/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect
@@ -6,7 +6,8 @@
 static method getNull() → dynamic
   return null;
 static method fn() → asy::Future<core::Object> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::Object> :async_completer = new asy::_AsyncAwaitCompleter::•<core::Object>();
+  final asy::_Future<core::Object> :async_future = new asy::_Future::•<core::Object>();
+  core::bool* :is_sync = false;
   FutureOr<core::Object>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -24,16 +25,17 @@
         :return_value = let dynamic #t4 = :result in #t4.==(null) ?{FutureOr<core::Object>} #t4 as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::Object> : #t4{FutureOr<core::Object>};
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42540.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42540.dart.weak.transformed.expect
index ae9a451..d317b87 100644
--- a/pkg/front_end/testcases/nnbd/issue42540.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42540.dart.weak.transformed.expect
@@ -6,7 +6,8 @@
 static method getNull() → dynamic
   return null;
 static method fn() → asy::Future<core::Object> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::Object> :async_completer = new asy::_AsyncAwaitCompleter::•<core::Object>();
+  final asy::_Future<core::Object> :async_future = new asy::_Future::•<core::Object>();
+  core::bool* :is_sync = false;
   FutureOr<core::Object>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -24,16 +25,17 @@
         :return_value = :result;
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42743.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42743.dart.strong.transformed.expect
index 454a896..47601b2 100644
--- a/pkg/front_end/testcases/nnbd/issue42743.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42743.dart.strong.transformed.expect
@@ -4,7 +4,8 @@
 import "dart:core" as core;
 
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -21,7 +22,8 @@
             return 42;
         };
         (dynamic _) → asy::Future<core::int?> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
+          final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
+          core::bool* :is_sync = false;
           FutureOr<core::int?>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -37,28 +39,30 @@
                   break #L2;
                 }
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         };
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/nnbd/issue42743.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42743.dart.weak.transformed.expect
index 454a896..47601b2 100644
--- a/pkg/front_end/testcases/nnbd/issue42743.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42743.dart.weak.transformed.expect
@@ -4,7 +4,8 @@
 import "dart:core" as core;
 
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -21,7 +22,8 @@
             return 42;
         };
         (dynamic _) → asy::Future<core::int?> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
+          final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
+          core::bool* :is_sync = false;
           FutureOr<core::int?>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -37,28 +39,30 @@
                   break #L2;
                 }
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         };
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
index f60d55f..597bd6c 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
@@ -124,7 +124,8 @@
   } =>#t1;
 }
 static method hest() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -165,20 +166,22 @@
         :return_value = "hest";
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method fisk() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -201,7 +204,8 @@
         late core::String s2 = #s2#initializer.call();
         function #f#initializer() → core::Function
           return () → asy::Future<dynamic> /* originally async */ {
-            final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+            final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+            core::bool* :is_sync = false;
             FutureOr<dynamic>? :return_value;
             dynamic :async_stack_trace;
             (dynamic) → dynamic :async_op_then;
@@ -217,31 +221,33 @@
                   :return_value = :result;
                   break #L4;
                 }
-                asy::_completeOnAsyncReturn(:async_completer, :return_value);
+                asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
                 return;
               }
               on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-                :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+                asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
               }
             :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
             :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
             :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-            :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-            return :async_completer.{asy::Completer::future};
+            :async_op.call();
+            :is_sync = true;
+            return :async_future;
           };
         late core::Function f = #f#initializer.call();
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
index f60d55f..597bd6c 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
@@ -124,7 +124,8 @@
   } =>#t1;
 }
 static method hest() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -165,20 +166,22 @@
         :return_value = "hest";
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method fisk() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -201,7 +204,8 @@
         late core::String s2 = #s2#initializer.call();
         function #f#initializer() → core::Function
           return () → asy::Future<dynamic> /* originally async */ {
-            final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+            final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+            core::bool* :is_sync = false;
             FutureOr<dynamic>? :return_value;
             dynamic :async_stack_trace;
             (dynamic) → dynamic :async_op_then;
@@ -217,31 +221,33 @@
                   :return_value = :result;
                   break #L4;
                 }
-                asy::_completeOnAsyncReturn(:async_completer, :return_value);
+                asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
                 return;
               }
               on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-                :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+                asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
               }
             :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
             :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
             :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-            :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-            return :async_completer.{asy::Completer::future};
+            :async_op.call();
+            :is_sync = true;
+            return :async_future;
           };
         late core::Function f = #f#initializer.call();
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
 
diff --git a/pkg/front_end/testcases/nnbd/return_async.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/return_async.dart.strong.transformed.expect
index 9d3119e..c130478 100644
--- a/pkg/front_end/testcases/nnbd/return_async.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_async.dart.strong.transformed.expect
@@ -10,7 +10,8 @@
   throw "";
 }
 static method allYield() → asy::Future<void> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<void> :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
+  final asy::_Future<void> :async_future = new asy::_Future::•<void>();
+  core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -27,20 +28,22 @@
         [yield] let dynamic #t2 = asy::_awaitHelper(self::allYield2(), :async_op_then, :async_op_error, :async_op) in null;
         _in::unsafeCast<void>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method allYield2() → asy::Future<void> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<void> :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
+  final asy::_Future<void> :async_future = new asy::_Future::•<void>();
+  core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -57,20 +60,22 @@
         [yield] let dynamic #t4 = asy::_awaitHelper(self::allYield3(), :async_op_then, :async_op_error, :async_op) in null;
         _in::unsafeCast<void>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method allYield3() → asy::Future<void> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<void> :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
+  final asy::_Future<void> :async_future = new asy::_Future::•<void>();
+  core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -86,20 +91,22 @@
         _in::unsafeCast<core::int>(:result);
         self::throwSync();
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method customErrorZone() → asy::Future<void> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<void> :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
+  final asy::_Future<void> :async_future = new asy::_Future::•<void>();
+  core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -112,7 +119,8 @@
       {
         final asy::Completer<void> completer = asy::Completer::•<void>();
         asy::runZonedGuarded<asy::Future<core::Null?>>(() → asy::Future<core::Null?> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::Null?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::Null?>();
+          final asy::_Future<core::Null?> :async_future = new asy::_Future::•<core::Null?>();
+          core::bool* :is_sync = false;
           FutureOr<core::Null?>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -128,33 +136,35 @@
                 _in::unsafeCast<void>(:result);
                 completer.{asy::Completer::complete}(null);
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }, (core::Object e, core::StackTrace s) → void {
           completer.{asy::Completer::completeError}(e, s);
         });
         :return_value = completer.{asy::Completer::future};
         break #L4;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/return_async.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/return_async.dart.weak.transformed.expect
index 9d3119e..c130478 100644
--- a/pkg/front_end/testcases/nnbd/return_async.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_async.dart.weak.transformed.expect
@@ -10,7 +10,8 @@
   throw "";
 }
 static method allYield() → asy::Future<void> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<void> :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
+  final asy::_Future<void> :async_future = new asy::_Future::•<void>();
+  core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -27,20 +28,22 @@
         [yield] let dynamic #t2 = asy::_awaitHelper(self::allYield2(), :async_op_then, :async_op_error, :async_op) in null;
         _in::unsafeCast<void>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method allYield2() → asy::Future<void> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<void> :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
+  final asy::_Future<void> :async_future = new asy::_Future::•<void>();
+  core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -57,20 +60,22 @@
         [yield] let dynamic #t4 = asy::_awaitHelper(self::allYield3(), :async_op_then, :async_op_error, :async_op) in null;
         _in::unsafeCast<void>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method allYield3() → asy::Future<void> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<void> :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
+  final asy::_Future<void> :async_future = new asy::_Future::•<void>();
+  core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -86,20 +91,22 @@
         _in::unsafeCast<core::int>(:result);
         self::throwSync();
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method customErrorZone() → asy::Future<void> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<void> :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
+  final asy::_Future<void> :async_future = new asy::_Future::•<void>();
+  core::bool* :is_sync = false;
   FutureOr<void>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -112,7 +119,8 @@
       {
         final asy::Completer<void> completer = asy::Completer::•<void>();
         asy::runZonedGuarded<asy::Future<core::Null?>>(() → asy::Future<core::Null?> /* originally async */ {
-          final asy::_AsyncAwaitCompleter<core::Null?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::Null?>();
+          final asy::_Future<core::Null?> :async_future = new asy::_Future::•<core::Null?>();
+          core::bool* :is_sync = false;
           FutureOr<core::Null?>? :return_value;
           dynamic :async_stack_trace;
           (dynamic) → dynamic :async_op_then;
@@ -128,33 +136,35 @@
                 _in::unsafeCast<void>(:result);
                 completer.{asy::Completer::complete}(null);
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }, (core::Object e, core::StackTrace s) → void {
           completer.{asy::Completer::completeError}(e, s);
         });
         :return_value = completer.{asy::Completer::future};
         break #L4;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
index 5865ae7..35e4ddc 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.strong.transformed.expect
@@ -94,7 +94,8 @@
        ^" in null;
 }
 static method returnAsync1() → asy::Future<dynamic> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -105,20 +106,22 @@
     try {
       #L1:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnAsync2() → FutureOr<dynamic> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -129,20 +132,22 @@
     try {
       #L2:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnAsync3() → FutureOr<core::int> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::int> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int>();
+  final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+  core::bool* :is_sync = false;
   FutureOr<core::int>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -158,20 +163,22 @@
               ^" in null;
         break #L3;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnAsync4() → FutureOr<core::int?> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
+  final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
+  core::bool* :is_sync = false;
   FutureOr<core::int?>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -182,20 +189,22 @@
     try {
       #L4:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnAsync5() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -206,20 +215,22 @@
     try {
       #L5:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnAsync6() → asy::Future<core::int?> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
+  final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
+  core::bool* :is_sync = false;
   FutureOr<core::int?>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -233,20 +244,22 @@
         :return_value = null;
         break #L6;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnAsync7() → asy::Future<core::int?> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
+  final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
+  core::bool* :is_sync = false;
   FutureOr<core::int?>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -257,17 +270,18 @@
     try {
       #L7:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method yieldSync() → core::Iterable<dynamic> /* originally sync* */ {
   function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
@@ -364,7 +378,8 @@
   ^" in null;
   }
   function returnAsync1() → asy::Future<dynamic> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+    final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+    core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -375,20 +390,22 @@
       try {
         #L13:
         {}
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function returnAsync2() → FutureOr<dynamic> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+    final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+    core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -399,20 +416,22 @@
       try {
         #L14:
         {}
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function returnAsync3() → FutureOr<core::int> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int>();
+    final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+    core::bool* :is_sync = false;
     FutureOr<core::int>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -428,20 +447,22 @@
   ^" in null;
           break #L15;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function returnAsync4() → FutureOr<core::int?> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
+    final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
+    core::bool* :is_sync = false;
     FutureOr<core::int?>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -452,20 +473,22 @@
       try {
         #L16:
         {}
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function returnAsync5() → asy::Future<core::Null?> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::Null?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::Null?>();
+    final asy::_Future<core::Null?> :async_future = new asy::_Future::•<core::Null?>();
+    core::bool* :is_sync = false;
     FutureOr<core::Null?>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -476,20 +499,22 @@
       try {
         #L17:
         {}
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function returnAsync6() → asy::Future<core::int?> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
+    final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
+    core::bool* :is_sync = false;
     FutureOr<core::int?>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -503,20 +528,22 @@
           :return_value = null;
           break #L18;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function returnAsync7() → asy::Future<core::int?> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
+    final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
+    core::bool* :is_sync = false;
     FutureOr<core::int?>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -527,17 +554,18 @@
       try {
         #L19:
         {}
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function yieldSync() → core::Iterable<dynamic> /* originally sync* */ {
     function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
@@ -646,4 +674,4 @@
 Evaluated: MethodInvocation @ org-dartlang-testcase:///return_null.dart:75:14 -> BoolConstant(true)
 Evaluated: VariableGet @ org-dartlang-testcase:///return_null.dart:75:14 -> NullConstant(null)
 Evaluated: VariableGet @ org-dartlang-testcase:///return_null.dart:75:14 -> NullConstant(null)
-Extra constant evaluation: evaluated: 428, effectively constant: 12
+Extra constant evaluation: evaluated: 442, effectively constant: 12
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
index db4f23d..0a2d547 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.transformed.expect
@@ -95,7 +95,8 @@
        ^" in null;
 }
 static method returnAsync1() → asy::Future<dynamic> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -106,20 +107,22 @@
     try {
       #L1:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnAsync2() → FutureOr<dynamic> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -130,20 +133,22 @@
     try {
       #L2:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnAsync3() → FutureOr<core::int> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::int> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int>();
+  final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+  core::bool* :is_sync = false;
   FutureOr<core::int>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -159,20 +164,22 @@
               ^" in null;
         break #L3;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnAsync4() → FutureOr<core::int?> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
+  final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
+  core::bool* :is_sync = false;
   FutureOr<core::int?>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -183,20 +190,22 @@
     try {
       #L4:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnAsync5() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -207,20 +216,22 @@
     try {
       #L5:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnAsync6() → asy::Future<core::int?> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
+  final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
+  core::bool* :is_sync = false;
   FutureOr<core::int?>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -234,20 +245,22 @@
         :return_value = null;
         break #L6;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnAsync7() → asy::Future<core::int?> /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
+  final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
+  core::bool* :is_sync = false;
   FutureOr<core::int?>? :return_value;
   dynamic :async_stack_trace;
   (dynamic) → dynamic :async_op_then;
@@ -258,17 +271,18 @@
     try {
       #L7:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method yieldSync() → core::Iterable<dynamic> /* originally sync* */ {
   function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
@@ -368,7 +382,8 @@
   ^" in null;
   }
   function returnAsync1() → asy::Future<dynamic> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+    final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+    core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -379,20 +394,22 @@
       try {
         #L14:
         {}
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function returnAsync2() → FutureOr<dynamic> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+    final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+    core::bool* :is_sync = false;
     FutureOr<dynamic>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -403,20 +420,22 @@
       try {
         #L15:
         {}
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function returnAsync3() → FutureOr<core::int> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int>();
+    final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+    core::bool* :is_sync = false;
     FutureOr<core::int>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -432,20 +451,22 @@
   ^" in null;
           break #L16;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function returnAsync4() → FutureOr<core::int?> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
+    final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
+    core::bool* :is_sync = false;
     FutureOr<core::int?>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -456,20 +477,22 @@
       try {
         #L17:
         {}
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function returnAsync5() → asy::Future<core::Null?> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::Null?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::Null?>();
+    final asy::_Future<core::Null?> :async_future = new asy::_Future::•<core::Null?>();
+    core::bool* :is_sync = false;
     FutureOr<core::Null?>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -480,20 +503,22 @@
       try {
         #L18:
         {}
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function returnAsync6() → asy::Future<core::int?> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
+    final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
+    core::bool* :is_sync = false;
     FutureOr<core::int?>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -507,20 +532,22 @@
           :return_value = null;
           break #L19;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function returnAsync7() → asy::Future<core::int?> /* originally async */ {
-    final asy::_AsyncAwaitCompleter<core::int?> :async_completer = new asy::_AsyncAwaitCompleter::•<core::int?>();
+    final asy::_Future<core::int?> :async_future = new asy::_Future::•<core::int?>();
+    core::bool* :is_sync = false;
     FutureOr<core::int?>? :return_value;
     dynamic :async_stack_trace;
     (dynamic) → dynamic :async_op_then;
@@ -531,17 +558,18 @@
       try {
         #L20:
         {}
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
-        :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{asy::Completer::future};
+    :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
   function yieldSync() → core::Iterable<dynamic> /* originally sync* */ {
     function :sync_op_gen() → (core::_SyncIterator<dynamic>?, dynamic, dynamic) → core::bool* {
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 64235dc..ee6d621 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
@@ -5,7 +5,8 @@
 import "dart:_internal" as _in;
 
 static method returnFutureOfVoid() → asy::Future<void>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<void>* :async_completer = new asy::_AsyncAwaitCompleter::•<void>();
+  final asy::_Future<void>* :async_future = new asy::_Future::•<void>();
+  core::bool* :is_sync = false;
   FutureOr<void>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -16,21 +17,23 @@
     try {
       #L1:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method returnVoid() → void {}
 static method returnVoidAsync() → void /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -41,20 +44,22 @@
     try {
       #L2:
       {}
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -73,15 +78,16 @@
         [yield] let dynamic #t3 = asy::_awaitHelper(self::returnVoidAsync(), :async_op_then, :async_op_error, :async_op) in null;
         _in::unsafeCast<void>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect
index 6413088..15f42cb 100644
--- a/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_34850.dart.strong.transformed.expect
@@ -60,7 +60,8 @@
 }
 static method Future<List extends core::Object* = dynamic>() → invalid-type {}
 static method f2() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -74,20 +75,22 @@
         :return_value = null;
         break #L1;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method f3() → invalid-type /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -101,20 +104,22 @@
         :return_value = null;
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -132,15 +137,16 @@
         [yield] let dynamic #t2 = asy::_awaitHelper(self::f3(), :async_op_then, :async_op_error, :async_op) in null;
         core::print(_in::unsafeCast<invalid-type>(:result));
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect
index 5797f90..a16254c 100644
--- a/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_37681.dart.strong.transformed.expect
@@ -20,7 +20,8 @@
 import "dart:_internal" as _in;
 
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -36,7 +37,8 @@
       #L1:
       {
         function f_async() → core::int* /* originally async */ {
-          final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+          final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+          core::bool* :is_sync = false;
           FutureOr<dynamic>* :return_value;
           dynamic :async_stack_trace;
           (dynamic) →* dynamic :async_op_then;
@@ -50,17 +52,18 @@
                 :return_value = 42;
                 break #L2;
               }
-              asy::_completeOnAsyncReturn(:async_completer, :return_value);
+              asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
               return;
             }
             on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-              :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+              asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
             }
           :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
           :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
           :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-          :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-          return :async_completer.{asy::Completer::future};
+          :async_op.call();
+          :is_sync = true;
+          return :async_future;
         }
         [yield] let dynamic #t1 = asy::_awaitHelper(f_async.call(), :async_op_then, :async_op_error, :async_op) in null;
         core::print(_in::unsafeCast<core::int*>(:result));
@@ -149,15 +152,16 @@
           }
         }
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect
index 7d09113..01725ee 100644
--- a/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/set_literals/disambiguation_rule.dart.strong.transformed.expect
@@ -54,7 +54,8 @@
 import "dart:collection" show LinkedHashMap, LinkedHashSet;
 
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -108,20 +109,22 @@
         [yield] let dynamic #t15 = asy::_awaitHelper(self::lhmfun2(), :async_op_then, :async_op_error, :async_op) in null;
         col::LinkedHashMap<core::int*, core::bool*>* flhm2 = _in::unsafeCast<col::LinkedHashMap<core::int*, core::bool*>*>(:result);
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method mapfun() → asy::Future<core::Map<core::int*, core::bool*>*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::Map<core::int*, core::bool*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::Map<core::int*, core::bool*>*>();
+  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;
   FutureOr<core::Map<core::int*, core::bool*>*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -135,20 +138,22 @@
         :return_value = <core::int*, core::bool*>{};
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method setfun() → asy::Future<core::Set<core::int*>*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::Set<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::Set<core::int*>*>();
+  final asy::_Future<core::Set<core::int*>*>* :async_future = new asy::_Future::•<core::Set<core::int*>*>();
+  core::bool* :is_sync = false;
   FutureOr<core::Set<core::int*>*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -164,20 +169,22 @@
         } =>#t16;
         break #L3;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method iterablefun() → asy::Future<core::Iterable<core::int*>*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<core::Iterable<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<core::Iterable<core::int*>*>();
+  final asy::_Future<core::Iterable<core::int*>*>* :async_future = new asy::_Future::•<core::Iterable<core::int*>*>();
+  core::bool* :is_sync = false;
   FutureOr<core::Iterable<core::int*>*>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -193,20 +200,22 @@
         } =>#t17;
         break #L4;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method lhsfun() → asy::Future<col::LinkedHashSet<core::int*>*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<col::LinkedHashSet<core::int*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<col::LinkedHashSet<core::int*>*>();
+  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;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -228,20 +237,22 @@
         } =>#t19;
         break #L5;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method lhmfun() → asy::Future<col::LinkedHashMap<core::int*, core::bool*>*>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<col::LinkedHashMap<core::int*, core::bool*>*>* :async_completer = new asy::_AsyncAwaitCompleter::•<col::LinkedHashMap<core::int*, core::bool*>*>();
+  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;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -261,17 +272,18 @@
                                                    ^" in <dynamic, dynamic>{};
         break #L6;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return :async_completer.{asy::Completer::future};
+  :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method mapfun2() → FutureOr<core::Map<core::int*, core::bool*>*>*
   return <core::int*, core::bool*>{};
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index ec578d3..2b9c480 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -82,11 +82,10 @@
   Class _deprecatedFutureOrClass;
   Class _stackTraceClass;
   Class _streamClass;
-  Class _asyncAwaitCompleterClass;
-  Constructor _asyncAwaitCompleterConstructor;
-  Procedure _asyncAwaitCompleterStartProcedure;
+  Class _futureImplClass;
+  Constructor _futureImplConstructor;
+  Procedure _completeOnAsyncErrorProcedure;
   Procedure _completeOnAsyncReturnProcedure;
-  Procedure _completerCompleteError;
   Constructor _syncIterableDefaultConstructor;
   Constructor _streamIteratorDefaultConstructor;
   Constructor _asyncStarStreamControllerDefaultConstructor;
@@ -253,19 +252,13 @@
     return _boolClass ??= index.getClass('dart:core', 'bool');
   }
 
-  Class get asyncAwaitCompleterClass {
-    return _asyncAwaitCompleterClass ??=
-        index.getClass('dart:async', '_AsyncAwaitCompleter');
+  Class get futureImplClass {
+    return _futureImplClass ??= index.getClass('dart:async', '_Future');
   }
 
-  Constructor get asyncAwaitCompleterConstructor {
-    return _asyncAwaitCompleterConstructor ??=
-        index.getMember('dart:async', '_AsyncAwaitCompleter', '');
-  }
-
-  Procedure get asyncAwaitCompleterStartProcedure {
-    return _asyncAwaitCompleterStartProcedure ??=
-        index.getMember('dart:async', '_AsyncAwaitCompleter', 'start');
+  Constructor get futureImplConstructor {
+    return _futureImplConstructor ??=
+        index.getMember('dart:async', '_Future', '');
   }
 
   Member get completeOnAsyncReturn {
@@ -273,13 +266,9 @@
         index.getTopLevelMember('dart:async', '_completeOnAsyncReturn');
   }
 
-  Procedure get completerCompleteError {
-    return _completerCompleteError ??=
-        index.getMember('dart:async', 'Completer', 'completeError');
-  }
-
-  Member get completerFuture {
-    return index.getMember('dart:async', 'Completer', 'get:future');
+  Member get completeOnAsyncError {
+    return _completeOnAsyncErrorProcedure ??=
+        index.getTopLevelMember('dart:async', '_completeOnAsyncError');
   }
 
   Library get coreLibrary {
diff --git a/pkg/kernel/lib/transformations/continuation.dart b/pkg/kernel/lib/transformations/continuation.dart
index 13942d4..3900833 100644
--- a/pkg/kernel/lib/transformations/continuation.dart
+++ b/pkg/kernel/lib/transformations/continuation.dart
@@ -15,6 +15,8 @@
 
 class ContinuationVariables {
   static const awaitJumpVar = ':await_jump_var';
+  static const asyncFuture = ':async_future';
+  static const isSync = ":is_sync";
   static const awaitContextVar = ':await_ctx_var';
   static const asyncCompleter = ':async_completer';
   static const asyncOp = ':async_op';
@@ -1283,8 +1285,9 @@
 }
 
 class AsyncFunctionRewriter extends AsyncRewriterBase {
-  VariableDeclaration completerVariable;
   VariableDeclaration returnVariable;
+  VariableDeclaration asyncFutureVariable;
+  VariableDeclaration isSyncVariable;
 
   AsyncFunctionRewriter(HelperNodes helper, FunctionNode enclosingFunction,
       StaticTypeContext staticTypeContext)
@@ -1303,71 +1306,87 @@
       valueType = elementTypeFromAsyncReturnType();
     }
     final DartType returnType =
-        new FutureOrType(valueType, staticTypeContext.nullable);
-    var completerTypeArguments = <DartType>[valueType];
+        FutureOrType(valueType, staticTypeContext.nullable);
+    final futureTypeArguments = <DartType>[valueType];
 
-    final completerType = new InterfaceType(helper.asyncAwaitCompleterClass,
-        staticTypeContext.nonNullable, completerTypeArguments);
-    // final Completer<T> :async_completer = new _AsyncAwaitCompleter<T>();
-    completerVariable = new VariableDeclaration(
-        ContinuationVariables.asyncCompleter,
-        initializer: new ConstructorInvocation(
-            helper.asyncAwaitCompleterConstructor,
-            new Arguments([], types: completerTypeArguments))
+    final futureType = InterfaceType(helper.futureImplClass,
+        staticTypeContext.nonNullable, futureTypeArguments);
+
+    // final _Future<T> :async_future = _Future<T>();
+    asyncFutureVariable = VariableDeclaration(ContinuationVariables.asyncFuture,
+        initializer: ConstructorInvocation(helper.futureImplConstructor,
+            Arguments([], types: futureTypeArguments))
           ..fileOffset = enclosingFunction.body?.fileOffset ?? -1,
         isFinal: true,
-        type: completerType);
-    statements.add(completerVariable);
+        type: futureType);
+    statements.add(asyncFutureVariable);
 
-    returnVariable = new VariableDeclaration(ContinuationVariables.returnValue,
+    // bool :is_sync = false;
+    isSyncVariable = VariableDeclaration(ContinuationVariables.isSync,
+        initializer: BoolLiteral(false),
+        type: helper.coreTypes.boolLegacyRawType);
+    statements.add(isSyncVariable);
+
+    // asy::FutureOr<dynamic>* :return_value;
+    returnVariable = VariableDeclaration(ContinuationVariables.returnValue,
         type: returnType);
     statements.add(returnVariable);
 
     setupAsyncContinuations(statements);
 
-    // :async_completer.start(:async_op);
-    var startStatement = new ExpressionStatement(new MethodInvocation(
-        new VariableGet(completerVariable),
-        new Name('start'),
-        new Arguments([new VariableGet(nestedClosureVariable)]),
-        helper.asyncAwaitCompleterStartProcedure)
-      ..fileOffset = enclosingFunction.fileOffset);
+    // :async_op();
+    final startStatement = ExpressionStatement(MethodInvocation(
+      VariableGet(nestedClosureVariable),
+      Name('call'),
+      Arguments([]),
+    )..fileOffset = enclosingFunction.fileOffset);
     statements.add(startStatement);
-    // return :async_completer.future;
-    var completerGet = new VariableGet(completerVariable);
-    var returnStatement = new ReturnStatement(new PropertyGet(completerGet,
-        new Name('future', helper.asyncLibrary), helper.completerFuture));
-    statements.add(returnStatement);
 
-    enclosingFunction.body = new Block(statements);
+    // :is_sync = true;
+    final setIsSync =
+        ExpressionStatement(VariableSet(isSyncVariable, BoolLiteral(true)));
+    statements.add(setIsSync);
+
+    // return :async_future;
+    statements.add(ReturnStatement(VariableGet(asyncFutureVariable)));
+
+    enclosingFunction.body = Block(statements);
     enclosingFunction.body.parent = enclosingFunction;
     enclosingFunction.asyncMarker = AsyncMarker.Sync;
     return enclosingFunction;
   }
 
+  // :async_op's try-catch catch body:
   Statement buildCatchBody(exceptionVariable, stackTraceVariable) {
-    return new ExpressionStatement(new MethodInvocation(
-        new VariableGet(completerVariable),
-        new Name('completeError'),
-        new Arguments([
-          new VariableGet(exceptionVariable),
-          new VariableGet(stackTraceVariable)
-        ]),
-        helper.completerCompleteError));
+    // _completeOnAsyncError(_future, e, st, :is_sync)
+    return ExpressionStatement(StaticInvocation(
+        helper.completeOnAsyncError,
+        Arguments([
+          VariableGet(asyncFutureVariable),
+          VariableGet(exceptionVariable),
+          VariableGet(stackTraceVariable),
+          VariableGet(isSyncVariable)
+        ])));
   }
 
+  // :async_op's try-catch try body:
   Statement buildReturn(Statement body) {
     // Returns from the body have all been translated into assignments to the
     // return value variable followed by a break from the labeled body.
-    return new Block(<Statement>[
+
+    // .. body ..
+    // _completeOnAsyncReturn(_future, returnVariable, :is_sync)
+    // return;
+    return Block(<Statement>[
       body,
-      new ExpressionStatement(new StaticInvocation(
+      ExpressionStatement(StaticInvocation(
           helper.completeOnAsyncReturn,
-          new Arguments([
-            new VariableGet(completerVariable),
-            new VariableGet(returnVariable)
+          Arguments([
+            VariableGet(asyncFutureVariable),
+            VariableGet(returnVariable),
+            VariableGet(isSyncVariable)
           ]))),
-      new ReturnStatement()..fileOffset = enclosingFunction.fileEndOffset
+      ReturnStatement()..fileOffset = enclosingFunction.fileEndOffset
     ]);
   }
 
@@ -1396,15 +1415,14 @@
   final Member asyncStarMoveNextHelper;
   final Procedure asyncThenWrapper;
   final Procedure awaitHelper;
-  final Class asyncAwaitCompleterClass;
-  final Member completerCompleteError;
-  final Member asyncAwaitCompleterConstructor;
-  final Member asyncAwaitCompleterStartProcedure;
   final Member completeOnAsyncReturn;
-  final Member completerFuture;
+  final Member completeOnAsyncError;
   final Library coreLibrary;
   final CoreTypes coreTypes;
   final Class futureClass;
+  final Class futureOrClass;
+  final Class futureImplClass;
+  final Constructor futureImplConstructor;
   final Class iterableClass;
   final Class streamClass;
   final Member streamIteratorCancel;
@@ -1435,15 +1453,14 @@
       this.asyncStarMoveNextHelper,
       this.asyncThenWrapper,
       this.awaitHelper,
-      this.asyncAwaitCompleterClass,
-      this.completerCompleteError,
-      this.asyncAwaitCompleterConstructor,
-      this.asyncAwaitCompleterStartProcedure,
       this.completeOnAsyncReturn,
-      this.completerFuture,
+      this.completeOnAsyncError,
       this.coreLibrary,
       this.coreTypes,
       this.futureClass,
+      this.futureOrClass,
+      this.futureImplClass,
+      this.futureImplConstructor,
       this.iterableClass,
       this.streamClass,
       this.streamIteratorCancel,
@@ -1474,15 +1491,14 @@
         coreTypes.asyncStarMoveNextHelper,
         coreTypes.asyncThenWrapperHelperProcedure,
         coreTypes.awaitHelperProcedure,
-        coreTypes.asyncAwaitCompleterClass,
-        coreTypes.completerCompleteError,
-        coreTypes.asyncAwaitCompleterConstructor,
-        coreTypes.asyncAwaitCompleterStartProcedure,
         coreTypes.completeOnAsyncReturn,
-        coreTypes.completerFuture,
+        coreTypes.completeOnAsyncError,
         coreTypes.coreLibrary,
         coreTypes,
         coreTypes.futureClass,
+        coreTypes.deprecatedFutureOrClass,
+        coreTypes.futureImplClass,
+        coreTypes.futureImplConstructor,
         coreTypes.iterableClass,
         coreTypes.streamClass,
         coreTypes.streamIteratorCancel,
diff --git a/pkg/kernel/problems.md b/pkg/kernel/problems.md
index f064a3f..073789e 100644
--- a/pkg/kernel/problems.md
+++ b/pkg/kernel/problems.md
@@ -17,7 +17,13 @@
 `severity`: An integer representing severity. This should match the index in
 `package:_fe_analyzer_shared/src/messages/severity.dart`.
 
-`uri`: A uri that this problems relates to.
+`uri`: A possibly null uri that this problems relates to. This is the main uri.
+Normally this is not null (but it can be).
+
+`involvedFiles`: A possibly null list of uris involved in this message.
+Normally this is null.
+
+`codeName`: A string identifing the specific error message.
 
 These values are subject to change, but this file will be updated along with any
 such changes. On the code-side these are defined in
diff --git a/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect b/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect
index f6484af..e069735 100644
--- a/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect
+++ b/pkg/vm/testcases/transformations/deferred_loading/main.dart.expect
@@ -47,7 +47,8 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/a.dart" as a;
 
   static method j() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -60,17 +61,18 @@
         {
           dart.core::print("J");
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 library h from "#pkg/vm/testcases/transformations/deferred_loading/h.dart" as h {
@@ -78,7 +80,8 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/g.dart" as g;
 
   static method h() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -91,17 +94,18 @@
         {
           dart.core::print("H");
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 library i from "#pkg/vm/testcases/transformations/deferred_loading/i.dart" as i {
@@ -110,7 +114,8 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/b.dart" as b;
 
   static method i() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -128,17 +133,18 @@
           :return_value = let final dynamic #t2 = CheckLibraryIsLoaded(j) in j::j();
           break #L3;
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 library g from "#pkg/vm/testcases/transformations/deferred_loading/g.dart" as g {
@@ -146,7 +152,8 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/h.dart" as h;
 
   static method g() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -159,17 +166,18 @@
         {
           dart.core::print("G");
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 library f from "#pkg/vm/testcases/transformations/deferred_loading/f.dart" as f {
@@ -178,7 +186,8 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/i.dart" deferred as i;
 
   static method f() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -200,17 +209,18 @@
           :return_value = let final dynamic #t6 = CheckLibraryIsLoaded(i) in i::i();
           break #L5;
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 library e from "#pkg/vm/testcases/transformations/deferred_loading/e.dart" as e {
@@ -218,7 +228,8 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/g.dart" deferred as g;
 
   static method e() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -236,17 +247,18 @@
           :return_value = let final dynamic #t8 = CheckLibraryIsLoaded(g) in g::g();
           break #L6;
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 library c from "#pkg/vm/testcases/transformations/deferred_loading/c.dart" as c {
@@ -255,7 +267,8 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/f.dart" deferred as f;
 
   static method c() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -273,17 +286,18 @@
           :return_value = let final dynamic #t10 = CheckLibraryIsLoaded(f) in f::f();
           break #L7;
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 library d from "#pkg/vm/testcases/transformations/deferred_loading/d.dart" as d {
@@ -291,7 +305,8 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/e.dart" as e;
 
   static method d() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -306,17 +321,18 @@
           :return_value = e::e();
           break #L8;
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 library b from "#pkg/vm/testcases/transformations/deferred_loading/b.dart" as b {
@@ -324,7 +340,8 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/c.dart" as c;
 
   static method b() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -339,17 +356,18 @@
           :return_value = c::c();
           break #L9;
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 library a from "#pkg/vm/testcases/transformations/deferred_loading/a.dart" as a {
@@ -357,7 +375,8 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/d.dart" deferred as d;
 
   static method a() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -375,17 +394,18 @@
           :return_value = let final dynamic #t12 = CheckLibraryIsLoaded(d) in d::d();
           break #L10;
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 library #lib from "#lib" as #lib {
@@ -394,7 +414,8 @@
   import "#pkg/vm/testcases/transformations/deferred_loading/b.dart";
 
   static method main() → dynamic /* originally async */ {
-    final dart.async::_AsyncAwaitCompleter<dynamic>* :async_completer = new dart.async::_AsyncAwaitCompleter::•<dynamic>();
+    final dart.async::_Future<dynamic>* :async_future = new dart.async::_Future::•<dynamic>();
+    dart.core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -411,16 +432,17 @@
           [yield] let dynamic #t14 = dart.async::_awaitHelper(b::b(), :async_op_then, :async_op_error, :async_op) in null;
           :result;
         }
-        dart.async::_completeOnAsyncReturn(:async_completer, :return_value);
+        dart.async::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, dart.core::StackTrace* stack_trace) {
-        :async_completer.{dart.async::Completer::completeError}(exception, stack_trace);
+        dart.async::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = dart.async::_asyncStackTraceHelper(:async_op);
     :async_op_then = dart.async::_asyncThenWrapperHelper(:async_op);
     :async_op_error = dart.async::_asyncErrorWrapperHelper(:async_op);
-    :async_completer.{dart.async::_AsyncAwaitCompleter::start}(:async_op);
-    return :async_completer.{dart.async::Completer::future};
+    [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
index 92436bf..f1dfad8 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/async_await.dart.expect
@@ -9,7 +9,8 @@
     : super core::Object::•()
     ;
 [@vm.procedure-attributes.metadata=getterCalledDynamically:false,hasThisUses:false,hasTearOffUses:false,methodOrSetterSelectorId:1,getterSelectorId:2]  method bar(dynamic x) → asy::Future<dynamic>* /* originally async */ {
-    final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+    final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+    core::bool* :is_sync = false;
     FutureOr<dynamic>* :return_value;
     dynamic :async_stack_trace;
     (dynamic) →* dynamic :async_op_then;
@@ -23,17 +24,18 @@
           :return_value = [@vm.inferred-type.metadata=dart.core::Null? (value: null)] core::print(x);
           break #L1;
         }
-        asy::_completeOnAsyncReturn(:async_completer, :return_value);
+        asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
         return;
       }
       on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-        [@vm.direct-call.metadata=dart.async::_AsyncAwaitCompleter.completeError] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+        asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
       }
     :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
     :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
     :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-    [@vm.direct-call.metadata=dart.async::_AsyncAwaitCompleter.start] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-    return [@vm.direct-call.metadata=dart.async::_AsyncAwaitCompleter.future] [@vm.inferred-type.metadata=dart.async::_Future] :async_completer.{asy::Completer::future};
+    [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
+    :is_sync = true;
+    return :async_future;
   }
 }
 class B extends core::Object {
@@ -44,7 +46,8 @@
 static method foo() → dynamic
   return new self::A::•();
 static method baz() → asy::Future<dynamic>* /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -58,20 +61,22 @@
         :return_value = new self::B::•();
         break #L2;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      [@vm.direct-call.metadata=dart.async::_AsyncAwaitCompleter.completeError] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  [@vm.direct-call.metadata=dart.async::_AsyncAwaitCompleter.start] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return [@vm.direct-call.metadata=dart.async::_AsyncAwaitCompleter.future] [@vm.inferred-type.metadata=dart.async::_Future] :async_completer.{asy::Completer::future};
+  [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
 static method main() → dynamic /* originally async */ {
-  final asy::_AsyncAwaitCompleter<dynamic>* :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
+  final asy::_Future<dynamic>* :async_future = new asy::_Future::•<dynamic>();
+  core::bool* :is_sync = false;
   FutureOr<dynamic>* :return_value;
   dynamic :async_stack_trace;
   (dynamic) →* dynamic :async_op_then;
@@ -85,19 +90,20 @@
       #L3:
       {
         :async_temporary_0 = [@vm.inferred-type.metadata=#lib::A] self::foo();
-        [yield] let dynamic #t1 = asy::_awaitHelper([@vm.inferred-type.metadata=dart.async::_Future] self::baz(), :async_op_then, :async_op_error, :async_op) in null;
-        [yield] let dynamic #t2 = asy::_awaitHelper([@vm.direct-call.metadata=#lib::A.bar??] [@vm.inferred-type.metadata=dart.async::_Future (receiver not int)] _in::unsafeCast<dynamic>(:async_temporary_0).bar(:result), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t1 = asy::_awaitHelper([@vm.inferred-type.metadata=dart.async::_Future<dynamic>] self::baz(), :async_op_then, :async_op_error, :async_op) in null;
+        [yield] let dynamic #t2 = asy::_awaitHelper([@vm.direct-call.metadata=#lib::A.bar??] [@vm.inferred-type.metadata=dart.async::_Future<dynamic> (receiver not int)] _in::unsafeCast<dynamic>(:async_temporary_0).bar(:result), :async_op_then, :async_op_error, :async_op) in null;
         :result;
       }
-      asy::_completeOnAsyncReturn(:async_completer, :return_value);
+      asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
       return;
     }
     on dynamic catch(dynamic exception, core::StackTrace* stack_trace) {
-      [@vm.direct-call.metadata=dart.async::_AsyncAwaitCompleter.completeError] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::Completer::completeError}(exception, stack_trace);
+      asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
     }
   :async_stack_trace = asy::_asyncStackTraceHelper(:async_op);
   :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
   :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
-  [@vm.direct-call.metadata=dart.async::_AsyncAwaitCompleter.start] [@vm.inferred-type.metadata=!? (skip check)] :async_completer.{asy::_AsyncAwaitCompleter::start}(:async_op);
-  return [@vm.direct-call.metadata=dart.async::_AsyncAwaitCompleter.future] [@vm.inferred-type.metadata=dart.async::_Future] :async_completer.{asy::Completer::future};
+  [@vm.call-site-attributes.metadata=receiverType:dynamic Function([dynamic, dynamic, dart.core::StackTrace*])*] :async_op.call();
+  :is_sync = true;
+  return :async_future;
 }
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index a4f3270..452346f 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -36,8 +36,6 @@
 
 SnapshotKind Options::gen_snapshot_kind_ = kNone;
 bool Options::enable_vm_service_ = false;
-MallocGrowableArray<const char*> Options::enabled_experiments_ =
-    MallocGrowableArray<const char*>(4);
 
 #define OPTION_FIELD(variable) Options::variable##_
 
@@ -368,28 +366,6 @@
   return false;
 }
 
-bool Options::ProcessEnableExperimentOption(const char* arg,
-                                            CommandLineOptions* vm_options) {
-  const char* value =
-      OptionProcessor::ProcessOption(arg, "--enable_experiment=");
-  if (value == nullptr) {
-    value = OptionProcessor::ProcessOption(arg, "--enable-experiment=");
-  }
-  if (value == nullptr) {
-    return false;
-  }
-  vm_options->AddArgument(arg);
-  Utils::CStringUniquePtr tmp =
-      Utils::CreateCStringUniquePtr(Utils::StrDup(value));
-  char* save_ptr;  // Needed for strtok_r.
-  char* token = strtok_r(const_cast<char*>(tmp.get()), ",", &save_ptr);
-  while (token != NULL) {
-    enabled_experiments_.Add(Utils::StrDup(token));
-    token = strtok_r(NULL, ",", &save_ptr);
-  }
-  return true;
-}
-
 int Options::ParseArguments(int argc,
                             char** argv,
                             bool vm_run_app_snapshot,
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index ae21138..f900a3c 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -70,7 +70,6 @@
   V(ProcessEnvironmentOption)                                                  \
   V(ProcessEnableVmServiceOption)                                              \
   V(ProcessObserveOption)                                                      \
-  V(ProcessEnableExperimentOption)                                             \
   V(ProcessVMDebuggingOptions)
 
 // This enum must match the strings in kSnapshotKindNames in main_options.cc.
@@ -179,8 +178,6 @@
                                     int default_port,
                                     const char* default_ip);
 
-  static MallocGrowableArray<const char*> enabled_experiments_;
-
 #define OPTION_FRIEND(flag, variable) friend class OptionProcessor_##flag;
   STRING_OPTIONS_LIST(OPTION_FRIEND)
   BOOL_OPTIONS_LIST(OPTION_FRIEND)
diff --git a/runtime/lib/stacktrace.cc b/runtime/lib/stacktrace.cc
index 3eabaf4..eaa287c 100644
--- a/runtime/lib/stacktrace.cc
+++ b/runtime/lib/stacktrace.cc
@@ -63,6 +63,12 @@
   return StackTrace::New(code_array, pc_offset_array);
 }
 
+// Gets current stack trace for `thread`.
+// This functions itself handles the --causel-async-stacks case.
+// For --lazy-async-stacks see `CurrentSyncStackTraceLazy`.
+// For --no-causel-async-stacks see `CurrentSyncStackTrace`.
+// Extracts the causal async stack from the thread if any set, then prepends
+// the current sync. stack up until the current async function (if any).
 static StackTracePtr CurrentStackTrace(
     Thread* thread,
     bool for_async_function,
@@ -91,9 +97,13 @@
   // Determine the size of the stack trace.
   const intptr_t extra_frames = for_async_function ? 1 : 0;
   bool sync_async_end = false;
+  // Count frames until `async_function` and set whether the async function is
+  // running synchronously (i.e. hasn't yielded yet).
   const intptr_t synchronous_stack_trace_length = StackTraceUtils::CountFrames(
       thread, skip_frames, async_function, &sync_async_end);
 
+  ASSERT(synchronous_stack_trace_length > 0);
+
   const intptr_t capacity = synchronous_stack_trace_length +
                             extra_frames;  // For the asynchronous gap.
 
@@ -112,18 +122,21 @@
     write_cursor++;
   }
 
-  // Append the synchronous stack trace.
-  const intptr_t collected_frames_count = StackTraceUtils::CollectFrames(
-      thread, code_array, pc_offset_array, write_cursor,
-      synchronous_stack_trace_length, skip_frames);
+  // Prepend: synchronous stack trace + (cached) async stack trace.
 
-  write_cursor += collected_frames_count;
+  write_cursor +=
+      StackTraceUtils::CollectFrames(thread, code_array, pc_offset_array,
+                                     /*array_offset=*/write_cursor,
+                                     /*count=*/synchronous_stack_trace_length,
+                                     /*skip_frames=*/skip_frames);
 
   ASSERT(write_cursor == capacity);
 
   const StackTrace& result = StackTrace::Handle(
-      zone, StackTrace::New(code_array, pc_offset_array, async_stack_trace,
-                            sync_async_end));
+      zone,
+      StackTrace::New(code_array, pc_offset_array,
+                      /*async_link=*/async_stack_trace,
+                      /*skip_sync_start_in_parent_stack=*/sync_async_end));
 
   return result.raw();
 }
diff --git a/runtime/observatory/tests/service/get_allocation_samples_test.dart b/runtime/observatory/tests/service/get_allocation_samples_test.dart
index 44b4694..72c4e2b 100644
--- a/runtime/observatory/tests/service/get_allocation_samples_test.dart
+++ b/runtime/observatory/tests/service/get_allocation_samples_test.dart
@@ -72,7 +72,6 @@
       '[Unoptimized] test',
       '[Unoptimized] _Closure.call',
       '[Unoptimized] _ServiceTesteeRunner.run',
-      '[Unoptimized] _AsyncAwaitCompleter.start'
     ];
     for (var i = 0; i < expected.length; i++) {
       expect(node!.profileCode.code.name, equals(expected[i]));
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index f8d96f8..8c09f06 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -111,7 +111,7 @@
 get_object_rpc_test: SkipByDesign
 get_source_report_test: Skip, Timeout
 get_source_report_with_mixin_test: Skip, Timeout
-get_stack_limit_test: Skip, Timeout
+get_stack_limit_rpc_test: Skip, Timeout
 get_stack_rpc_test: Skip, Timeout
 implicit_getter_setter_test: SkipByDesign
 invoke_test: Skip, Timeout
diff --git a/runtime/observatory_2/tests/service_2/get_allocation_samples_test.dart b/runtime/observatory_2/tests/service_2/get_allocation_samples_test.dart
index 9c1252b..d39219d 100644
--- a/runtime/observatory_2/tests/service_2/get_allocation_samples_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_allocation_samples_test.dart
@@ -72,7 +72,6 @@
       '[Unoptimized] test',
       '[Unoptimized] _Closure.call',
       '[Unoptimized] _ServiceTesteeRunner.run',
-      '[Unoptimized] _AsyncAwaitCompleter.start'
     ];
     for (var i = 0; i < expected.length; i++) {
       expect(node.profileCode.code.name, equals(expected[i]));
diff --git a/runtime/tests/vm/dart/causal_stacks/utils.dart b/runtime/tests/vm/dart/causal_stacks/utils.dart
index 0b14b5c..6b3b6e6 100644
--- a/runtime/tests/vm/dart/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart/causal_stacks/utils.dart
@@ -770,156 +770,144 @@
   final noYieldsExpected = const <String>[
     r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
     r'^#1      noYields3 \(.*/utils.dart:54(:3)?\)$',
-    r'^#2      _AsyncAwaitCompleter.start ',
-    r'^#3      noYields3 \(.*/utils.dart:53(:23)?\)$',
-    r'^#4      noYields2 \(.*/utils.dart:50(:9)?\)$',
-    r'^#5      _AsyncAwaitCompleter.start ',
-    r'^#6      noYields2 \(.*/utils.dart:49(:23)?\)$',
-    r'^#7      noYields \(.*/utils.dart:46(:9)?\)$',
-    r'^#8      _AsyncAwaitCompleter.start ',
-    r'^#9      noYields \(.*/utils.dart:45(:22)?\)$',
+    r'^#2      noYields3 \(.*/utils.dart:53(:23)?\)$',
+    r'^#3      noYields2 \(.*/utils.dart:50(:9)?\)$',
+    r'^#4      noYields2 \(.*/utils.dart:49(:23)?\)$',
+    r'^#5      noYields \(.*/utils.dart:46(:9)?\)$',
+    r'^#6      noYields \(.*/utils.dart:45(:22)?\)$',
   ];
   await doTestAwait(
       noYields,
       noYieldsExpected +
           const <String>[
-            r'^#10     doTestAwait ',
-            r'^#11     _AsyncAwaitCompleter.start ',
-            r'^#12     doTestAwait ',
-            r'^#13     doTestsNoCausalNoLazy ',
-            r'^#14     _RootZone.runUnary ',
-            r'^#15     _FutureListener.handleValue ',
-            r'^#16     Future._propagateToListeners.handleValueCallback ',
-            r'^#17     Future._propagateToListeners ',
-            r'^#18     Future._completeWithValue ',
-            r'^#19     _AsyncAwaitCompleter.complete ',
-            r'^#20     _completeOnAsyncReturn ',
-            r'^#21     doTestAwaitCatchError ',
-            r'^#22     _RootZone.runUnary ',
-            r'^#23     _FutureListener.handleValue ',
-            r'^#24     Future._propagateToListeners.handleValueCallback ',
-            r'^#25     Future._propagateToListeners ',
-            r'^#26     Future._completeError ',
-            r'^#27     _AsyncAwaitCompleter.completeError ',
-            r'^#28     allYield ',
-            r'^#29     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#30     _RootZone.runBinary ',
-            r'^#31     _FutureListener.handleError ',
-            r'^#32     Future._propagateToListeners.handleError ',
-            r'^#33     Future._propagateToListeners ',
-            r'^#34     Future._completeError ',
-            r'^#35     _AsyncAwaitCompleter.completeError ',
-            r'^#36     allYield2 ',
-            r'^#37     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#38     _RootZone.runBinary ',
-            r'^#39     _FutureListener.handleError ',
-            r'^#40     Future._propagateToListeners.handleError ',
-            r'^#41     Future._propagateToListeners ',
-            r'^#42     Future._completeError ',
-            r'^#43     _AsyncAwaitCompleter.completeError ',
-            r'^#44     allYield3 ',
-            r'^#45     _RootZone.runUnary ',
-            r'^#46     _FutureListener.handleValue ',
-            r'^#47     Future._propagateToListeners.handleValueCallback ',
-            r'^#48     Future._propagateToListeners ',
-            // TODO(dart-vm): Figure out why this is inconsistent:
-            r'^#49     Future.(_addListener|_prependListeners).<anonymous closure> ',
-            r'^#50     _microtaskLoop ',
-            r'^#51     _startMicrotaskLoop ',
-            r'^#52     _runPendingImmediateCallback ',
-            r'^#53     _RawReceivePortImpl._handleMessage ',
+            r'^#7      doTestAwait ',
+            r'^#8      doTestAwait ',
+            r'^#9      doTestsNoCausalNoLazy ',
+            r'^#10     _RootZone.runUnary ',
+            r'^#11     _FutureListener.handleValue ',
+            r'^#12     Future._propagateToListeners.handleValueCallback ',
+            r'^#13     Future._propagateToListeners ',
+            r'^#14     Future._completeWithValue ',
+            r'^#15     _completeOnAsyncReturn ',
+            r'^#16     doTestAwaitCatchError ',
+            r'^#17     _RootZone.runUnary ',
+            r'^#18     _FutureListener.handleValue ',
+            r'^#19     Future._propagateToListeners.handleValueCallback ',
+            r'^#20     Future._propagateToListeners ',
+            r'^#21     Future._completeError ',
+            r'^#22     _completeOnAsyncError ',
+            r'^#23     allYield ',
+            r'^#24     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#25     _RootZone.runBinary ',
+            r'^#26     _FutureListener.handleError ',
+            r'^#27     Future._propagateToListeners.handleError ',
+            r'^#28     Future._propagateToListeners ',
+            r'^#29     Future._completeError ',
+            r'^#30     _completeOnAsyncError ',
+            r'^#31     allYield2 ',
+            r'^#32     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#33     _RootZone.runBinary ',
+            r'^#34     _FutureListener.handleError ',
+            r'^#35     Future._propagateToListeners.handleError ',
+            r'^#36     Future._propagateToListeners ',
+            r'^#37     Future._completeError ',
+            r'^#38     _completeOnAsyncError ',
+            r'^#39     allYield3 ',
+            r'^#40     _RootZone.runUnary ',
+            r'^#41     _FutureListener.handleValue ',
+            r'^#42     Future._propagateToListeners.handleValueCallback ',
+            r'^#43     Future._propagateToListeners ',
+            r'^#44     Future._addListener.<anonymous closure> ',
+            r'^#45     _microtaskLoop ',
+            r'^#46     _startMicrotaskLoop ',
+            r'^#47     _runPendingImmediateCallback ',
+            r'^#48     _RawReceivePortImpl._handleMessage ',
           ],
       debugInfoFilename);
   await doTestAwaitThen(
       noYields,
       noYieldsExpected +
           const <String>[
-            r'^#10     doTestAwaitThen ',
-            r'^#11     _AsyncAwaitCompleter.start ',
-            r'^#12     doTestAwaitThen ',
-            r'^#13     doTestsNoCausalNoLazy ',
-            r'^#14     _RootZone.runUnary ',
-            r'^#15     _FutureListener.handleValue ',
-            r'^#16     Future._propagateToListeners.handleValueCallback ',
-            r'^#17     Future._propagateToListeners ',
-            r'^#18     Future._completeWithValue ',
-            r'^#19     _AsyncAwaitCompleter.complete ',
-            r'^#20     _completeOnAsyncReturn ',
-            r'^#21     doTestAwait ',
-            r'^#22     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#23     _RootZone.runBinary ',
-            r'^#24     _FutureListener.handleError ',
-            r'^#25     Future._propagateToListeners.handleError ',
-            r'^#26     Future._propagateToListeners ',
-            r'^#27     Future._completeError ',
-            r'^#28     _AsyncAwaitCompleter.completeError ',
-            r'^#29     noYields ',
-            r'^#30     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#31     _RootZone.runBinary ',
-            r'^#32     _FutureListener.handleError ',
-            r'^#33     Future._propagateToListeners.handleError ',
-            r'^#34     Future._propagateToListeners ',
-            r'^#35     Future._completeError ',
-            r'^#36     _AsyncAwaitCompleter.completeError ',
-            r'^#37     noYields2 ',
-            r'^#38     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#39     _RootZone.runBinary ',
-            r'^#40     _FutureListener.handleError ',
-            r'^#41     Future._propagateToListeners.handleError ',
-            r'^#42     Future._propagateToListeners ',
-            r'^#43     Future._completeError ',
-            // TODO(dart-vm): Figure out why this is inconsistent:
-            r'^#44     Future.(_asyncCompleteError|_chainForeignFuture).<anonymous closure> ',
-            r'^#45     _microtaskLoop ',
-            r'^#46     _startMicrotaskLoop ',
-            r'^#47     _runPendingImmediateCallback ',
-            r'^#48     _RawReceivePortImpl._handleMessage ',
+            r'^#7      doTestAwaitThen ',
+            r'^#8      doTestAwaitThen ',
+            r'^#9      doTestsNoCausalNoLazy ',
+            r'^#10     _RootZone.runUnary ',
+            r'^#11     _FutureListener.handleValue ',
+            r'^#12     Future._propagateToListeners.handleValueCallback ',
+            r'^#13     Future._propagateToListeners ',
+            r'^#14     Future._completeWithValue ',
+            r'^#15     _completeOnAsyncReturn ',
+            r'^#16     doTestAwait ',
+            r'^#17     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#18     _RootZone.runBinary ',
+            r'^#19     _FutureListener.handleError ',
+            r'^#20     Future._propagateToListeners.handleError ',
+            r'^#21     Future._propagateToListeners ',
+            r'^#22     Future._completeError ',
+            r'^#23     _completeOnAsyncError ',
+            r'^#24     noYields ',
+            r'^#25     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#26     _RootZone.runBinary ',
+            r'^#27     _FutureListener.handleError ',
+            r'^#28     Future._propagateToListeners.handleError ',
+            r'^#29     Future._propagateToListeners ',
+            r'^#30     Future._completeError ',
+            r'^#31     _completeOnAsyncError ',
+            r'^#32     noYields2 ',
+            r'^#33     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#34     _RootZone.runBinary ',
+            r'^#35     _FutureListener.handleError ',
+            r'^#36     Future._propagateToListeners.handleError ',
+            r'^#37     Future._propagateToListeners ',
+            r'^#38     Future._completeError ',
+            r'^#39     Future._asyncCompleteError.<anonymous closure> ',
+            r'^#40     _microtaskLoop ',
+            r'^#41     _startMicrotaskLoop ',
+            r'^#42     _runPendingImmediateCallback ',
+            r'^#43     _RawReceivePortImpl._handleMessage ',
           ],
       debugInfoFilename);
   await doTestAwaitCatchError(
       noYields,
       noYieldsExpected +
           const <String>[
-            r'^#10     doTestAwaitCatchError ',
-            r'^#11     _AsyncAwaitCompleter.start ',
-            r'^#12     doTestAwaitCatchError ',
-            r'^#13     doTestsNoCausalNoLazy ',
-            r'^#14     _RootZone.runUnary ',
-            r'^#15     _FutureListener.handleValue ',
-            r'^#16     Future._propagateToListeners.handleValueCallback ',
-            r'^#17     Future._propagateToListeners ',
-            r'^#18     Future._completeWithValue ',
-            r'^#19     _AsyncAwaitCompleter.complete ',
-            r'^#20     _completeOnAsyncReturn ',
-            r'^#21     doTestAwaitThen ',
-            r'^#22     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#23     _RootZone.runBinary ',
-            r'^#24     _FutureListener.handleError ',
-            r'^#25     Future._propagateToListeners.handleError ',
-            r'^#26     Future._propagateToListeners ',
-            r'^#27     Future._completeError ',
-            r'^#28     _AsyncAwaitCompleter.completeError ',
-            r'^#29     noYields ',
-            r'^#30     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#31     _RootZone.runBinary ',
-            r'^#32     _FutureListener.handleError ',
-            r'^#33     Future._propagateToListeners.handleError ',
-            r'^#34     Future._propagateToListeners ',
-            r'^#35     Future._completeError ',
-            r'^#36     _AsyncAwaitCompleter.completeError ',
-            r'^#37     noYields2 ',
-            r'^#38     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#39     _RootZone.runBinary ',
-            r'^#40     _FutureListener.handleError ',
-            r'^#41     Future._propagateToListeners.handleError ',
-            r'^#42     Future._propagateToListeners ',
-            r'^#43     Future._completeError ',
-            // TODO(dart-vm): Figure out why this is inconsistent:
-            r'^#44     Future.(_asyncCompleteError|_chainForeignFuture).<anonymous closure> ',
-            r'^#45     _microtaskLoop ',
-            r'^#46     _startMicrotaskLoop ',
-            r'^#47     _runPendingImmediateCallback ',
-            r'^#48     _RawReceivePortImpl._handleMessage ',
+            r'^#7      doTestAwaitCatchError ',
+            r'^#8      doTestAwaitCatchError ',
+            r'^#9      doTestsNoCausalNoLazy ',
+            r'^#10     _RootZone.runUnary ',
+            r'^#11     _FutureListener.handleValue ',
+            r'^#12     Future._propagateToListeners.handleValueCallback ',
+            r'^#13     Future._propagateToListeners ',
+            r'^#14     Future._completeWithValue ',
+            r'^#15     _completeOnAsyncReturn ',
+            r'^#16     doTestAwaitThen ',
+            r'^#17     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#18     _RootZone.runBinary ',
+            r'^#19     _FutureListener.handleError ',
+            r'^#20     Future._propagateToListeners.handleError ',
+            r'^#21     Future._propagateToListeners ',
+            r'^#22     Future._completeError ',
+            r'^#23     _completeOnAsyncError ',
+            r'^#24     noYields ',
+            r'^#25     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#26     _RootZone.runBinary ',
+            r'^#27     _FutureListener.handleError ',
+            r'^#28     Future._propagateToListeners.handleError ',
+            r'^#29     Future._propagateToListeners ',
+            r'^#30     Future._completeError ',
+            r'^#31     _completeOnAsyncError ',
+            r'^#32     noYields2 ',
+            r'^#33     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#34     _RootZone.runBinary ',
+            r'^#35     _FutureListener.handleError ',
+            r'^#36     Future._propagateToListeners.handleError ',
+            r'^#37     Future._propagateToListeners ',
+            r'^#38     Future._completeError ',
+            r'^#39     Future._asyncCompleteError.<anonymous closure> ',
+            r'^#40     _microtaskLoop ',
+            r'^#41     _startMicrotaskLoop ',
+            r'^#42     _runPendingImmediateCallback ',
+            r'^#43     _RawReceivePortImpl._handleMessage ',
           ],
       debugInfoFilename);
 
diff --git a/runtime/tests/vm/dart_2/causal_stacks/utils.dart b/runtime/tests/vm/dart_2/causal_stacks/utils.dart
index 94db964..743986d 100644
--- a/runtime/tests/vm/dart_2/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart_2/causal_stacks/utils.dart
@@ -770,156 +770,144 @@
   final noYieldsExpected = const <String>[
     r'^#0      throwSync \(.*/utils.dart:16(:3)?\)$',
     r'^#1      noYields3 \(.*/utils.dart:54(:3)?\)$',
-    r'^#2      _AsyncAwaitCompleter.start ',
-    r'^#3      noYields3 \(.*/utils.dart:53(:23)?\)$',
-    r'^#4      noYields2 \(.*/utils.dart:50(:9)?\)$',
-    r'^#5      _AsyncAwaitCompleter.start ',
-    r'^#6      noYields2 \(.*/utils.dart:49(:23)?\)$',
-    r'^#7      noYields \(.*/utils.dart:46(:9)?\)$',
-    r'^#8      _AsyncAwaitCompleter.start ',
-    r'^#9      noYields \(.*/utils.dart:45(:22)?\)$',
+    r'^#2      noYields3 \(.*/utils.dart:53(:23)?\)$',
+    r'^#3      noYields2 \(.*/utils.dart:50(:9)?\)$',
+    r'^#4      noYields2 \(.*/utils.dart:49(:23)?\)$',
+    r'^#5      noYields \(.*/utils.dart:46(:9)?\)$',
+    r'^#6      noYields \(.*/utils.dart:45(:22)?\)$',
   ];
   await doTestAwait(
       noYields,
       noYieldsExpected +
           const <String>[
-            r'^#10     doTestAwait ',
-            r'^#11     _AsyncAwaitCompleter.start ',
-            r'^#12     doTestAwait ',
-            r'^#13     doTestsNoCausalNoLazy ',
-            r'^#14     _RootZone.runUnary ',
-            r'^#15     _FutureListener.handleValue ',
-            r'^#16     Future._propagateToListeners.handleValueCallback ',
-            r'^#17     Future._propagateToListeners ',
-            r'^#18     Future._completeWithValue ',
-            r'^#19     _AsyncAwaitCompleter.complete ',
-            r'^#20     _completeOnAsyncReturn ',
-            r'^#21     doTestAwaitCatchError ',
-            r'^#22     _RootZone.runUnary ',
-            r'^#23     _FutureListener.handleValue ',
-            r'^#24     Future._propagateToListeners.handleValueCallback ',
-            r'^#25     Future._propagateToListeners ',
-            r'^#26     Future._completeError ',
-            r'^#27     _AsyncAwaitCompleter.completeError ',
-            r'^#28     allYield ',
-            r'^#29     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#30     _RootZone.runBinary ',
-            r'^#31     _FutureListener.handleError ',
-            r'^#32     Future._propagateToListeners.handleError ',
-            r'^#33     Future._propagateToListeners ',
-            r'^#34     Future._completeError ',
-            r'^#35     _AsyncAwaitCompleter.completeError ',
-            r'^#36     allYield2 ',
-            r'^#37     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#38     _RootZone.runBinary ',
-            r'^#39     _FutureListener.handleError ',
-            r'^#40     Future._propagateToListeners.handleError ',
-            r'^#41     Future._propagateToListeners ',
-            r'^#42     Future._completeError ',
-            r'^#43     _AsyncAwaitCompleter.completeError ',
-            r'^#44     allYield3 ',
-            r'^#45     _RootZone.runUnary ',
-            r'^#46     _FutureListener.handleValue ',
-            r'^#47     Future._propagateToListeners.handleValueCallback ',
-            r'^#48     Future._propagateToListeners ',
-            // TODO(dart-vm): Figure out why this is inconsistent:
-            r'^#49     Future.(_addListener|_prependListeners).<anonymous closure> ',
-            r'^#50     _microtaskLoop ',
-            r'^#51     _startMicrotaskLoop ',
-            r'^#52     _runPendingImmediateCallback ',
-            r'^#53     _RawReceivePortImpl._handleMessage ',
+            r'^#7      doTestAwait ',
+            r'^#8      doTestAwait ',
+            r'^#9      doTestsNoCausalNoLazy ',
+            r'^#10     _RootZone.runUnary ',
+            r'^#11     _FutureListener.handleValue ',
+            r'^#12     Future._propagateToListeners.handleValueCallback ',
+            r'^#13     Future._propagateToListeners ',
+            r'^#14     Future._completeWithValue ',
+            r'^#15     _completeOnAsyncReturn ',
+            r'^#16     doTestAwaitCatchError ',
+            r'^#17     _RootZone.runUnary ',
+            r'^#18     _FutureListener.handleValue ',
+            r'^#19     Future._propagateToListeners.handleValueCallback ',
+            r'^#20     Future._propagateToListeners ',
+            r'^#21     Future._completeError ',
+            r'^#22     _completeOnAsyncError ',
+            r'^#23     allYield ',
+            r'^#24     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#25     _RootZone.runBinary ',
+            r'^#26     _FutureListener.handleError ',
+            r'^#27     Future._propagateToListeners.handleError ',
+            r'^#28     Future._propagateToListeners ',
+            r'^#29     Future._completeError ',
+            r'^#30     _completeOnAsyncError ',
+            r'^#31     allYield2 ',
+            r'^#32     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#33     _RootZone.runBinary ',
+            r'^#34     _FutureListener.handleError ',
+            r'^#35     Future._propagateToListeners.handleError ',
+            r'^#36     Future._propagateToListeners ',
+            r'^#37     Future._completeError ',
+            r'^#38     _completeOnAsyncError ',
+            r'^#39     allYield3 ',
+            r'^#40     _RootZone.runUnary ',
+            r'^#41     _FutureListener.handleValue ',
+            r'^#42     Future._propagateToListeners.handleValueCallback ',
+            r'^#43     Future._propagateToListeners ',
+            r'^#44     Future._addListener.<anonymous closure> ',
+            r'^#45     _microtaskLoop ',
+            r'^#46     _startMicrotaskLoop ',
+            r'^#47     _runPendingImmediateCallback ',
+            r'^#48     _RawReceivePortImpl._handleMessage ',
           ],
       debugInfoFilename);
   await doTestAwaitThen(
       noYields,
       noYieldsExpected +
           const <String>[
-            r'^#10     doTestAwaitThen ',
-            r'^#11     _AsyncAwaitCompleter.start ',
-            r'^#12     doTestAwaitThen ',
-            r'^#13     doTestsNoCausalNoLazy ',
-            r'^#14     _RootZone.runUnary ',
-            r'^#15     _FutureListener.handleValue ',
-            r'^#16     Future._propagateToListeners.handleValueCallback ',
-            r'^#17     Future._propagateToListeners ',
-            r'^#18     Future._completeWithValue ',
-            r'^#19     _AsyncAwaitCompleter.complete ',
-            r'^#20     _completeOnAsyncReturn ',
-            r'^#21     doTestAwait ',
-            r'^#22     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#23     _RootZone.runBinary ',
-            r'^#24     _FutureListener.handleError ',
-            r'^#25     Future._propagateToListeners.handleError ',
-            r'^#26     Future._propagateToListeners ',
-            r'^#27     Future._completeError ',
-            r'^#28     _AsyncAwaitCompleter.completeError ',
-            r'^#29     noYields ',
-            r'^#30     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#31     _RootZone.runBinary ',
-            r'^#32     _FutureListener.handleError ',
-            r'^#33     Future._propagateToListeners.handleError ',
-            r'^#34     Future._propagateToListeners ',
-            r'^#35     Future._completeError ',
-            r'^#36     _AsyncAwaitCompleter.completeError ',
-            r'^#37     noYields2 ',
-            r'^#38     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#39     _RootZone.runBinary ',
-            r'^#40     _FutureListener.handleError ',
-            r'^#41     Future._propagateToListeners.handleError ',
-            r'^#42     Future._propagateToListeners ',
-            r'^#43     Future._completeError ',
-            // TODO(dart-vm): Figure out why this is inconsistent:
-            r'^#44     Future.(_asyncCompleteError|_chainForeignFuture).<anonymous closure> ',
-            r'^#45     _microtaskLoop ',
-            r'^#46     _startMicrotaskLoop ',
-            r'^#47     _runPendingImmediateCallback ',
-            r'^#48     _RawReceivePortImpl._handleMessage ',
+            r'^#7      doTestAwaitThen ',
+            r'^#8      doTestAwaitThen ',
+            r'^#9      doTestsNoCausalNoLazy ',
+            r'^#10     _RootZone.runUnary ',
+            r'^#11     _FutureListener.handleValue ',
+            r'^#12     Future._propagateToListeners.handleValueCallback ',
+            r'^#13     Future._propagateToListeners ',
+            r'^#14     Future._completeWithValue ',
+            r'^#15     _completeOnAsyncReturn ',
+            r'^#16     doTestAwait ',
+            r'^#17     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#18     _RootZone.runBinary ',
+            r'^#19     _FutureListener.handleError ',
+            r'^#20     Future._propagateToListeners.handleError ',
+            r'^#21     Future._propagateToListeners ',
+            r'^#22     Future._completeError ',
+            r'^#23     _completeOnAsyncError ',
+            r'^#24     noYields ',
+            r'^#25     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#26     _RootZone.runBinary ',
+            r'^#27     _FutureListener.handleError ',
+            r'^#28     Future._propagateToListeners.handleError ',
+            r'^#29     Future._propagateToListeners ',
+            r'^#30     Future._completeError ',
+            r'^#31     _completeOnAsyncError ',
+            r'^#32     noYields2 ',
+            r'^#33     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#34     _RootZone.runBinary ',
+            r'^#35     _FutureListener.handleError ',
+            r'^#36     Future._propagateToListeners.handleError ',
+            r'^#37     Future._propagateToListeners ',
+            r'^#38     Future._completeError ',
+            r'^#39     Future._asyncCompleteError.<anonymous closure> ',
+            r'^#40     _microtaskLoop ',
+            r'^#41     _startMicrotaskLoop ',
+            r'^#42     _runPendingImmediateCallback ',
+            r'^#43     _RawReceivePortImpl._handleMessage ',
           ],
       debugInfoFilename);
   await doTestAwaitCatchError(
       noYields,
       noYieldsExpected +
           const <String>[
-            r'^#10     doTestAwaitCatchError ',
-            r'^#11     _AsyncAwaitCompleter.start ',
-            r'^#12     doTestAwaitCatchError ',
-            r'^#13     doTestsNoCausalNoLazy ',
-            r'^#14     _RootZone.runUnary ',
-            r'^#15     _FutureListener.handleValue ',
-            r'^#16     Future._propagateToListeners.handleValueCallback ',
-            r'^#17     Future._propagateToListeners ',
-            r'^#18     Future._completeWithValue ',
-            r'^#19     _AsyncAwaitCompleter.complete ',
-            r'^#20     _completeOnAsyncReturn ',
-            r'^#21     doTestAwaitThen ',
-            r'^#22     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#23     _RootZone.runBinary ',
-            r'^#24     _FutureListener.handleError ',
-            r'^#25     Future._propagateToListeners.handleError ',
-            r'^#26     Future._propagateToListeners ',
-            r'^#27     Future._completeError ',
-            r'^#28     _AsyncAwaitCompleter.completeError ',
-            r'^#29     noYields ',
-            r'^#30     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#31     _RootZone.runBinary ',
-            r'^#32     _FutureListener.handleError ',
-            r'^#33     Future._propagateToListeners.handleError ',
-            r'^#34     Future._propagateToListeners ',
-            r'^#35     Future._completeError ',
-            r'^#36     _AsyncAwaitCompleter.completeError ',
-            r'^#37     noYields2 ',
-            r'^#38     _asyncErrorWrapperHelper.errorCallback ',
-            r'^#39     _RootZone.runBinary ',
-            r'^#40     _FutureListener.handleError ',
-            r'^#41     Future._propagateToListeners.handleError ',
-            r'^#42     Future._propagateToListeners ',
-            r'^#43     Future._completeError ',
-            // TODO(dart-vm): Figure out why this is inconsistent:
-            r'^#44     Future.(_asyncCompleteError|_chainForeignFuture).<anonymous closure> ',
-            r'^#45     _microtaskLoop ',
-            r'^#46     _startMicrotaskLoop ',
-            r'^#47     _runPendingImmediateCallback ',
-            r'^#48     _RawReceivePortImpl._handleMessage ',
+            r'^#7      doTestAwaitCatchError ',
+            r'^#8      doTestAwaitCatchError ',
+            r'^#9      doTestsNoCausalNoLazy ',
+            r'^#10     _RootZone.runUnary ',
+            r'^#11     _FutureListener.handleValue ',
+            r'^#12     Future._propagateToListeners.handleValueCallback ',
+            r'^#13     Future._propagateToListeners ',
+            r'^#14     Future._completeWithValue ',
+            r'^#15     _completeOnAsyncReturn ',
+            r'^#16     doTestAwaitThen ',
+            r'^#17     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#18     _RootZone.runBinary ',
+            r'^#19     _FutureListener.handleError ',
+            r'^#20     Future._propagateToListeners.handleError ',
+            r'^#21     Future._propagateToListeners ',
+            r'^#22     Future._completeError ',
+            r'^#23     _completeOnAsyncError ',
+            r'^#24     noYields ',
+            r'^#25     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#26     _RootZone.runBinary ',
+            r'^#27     _FutureListener.handleError ',
+            r'^#28     Future._propagateToListeners.handleError ',
+            r'^#29     Future._propagateToListeners ',
+            r'^#30     Future._completeError ',
+            r'^#31     _completeOnAsyncError ',
+            r'^#32     noYields2 ',
+            r'^#33     _asyncErrorWrapperHelper.errorCallback ',
+            r'^#34     _RootZone.runBinary ',
+            r'^#35     _FutureListener.handleError ',
+            r'^#36     Future._propagateToListeners.handleError ',
+            r'^#37     Future._propagateToListeners ',
+            r'^#38     Future._completeError ',
+            r'^#39     Future._asyncCompleteError.<anonymous closure> ',
+            r'^#40     _microtaskLoop ',
+            r'^#41     _startMicrotaskLoop ',
+            r'^#42     _runPendingImmediateCallback ',
+            r'^#43     _RawReceivePortImpl._handleMessage ',
           ],
       debugInfoFilename);
 
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 2cf2c29..aeed3f4 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -627,17 +627,17 @@
     first_body_token_position_ = helper_.reader_.min_position();
   }
 
-  // Ensure that :await_jump_var, :await_ctx_var, :async_op,
-  // :async_completer and :async_stack_trace are captured.
+  // Ensure that :await_jump_var, :await_ctx_var, :async_op, :is_sync,
+  // :async_future and :async_stack_trace are captured.
   if (function_node_helper.async_marker_ == FunctionNodeHelper::kSyncYielding) {
     {
-      LocalVariable* temp = NULL;
+      LocalVariable* temp = nullptr;
       LookupCapturedVariableByName(
           (depth_.function_ == 0) ? &result_->yield_jump_variable : &temp,
           Symbols::AwaitJumpVar());
     }
     {
-      LocalVariable* temp = NULL;
+      LocalVariable* temp = nullptr;
       LookupCapturedVariableByName(
           (depth_.function_ == 0) ? &result_->yield_context_variable : &temp,
           Symbols::AwaitContextVar());
@@ -645,28 +645,34 @@
     {
       LocalVariable* temp =
           scope_->LookupVariable(Symbols::AsyncOperation(), true);
-      if (temp != NULL) {
+      if (temp != nullptr) {
         scope_->CaptureVariable(temp);
       }
     }
     {
       LocalVariable* temp =
-          scope_->LookupVariable(Symbols::AsyncCompleter(), true);
-      if (temp != NULL) {
+          scope_->LookupVariable(Symbols::AsyncFuture(), true);
+      if (temp != nullptr) {
+        scope_->CaptureVariable(temp);
+      }
+    }
+    {
+      LocalVariable* temp = scope_->LookupVariable(Symbols::is_sync(), true);
+      if (temp != nullptr) {
         scope_->CaptureVariable(temp);
       }
     }
     {
       LocalVariable* temp =
           scope_->LookupVariable(Symbols::ControllerStream(), true);
-      if (temp != NULL) {
+      if (temp != nullptr) {
         scope_->CaptureVariable(temp);
       }
     }
     if (FLAG_causal_async_stacks) {
       LocalVariable* temp =
           scope_->LookupVariable(Symbols::AsyncStackTraceVar(), true);
-      if (temp != NULL) {
+      if (temp != nullptr) {
         scope_->CaptureVariable(temp);
       }
     }
@@ -1354,7 +1360,7 @@
   // This way we can allocate them in the outermost context at fixed indices,
   // allowing support for --lazy-async-stacks implementation to find awaiters.
   if (name.Equals(Symbols::AwaitJumpVar()) ||
-      name.Equals(Symbols::AsyncCompleter()) ||
+      name.Equals(Symbols::AsyncFuture()) || name.Equals(Symbols::is_sync()) ||
       name.Equals(Symbols::Controller())) {
     scope_->parent()->AddVariable(variable);
   } else {
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index dfd6e56..5a146e0 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1969,10 +1969,10 @@
 #if defined(DART_PRECOMPILED_RUNTIME)
   // Causal async stacks are not supported in the AOT runtime.
   ASSERT(!FLAG_async_debugger);
-  return NULL;
+  return nullptr;
 #else
   if (!FLAG_async_debugger) {
-    return NULL;
+    return nullptr;
   }
 
   Thread* thread = Thread::Current();
@@ -1992,131 +1992,111 @@
   Closure& async_activation = Closure::Handle(zone);
   Object& next_async_activation = Object::Handle(zone);
   Array& deopt_frame = Array::Handle(zone);
+  // Note: 'class' since Debugger declares a method by the same name.
   class StackTrace& async_stack_trace = StackTrace::Handle(zone);
   bool stack_has_async_function = false;
+  Closure& closure = Closure::Handle();
 
   CallerClosureFinder caller_closure_finder(zone);
 
-  // Number of frames we are trying to skip that form "sync async" entry.
-  int skip_sync_async_frames_count = -1;
-
-  String& function_name = String::Handle(zone);
-  for (StackFrame* frame = iterator.NextFrame(); frame != NULL;
+  for (StackFrame* frame = iterator.NextFrame(); frame != nullptr;
        frame = iterator.NextFrame()) {
     ASSERT(frame->IsValid());
     if (FLAG_trace_debugger_stacktrace) {
       OS::PrintErr("CollectAwaiterReturnStackTrace: visiting frame:\n\t%s\n",
                    frame->ToCString());
     }
-    if (frame->IsDartFrame()) {
-      code = frame->LookupDartCode();
-      if (code.is_optimized()) {
-        if (code.is_force_optimized()) {
-          if (FLAG_trace_debugger_stacktrace) {
-            function = code.function();
-            ASSERT(!function.IsNull());
-            OS::PrintErr(
-                "CollectAwaiterReturnStackTrace: "
-                "skipping force-optimized function: %s\n",
-                function.ToFullyQualifiedCString());
-          }
-          // Skip frame of force-optimized (and non-debuggable) function.
-          continue;
-        }
-        deopt_frame = DeoptimizeToArray(thread, frame, code);
-        bool found_async_awaiter = false;
-        bool abort_attempt_to_navigate_through_sync_async = false;
-        for (InlinedFunctionsIterator it(code, frame->pc()); !it.Done();
-             it.Advance()) {
-          inlined_code = it.code();
-          function = it.function();
 
-          if (skip_sync_async_frames_count > 0) {
-            function_name ^= function.QualifiedScrubbedName();
-            if (!StackTraceUtils::CheckAndSkipAsync(
-                    &skip_sync_async_frames_count, function_name)) {
-              // Unexpected function in sync async call
-              skip_sync_async_frames_count = -1;
-              abort_attempt_to_navigate_through_sync_async = true;
-              break;
-            }
-          }
+    if (!frame->IsDartFrame()) {
+      continue;
+    }
 
-          if (FLAG_trace_debugger_stacktrace) {
-            ASSERT(!function.IsNull());
-            OS::PrintErr(
-                "CollectAwaiterReturnStackTrace: "
-                "visiting inlined function: %s\n ",
-                function.ToFullyQualifiedCString());
-          }
-          intptr_t deopt_frame_offset = it.GetDeoptFpOffset();
-          if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
-            ActivationFrame* activation = CollectDartFrame(
-                isolate, it.pc(), frame, inlined_code, deopt_frame,
-                deopt_frame_offset, ActivationFrame::kAsyncActivation);
-            ASSERT(activation != NULL);
-            stack_trace->AddActivation(activation);
-            stack_has_async_function = true;
-            // Grab the awaiter.
-            async_activation ^=
-                activation->GetAsyncAwaiter(&caller_closure_finder);
-            found_async_awaiter = true;
-            // async function might have been called synchronously, in which
-            // case we need to keep going down the stack.
-            // To determine how we are called we peek few more frames further
-            // expecting to see Closure_call followed by
-            // AsyncAwaitCompleter_start.
-            // If we are able to see those functions we continue going down
-            // thestack, if we are not, we break out of the loop as we are
-            // not interested in exploring rest of the stack - there is only
-            // dart-internal code left.
-            skip_sync_async_frames_count = 2;
-          } else {
-            stack_trace->AddActivation(
-                CollectDartFrame(isolate, it.pc(), frame, inlined_code,
-                                 deopt_frame, deopt_frame_offset));
-          }
-        }
-        // Break out of outer loop.
-        if (found_async_awaiter ||
-            abort_attempt_to_navigate_through_sync_async) {
+    code = frame->LookupDartCode();
+
+    // Simple frame. Just add the one.
+    if (!code.is_optimized()) {
+      function = code.function();
+      if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
+        ActivationFrame* activation = CollectDartFrame(
+            isolate, frame->pc(), frame, code, Object::null_array(), 0,
+            ActivationFrame::kAsyncActivation);
+        ASSERT(activation != nullptr);
+        stack_trace->AddActivation(activation);
+        stack_has_async_function = true;
+        // Grab the awaiter.
+        async_activation ^= activation->GetAsyncAwaiter(&caller_closure_finder);
+        async_stack_trace ^= activation->GetCausalStack();
+        // Bail if we've reach the end of sync execution stack.
+        ObjectPtr* last_caller_obj =
+            reinterpret_cast<ObjectPtr*>(frame->GetCallerSp());
+        closure =
+            StackTraceUtils::FindClosureInFrame(last_caller_obj, function);
+        if (caller_closure_finder.IsRunningAsync(closure)) {
           break;
         }
       } else {
-        function = code.function();
-
-        if (skip_sync_async_frames_count > 0) {
-          function_name ^= function.QualifiedScrubbedName();
-          if (!StackTraceUtils::CheckAndSkipAsync(&skip_sync_async_frames_count,
-                                                  function_name)) {
-            // Unexpected function in synchronous call of async function.
-            break;
-          }
-        }
-
-        if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
-          ActivationFrame* activation = CollectDartFrame(
-              isolate, frame->pc(), frame, code, Object::null_array(), 0,
-              ActivationFrame::kAsyncActivation);
-          ASSERT(activation != NULL);
-          stack_trace->AddActivation(activation);
-          stack_has_async_function = true;
-          // Grab the awaiter.
-          async_activation ^=
-              activation->GetAsyncAwaiter(&caller_closure_finder);
-          async_stack_trace ^= activation->GetCausalStack();
-          // see comment regarding skipping frames of async functions called
-          // synchronously above.
-          skip_sync_async_frames_count = 2;
-        } else {
-          stack_trace->AddActivation(CollectDartFrame(
-              isolate, frame->pc(), frame, code, Object::null_array(), 0));
-        }
+        stack_trace->AddActivation(CollectDartFrame(
+            isolate, frame->pc(), frame, code, Object::null_array(), 0));
       }
+
+      continue;
+    }
+
+    if (code.is_force_optimized()) {
+      if (FLAG_trace_debugger_stacktrace) {
+        function = code.function();
+        ASSERT(!function.IsNull());
+        OS::PrintErr(
+            "CollectAwaiterReturnStackTrace: "
+            "skipping force-optimized function: %s\n",
+            function.ToFullyQualifiedCString());
+      }
+      // Skip frame of force-optimized (and non-debuggable) function.
+      continue;
+    }
+
+    deopt_frame = DeoptimizeToArray(thread, frame, code);
+    bool found_async_awaiter = false;
+    bool abort_attempt_to_navigate_through_sync_async = false;
+    for (InlinedFunctionsIterator it(code, frame->pc()); !it.Done();
+         it.Advance()) {
+      inlined_code = it.code();
+      function = it.function();
+
+      if (FLAG_trace_debugger_stacktrace) {
+        ASSERT(!function.IsNull());
+        OS::PrintErr(
+            "CollectAwaiterReturnStackTrace: "
+            "visiting inlined function: %s\n ",
+            function.ToFullyQualifiedCString());
+      }
+
+      intptr_t deopt_frame_offset = it.GetDeoptFpOffset();
+      if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
+        ActivationFrame* activation = CollectDartFrame(
+            isolate, it.pc(), frame, inlined_code, deopt_frame,
+            deopt_frame_offset, ActivationFrame::kAsyncActivation);
+        ASSERT(activation != NULL);
+        stack_trace->AddActivation(activation);
+        stack_has_async_function = true;
+        // Grab the awaiter.
+        async_activation ^= activation->GetAsyncAwaiter(&caller_closure_finder);
+        async_stack_trace ^= activation->GetCausalStack();
+        found_async_awaiter = true;
+      } else {
+        stack_trace->AddActivation(CollectDartFrame(isolate, it.pc(), frame,
+                                                    inlined_code, deopt_frame,
+                                                    deopt_frame_offset));
+      }
+    }
+
+    // Break out of outer loop.
+    if (found_async_awaiter || abort_attempt_to_navigate_through_sync_async) {
+      break;
     }
   }
 
-  // If the stack doesn't have any async functions on it, return NULL.
+  // If the stack doesn't have any async functions on it, return nullptr.
   if (!stack_has_async_function) {
     return nullptr;
   }
@@ -2141,12 +2121,14 @@
           "closures:\n\t%s\n",
           activation->function().ToFullyQualifiedCString());
     }
+
     next_async_activation = activation->GetAsyncAwaiter(&caller_closure_finder);
     if (next_async_activation.IsNull()) {
       // No more awaiters. Extract the causal stack trace (if it exists).
       async_stack_trace ^= activation->GetCausalStack();
       break;
     }
+
     async_activation = Closure::RawCast(next_async_activation.raw());
   }
 
@@ -2155,39 +2137,42 @@
   // activated.
   while (!async_stack_trace.IsNull()) {
     for (intptr_t i = 0; i < async_stack_trace.Length(); i++) {
-      if (async_stack_trace.CodeAtFrame(i) == Code::null()) {
+      code_object = async_stack_trace.CodeAtFrame(i);
+
+      if (code_object.raw() == Code::null()) {
         // Incomplete OutOfMemory/StackOverflow trace OR array padding.
         break;
       }
-      if (async_stack_trace.CodeAtFrame(i) ==
-          StubCode::AsynchronousGapMarker().raw()) {
+
+      if (code_object.raw() == StubCode::AsynchronousGapMarker().raw()) {
         stack_trace->AddMarker(ActivationFrame::kAsyncSuspensionMarker);
         // The frame immediately below the asynchronous gap marker is the
         // identical to the frame above the marker. Skip the frame to enhance
         // the readability of the trace.
         i++;
+        continue;
+      }
+
+      code_object = async_stack_trace.CodeAtFrame(i);
+      offset = Smi::RawCast(async_stack_trace.PcOffsetAtFrame(i));
+      code ^= code_object.raw();
+      if (FLAG_trace_debugger_stacktrace) {
+        OS::PrintErr(
+            "CollectAwaiterReturnStackTrace: visiting frame %" Pd
+            " in async causal stack trace:\n\t%s\n",
+            i, Function::Handle(code.function()).ToFullyQualifiedCString());
+      }
+      uword pc = code.PayloadStart() + offset.Value();
+      if (code.is_optimized()) {
+        for (InlinedFunctionsIterator it(code, pc); !it.Done(); it.Advance()) {
+          inlined_code = it.code();
+          stack_trace->AddAsyncCausalFrame(it.pc(), inlined_code);
+        }
       } else {
-        code_object = async_stack_trace.CodeAtFrame(i);
-        offset = Smi::RawCast(async_stack_trace.PcOffsetAtFrame(i));
-        code ^= code_object.raw();
-        if (FLAG_trace_debugger_stacktrace) {
-          OS::PrintErr(
-              "CollectAwaiterReturnStackTrace: visiting frame %" Pd
-              " in async causal stack trace:\n\t%s\n",
-              i, Function::Handle(code.function()).ToFullyQualifiedCString());
-        }
-        uword pc = code.PayloadStart() + offset.Value();
-        if (code.is_optimized()) {
-          for (InlinedFunctionsIterator it(code, pc); !it.Done();
-               it.Advance()) {
-            inlined_code = it.code();
-            stack_trace->AddAsyncCausalFrame(it.pc(), inlined_code);
-          }
-        } else {
-          stack_trace->AddAsyncCausalFrame(pc, code);
-        }
+        stack_trace->AddAsyncCausalFrame(pc, code);
       }
     }
+
     // Follow the link.
     async_stack_trace = async_stack_trace.async_link();
   }
@@ -3747,14 +3732,14 @@
          frame->function().IsAsyncGenerator())) {
       ASSERT(!frame->GetSavedCurrentContext().IsNull());
       ASSERT(frame->GetSavedCurrentContext().num_variables() >
-             Context::kAsyncCompleterIndex);
+             Context::kAsyncFutureIndex);
 
-      const Object& async_completer = Object::Handle(
-          frame->GetSavedCurrentContext().At(Context::kAsyncCompleterIndex));
+      const Object& async_future = Object::Handle(
+          frame->GetSavedCurrentContext().At(Context::kAsyncFutureIndex));
 
       // Only set breakpoint when entering async_op the first time.
-      // :async_completer_var should be uninitialised at this point:
-      if (async_completer.IsNull()) {
+      // :async_future should be uninitialised at this point:
+      if (async_future.IsNull()) {
         const Function& async_op =
             Function::Handle(frame->function().GetGeneratedClosure());
         if (!async_op.IsNull()) {
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index bd42689..a64fef4 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -1988,29 +1988,8 @@
   ASSERT(function_node_tag == kSomething);
   FunctionNodeHelper function_node_helper(&helper_);
   function_node_helper.ReadUntilIncluding(FunctionNodeHelper::kDartAsyncMarker);
-
-  const bool is_async_await_completer_owner =
-      Symbols::_AsyncAwaitCompleter().Equals(
-          String::Handle(Z, owner.ScrubbedName()));
-
-  // _AsyncAwaitCompleter.future should be made non-debuggable, otherwise
-  // stepping out of async methods will keep hitting breakpoint resulting in
-  // infinite loop.
-  const bool is_async_await_completer_future =
-      is_async_await_completer_owner &&
-      Symbols::CompleterGetFuture().Equals(name);
   function.set_is_debuggable(function_node_helper.dart_async_marker_ ==
-                                 FunctionNodeHelper::kSync &&
-                             !is_async_await_completer_future);
-
-  // _AsyncAwaitCompleter.start should be made non-visible in stack traces,
-  // since it is an implementation detail of our await/async desugaring.
-  if (is_async_await_completer_owner &&
-      Symbols::_AsyncAwaitStart().Equals(name)) {
-    function.set_is_visible(!FLAG_causal_async_stacks &&
-                            !FLAG_lazy_async_stacks);
-  }
-
+                             FunctionNodeHelper::kSync);
   switch (function_node_helper.dart_async_marker_) {
     case FunctionNodeHelper::kSyncStar:
       function.set_modifier(FunctionLayout::kSyncGen);
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index bb0b642..13079ee 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -6670,12 +6670,13 @@
   static const intptr_t kMaxElements = kSmiMax / kBytesPerElement;
 
   static const intptr_t kAwaitJumpVarIndex = 0;
-  static const intptr_t kAsyncCompleterIndex = 1;
+  static const intptr_t kAsyncFutureIndex = 1;
   static const intptr_t kControllerIndex = 1;
   // Expected context index of chained futures in recognized async functions.
   // These are used to unwind async stacks.
   static const intptr_t kFutureTimeoutFutureIndex = 2;
   static const intptr_t kFutureWaitFutureIndex = 2;
+  static const intptr_t kIsSyncIndex = 2;
 
   static intptr_t variable_offset(intptr_t context_index) {
     return OFFSET_OF_RETURNED_VALUE(ContextLayout, data) +
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index fb463b3..5031b69 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -242,7 +242,7 @@
   function_name = async_lib.PrivateName(Symbols::_CompleteOnAsyncReturn());
   ASSERT(!function_name.IsNull());
   function = Resolver::ResolveStatic(async_lib, Object::null_string(),
-                                     function_name, 0, 2, Object::null_array());
+                                     function_name, 0, 3, Object::null_array());
   ASSERT(!function.IsNull());
   set_complete_on_async_return(function);
   if (FLAG_async_debugger) {
@@ -251,6 +251,18 @@
     function.set_is_inlinable(false);
   }
 
+  function_name = async_lib.PrivateName(Symbols::_CompleteOnAsyncError());
+  ASSERT(!function_name.IsNull());
+  function = Resolver::ResolveStatic(async_lib, Object::null_string(),
+                                     function_name, 0, 4, Object::null_array());
+  ASSERT(!function.IsNull());
+  set_complete_on_async_error(function);
+  if (FLAG_async_debugger) {
+    // Disable debugging and inlining the _CompleteOnAsyncError function.
+    function.set_is_debuggable(false);
+    function.set_is_inlinable(false);
+  }
+
   cls =
       async_lib.LookupClassAllowPrivate(Symbols::_AsyncStarStreamController());
   ASSERT(!cls.IsNull());
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 829ae7e..ed3e69d 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -170,6 +170,7 @@
   RW(Function, async_set_thread_stack_trace)                                   \
   RW(Function, async_star_move_next_helper)                                    \
   RW(Function, complete_on_async_return)                                       \
+  RW(Function, complete_on_async_error)                                        \
   RW(Class, async_star_stream_controller)                                      \
   RW(GrowableObjectArray, llvm_constant_pool)                                  \
   RW(GrowableObjectArray, llvm_function_pool)                                  \
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index e8e2ba6..bed2d5c 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -210,36 +210,39 @@
       first_parameter_index;  // Current free frame index.
 
   LocalVariable* await_jump_var = nullptr;
-  LocalVariable* async_completer = nullptr;
+  LocalVariable* async_future = nullptr;
   LocalVariable* controller = nullptr;
   LocalVariable* chained_future = nullptr;
+  LocalVariable* is_sync = nullptr;
   for (intptr_t i = 0; i < num_variables(); i++) {
     LocalVariable* variable = VariableAt(i);
     if (variable->owner() == this) {
       if (variable->is_captured()) {
         if (variable->name().Equals(Symbols::AwaitJumpVar())) {
           await_jump_var = variable;
-        } else if (variable->name().Equals(Symbols::AsyncCompleter())) {
-          async_completer = variable;
+        } else if (variable->name().Equals(Symbols::AsyncFuture())) {
+          async_future = variable;
         } else if (variable->name().Equals(Symbols::Controller())) {
           controller = variable;
         } else if (variable->is_chained_future()) {
           chained_future = variable;
+        } else if (variable->name().Equals(Symbols::is_sync())) {
+          is_sync = variable;
         }
       }
     }
   }
   // If we are in an async/async* function, force :await_jump_var and
-  // :async_completer_var to be at fixed locations in the slot.
+  // :async_future to be at fixed locations in the slot.
   if (await_jump_var != nullptr) {
     AllocateContextVariable(await_jump_var, &context_owner);
     *found_captured_variables = true;
     ASSERT(await_jump_var->index().value() == Context::kAwaitJumpVarIndex);
   }
-  if (async_completer != nullptr) {
-    AllocateContextVariable(async_completer, &context_owner);
+  if (async_future != nullptr) {
+    AllocateContextVariable(async_future, &context_owner);
     *found_captured_variables = true;
-    ASSERT(async_completer->index().value() == Context::kAsyncCompleterIndex);
+    ASSERT(async_future->index().value() == Context::kAsyncFutureIndex);
   }
   if (controller != nullptr) {
     AllocateContextVariable(controller, &context_owner);
@@ -252,6 +255,11 @@
     ASSERT(chained_future->index().value() ==
            chained_future->expected_context_index());
   }
+  if (is_sync != nullptr) {
+    AllocateContextVariable(is_sync, &context_owner);
+    *found_captured_variables = true;
+    ASSERT(is_sync->index().value() == Context::kIsSyncIndex);
+  }
 
   while (pos < num_parameters) {
     LocalVariable* parameter = VariableAt(pos);
@@ -281,8 +289,9 @@
     if (variable->owner() == this) {
       if (variable->is_captured()) {
         // Skip the variables already pre-allocated above.
-        if (variable != await_jump_var && variable != async_completer &&
-            variable != controller && variable != chained_future) {
+        if (variable != await_jump_var && variable != async_future &&
+            variable != controller && variable != chained_future &&
+            variable != is_sync) {
           AllocateContextVariable(variable, &context_owner);
           *found_captured_variables = true;
         }
@@ -320,8 +329,8 @@
     // Keep :async_op for asynchronous debugging.
     return false;
   }
-  if (str.raw() == Symbols::AsyncCompleter().raw()) {
-    // Keep :async_completer for asynchronous debugging.
+  if (str.raw() == Symbols::AsyncFuture().raw()) {
+    // Keep :async_future for asynchronous debugging.
     return false;
   }
   if (str.raw() == Symbols::ControllerStream().raw()) {
@@ -332,6 +341,10 @@
     // Keep :await_jump_var for asynchronous debugging.
     return false;
   }
+  if (str.raw() == Symbols::is_sync().raw()) {
+    // Keep :is_sync for asynchronous debugging.
+    return false;
+  }
   if (str.raw() == Symbols::AsyncStackTraceVar().raw()) {
     // Keep :async_stack_trace for asynchronous debugging.
     return false;
diff --git a/runtime/vm/stack_trace.cc b/runtime/vm/stack_trace.cc
index adb9c8b..5b146ff 100644
--- a/runtime/vm/stack_trace.cc
+++ b/runtime/vm/stack_trace.cc
@@ -49,7 +49,6 @@
       receiver_function_(Function::Handle(zone)),
       parent_function_(Function::Handle(zone)),
       context_entry_(Object::Handle(zone)),
-      is_sync(Object::Handle(zone)),
       future_(Object::Handle(zone)),
       listener_(Object::Handle(zone)),
       callback_(Object::Handle(zone)),
@@ -58,7 +57,6 @@
       var_data_(Object::Handle(zone)),
       callback_instance_(Object::Handle(zone)),
       future_impl_class(Class::Handle(zone)),
-      async_await_completer_class(Class::Handle(zone)),
       future_listener_class(Class::Handle(zone)),
       async_start_stream_controller_class(Class::Handle(zone)),
       stream_controller_class(Class::Handle(zone)),
@@ -66,8 +64,6 @@
       controller_subscription_class(Class::Handle(zone)),
       buffering_stream_subscription_class(Class::Handle(zone)),
       stream_iterator_class(Class::Handle(zone)),
-      completer_is_sync_field(Field::Handle(zone)),
-      completer_future_field(Field::Handle(zone)),
       future_result_or_listeners_field(Field::Handle(zone)),
       callback_field(Field::Handle(zone)),
       controller_controller_field(Field::Handle(zone)),
@@ -80,9 +76,6 @@
   // - async:
   future_impl_class = async_lib.LookupClassAllowPrivate(Symbols::FutureImpl());
   ASSERT(!future_impl_class.IsNull());
-  async_await_completer_class =
-      async_lib.LookupClassAllowPrivate(Symbols::_AsyncAwaitCompleter());
-  ASSERT(!async_await_completer_class.IsNull());
   future_listener_class =
       async_lib.LookupClassAllowPrivate(Symbols::_FutureListener());
   ASSERT(!future_listener_class.IsNull());
@@ -108,12 +101,6 @@
 
   // Look up fields:
   // - async:
-  completer_is_sync_field =
-      async_await_completer_class.LookupFieldAllowPrivate(Symbols::isSync());
-  ASSERT(!completer_is_sync_field.IsNull());
-  completer_future_field =
-      async_await_completer_class.LookupFieldAllowPrivate(Symbols::_future());
-  ASSERT(!completer_future_field.IsNull());
   future_result_or_listeners_field =
       future_impl_class.LookupFieldAllowPrivate(Symbols::_resultOrListeners());
   ASSERT(!future_result_or_listeners_field.IsNull());
@@ -161,12 +148,7 @@
 
 ClosurePtr CallerClosureFinder::FindCallerInAsyncClosure(
     const Context& receiver_context) {
-  context_entry_ = receiver_context.At(Context::kAsyncCompleterIndex);
-  ASSERT(context_entry_.IsInstance());
-  ASSERT(context_entry_.GetClassId() == async_await_completer_class.id());
-
-  const Instance& completer = Instance::Cast(context_entry_);
-  future_ = completer.GetField(completer_future_field);
+  future_ = receiver_context.At(Context::kAsyncFutureIndex);
   return GetCallerInFutureImpl(future_);
 }
 
@@ -248,28 +230,28 @@
 }
 
 bool CallerClosureFinder::IsRunningAsync(const Closure& receiver_closure) {
-  RELEASE_ASSERT(!receiver_closure.IsNull());
-  receiver_function_ = receiver_closure.function();
-  receiver_context_ = receiver_closure.context();
+  auto zone = Thread::Current()->zone();
 
   // The async* functions are never started synchronously, they start running
   // after the first `listen()` call to its returned `Stream`.
+  const Function& receiver_function_ =
+      Function::Handle(zone, receiver_closure.function());
   if (receiver_function_.IsAsyncGenClosure()) {
     return true;
   }
   ASSERT(receiver_function_.IsAsyncClosure());
 
-  context_entry_ = receiver_context_.At(Context::kAsyncCompleterIndex);
-  ASSERT(context_entry_.IsInstance());
-  ASSERT(context_entry_.GetClassId() == async_await_completer_class.id());
-
-  const Instance& completer = Instance::Cast(context_entry_);
-  is_sync = completer.GetField(completer_is_sync_field);
+  const Context& receiver_context_ =
+      Context::Handle(zone, receiver_closure.context());
+  const Object& is_sync =
+      Object::Handle(zone, receiver_context_.At(Context::kIsSyncIndex));
   ASSERT(!is_sync.IsNull());
   ASSERT(is_sync.IsBool());
-  // _AsyncAwaitCompleter.isSync indicates whether the future should be
-  // completed async. or sync., based on whether it has yielded yet.
-  // isSync is true when the :async_op is running async.
+  // isSync indicates whether the future should be completed async. or sync.,
+  // based on whether it has yielded yet.
+  // isSync is true when the :async_op has yielded at least once.
+  // I.e. isSync will be false even after :async_op has run, if e.g. it threw
+  // an exception before yielding.
   return Bool::Cast(is_sync).value();
 }
 
@@ -416,52 +398,55 @@
   return;
 }
 
-// Count the number of frames that are on the stack.
 intptr_t StackTraceUtils::CountFrames(Thread* thread,
                                       int skip_frames,
                                       const Function& async_function,
                                       bool* sync_async_end) {
   Zone* zone = thread->zone();
   intptr_t frame_count = 0;
-  StackFrameIterator frames(ValidationPolicy::kDontValidateFrames, thread,
-                            StackFrameIterator::kNoCrossThreadIteration);
+  DartFrameIterator frames(thread, StackFrameIterator::kNoCrossThreadIteration);
   StackFrame* frame = frames.NextFrame();
-  ASSERT(frame != NULL);  // We expect to find a dart invocation frame.
+  ASSERT(frame != nullptr);  // We expect to find a dart invocation frame.
   Function& function = Function::Handle(zone);
   Code& code = Code::Handle(zone);
-  String& function_name = String::Handle(zone);
+  Closure& closure = Closure::Handle(zone);
   const bool async_function_is_null = async_function.IsNull();
-  int sync_async_gap_frames = -1;
-  ASSERT(async_function_is_null || sync_async_end != NULL);
-  for (; frame != NULL && sync_async_gap_frames != 0;
-       frame = frames.NextFrame()) {
-    if (!frame->IsDartFrame()) {
-      continue;
-    }
+
+  ASSERT(async_function_is_null || sync_async_end != nullptr);
+
+  for (; frame != nullptr; frame = frames.NextFrame()) {
     if (skip_frames > 0) {
       skip_frames--;
       continue;
     }
     code = frame->LookupDartCode();
     function = code.function();
+
+    frame_count++;
+
     const bool function_is_null = function.IsNull();
-    if (!function_is_null && sync_async_gap_frames > 0) {
-      function_name = function.QualifiedScrubbedName();
-      if (!CheckAndSkipAsync(&sync_async_gap_frames, function_name)) {
-        *sync_async_end = false;
-        return frame_count;
-      }
-    } else {
-      frame_count++;
-    }
+
     if (!async_function_is_null && !function_is_null &&
-        (async_function.raw() == function.parent_function())) {
-      sync_async_gap_frames = kSyncAsyncFrameGap;
+        function.parent_function() != Function::null()) {
+      if (async_function.raw() == function.parent_function()) {
+        if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) {
+          ObjectPtr* last_caller_obj =
+              reinterpret_cast<ObjectPtr*>(frame->GetCallerSp());
+          closure = FindClosureInFrame(last_caller_obj, function);
+          if (CallerClosureFinder::IsRunningAsync(closure)) {
+            *sync_async_end = false;
+            return frame_count;
+          }
+        }
+        break;
+      }
     }
   }
+
   if (!async_function_is_null) {
-    *sync_async_end = sync_async_gap_frames == 0;
+    *sync_async_end = true;
   }
+
   return frame_count;
 }
 
@@ -472,8 +457,7 @@
                                         intptr_t count,
                                         int skip_frames) {
   Zone* zone = thread->zone();
-  StackFrameIterator frames(ValidationPolicy::kDontValidateFrames, thread,
-                            StackFrameIterator::kNoCrossThreadIteration);
+  DartFrameIterator frames(thread, StackFrameIterator::kNoCrossThreadIteration);
   StackFrame* frame = frames.NextFrame();
   ASSERT(frame != NULL);  // We expect to find a dart invocation frame.
   Code& code = Code::Handle(zone);
@@ -481,9 +465,6 @@
   intptr_t collected_frames_count = 0;
   for (; (frame != NULL) && (collected_frames_count < count);
        frame = frames.NextFrame()) {
-    if (!frame->IsDartFrame()) {
-      continue;
-    }
     if (skip_frames > 0) {
       skip_frames--;
       continue;
@@ -513,7 +494,7 @@
       StackTrace::Handle(thread->async_stack_trace());
   const intptr_t async_stack_trace_length = async_stack_trace.Length();
   // At least two entries (0: gap marker, 1: async function).
-  ASSERT(async_stack_trace_length >= 2);
+  RELEASE_ASSERT(async_stack_trace_length >= 2);
   // Validate the structure of this stack trace.
   *async_code_array = async_stack_trace.code_array();
   ASSERT(!async_code_array->IsNull());
diff --git a/runtime/vm/stack_trace.h b/runtime/vm/stack_trace.h
index adfec68..660746a 100644
--- a/runtime/vm/stack_trace.h
+++ b/runtime/vm/stack_trace.h
@@ -15,8 +15,6 @@
 namespace dart {
 
 // Helper class for finding the closure of the caller.
-// This is done via the _AsyncAwaitCompleter which holds a
-// FutureResultOrListeners which in turn holds a callback.
 class CallerClosureFinder {
  public:
   explicit CallerClosureFinder(Zone* zone);
@@ -29,7 +27,7 @@
 
   ClosurePtr FindCaller(const Closure& receiver_closure);
 
-  bool IsRunningAsync(const Closure& receiver_closure);
+  static bool IsRunningAsync(const Closure& receiver_closure);
 
  private:
   Context& receiver_context_;
@@ -37,7 +35,6 @@
   Function& parent_function_;
 
   Object& context_entry_;
-  Object& is_sync;
   Object& future_;
   Object& listener_;
   Object& callback_;
@@ -47,7 +44,6 @@
   Object& callback_instance_;
 
   Class& future_impl_class;
-  Class& async_await_completer_class;
   Class& future_listener_class;
   Class& async_start_stream_controller_class;
   Class& stream_controller_class;
@@ -56,8 +52,6 @@
   Class& buffering_stream_subscription_class;
   Class& stream_iterator_class;
 
-  Field& completer_is_sync_field;
-  Field& completer_future_field;
   Field& future_result_or_listeners_field;
   Field& callback_field;
   Field& controller_controller_field;
@@ -128,41 +122,6 @@
                                              StackTrace* async_stack_trace,
                                              Array* async_code_array,
                                              Array* async_pc_offset_array);
-
-  // The number of frames involved in a "sync-async" gap: a synchronous initial
-  // invocation of an asynchronous function. See CheckAndSkipAsync.
-  static constexpr intptr_t kSyncAsyncFrameGap = 2;
-
-  // A synchronous invocation of an async function involves the following
-  // frames:
-  //   <async function>__<anonymous_closure>    (0)
-  //   _Closure.call                            (1)
-  //   _AsyncAwaitCompleter.start               (2)
-  //   <async_function>                         (3)
-  //
-  // Alternatively, for optimized frames, we may see:
-  //   <async function>__<anonymous_closure>    (0)
-  //   _AsyncAwaitCompleter.start               (1)
-  //   <async_function>                         (2)
-  static bool CheckAndSkipAsync(int* skip_sync_async_frames_count,
-                                const String& function_name) {
-    ASSERT(*skip_sync_async_frames_count > 0);
-    // Make sure any function objects for methods used here are marked for
-    // retention by the precompiler, even if otherwise not needed at runtime.
-    //
-    // _AsyncAwaitCompleter.start is marked with the vm:entry-point pragma.
-    if (function_name.Equals(Symbols::_AsyncAwaitCompleterStart())) {
-      *skip_sync_async_frames_count = 0;
-      return true;
-    }
-    // _Closure.call is explicitly checked in Precompiler::MustRetainFunction.
-    if (function_name.Equals(Symbols::_ClosureCall()) &&
-        *skip_sync_async_frames_count == 2) {
-      (*skip_sync_async_frames_count)--;
-      return true;
-    }
-    return false;
-  }
 };
 
 }  // namespace dart
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index d8f11c2..7737d2a 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -28,7 +28,7 @@
   V(AsFunctionInternal, "_asFunctionInternal")                                 \
   V(AssertionError, "_AssertionError")                                         \
   V(AssignIndexToken, "[]=")                                                   \
-  V(AsyncCompleter, ":async_completer")                                        \
+  V(AsyncFuture, ":async_future")                                              \
   V(AsyncOperation, ":async_op")                                               \
   V(AsyncStackTraceVar, ":async_stack_trace")                                  \
   V(AsyncStarMoveNextHelper, "_asyncStarMoveNextHelper")                       \
@@ -308,9 +308,6 @@
   V(WasmDouble, "Double")                                                      \
   V(WasmVoid, "Void")                                                          \
   V(YieldKw, "yield")                                                          \
-  V(_AsyncAwaitCompleter, "_AsyncAwaitCompleter")                              \
-  V(_AsyncAwaitCompleterConstructor, "_AsyncAwaitCompleter.")                  \
-  V(_AsyncAwaitCompleterStart, "_AsyncAwaitCompleter.start")                   \
   V(_AsyncAwaitStart, "start")                                                 \
   V(_AsyncStarStreamController, "_AsyncStarStreamController")                  \
   V(_AsyncStarStreamControllerConstructor, "_AsyncStarStreamController.")      \
@@ -328,6 +325,7 @@
   V(_CompileTimeError, "_CompileTimeError")                                    \
   V(_CompleteOnAsyncReturn, "_completeOnAsyncReturn")                          \
   V(_ControllerSubscription, "_ControllerSubscription")                        \
+  V(_CompleteOnAsyncError, "_completeOnAsyncError")                            \
   V(_DeletedEnumPrefix, "Deleted enum value from ")                            \
   V(_DeletedEnumSentinel, "_deleted_enum_sentinel")                            \
   V(_Double, "_Double")                                                        \
@@ -478,6 +476,7 @@
   V(hashCode, "get:hashCode")                                                  \
   V(identityHashCode, "identityHashCode")                                      \
   V(index_temp, ":index_temp")                                                 \
+  V(is_sync, ":is_sync")                                                       \
   V(isPaused, "isPaused")                                                      \
   V(isSync, "isSync")                                                          \
   V(last, "last")                                                              \
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 3d4b5e3..2b48b5d 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -8,6 +8,8 @@
 import 'dart:_interceptors';
 import 'dart:_js_helper'
     show
+        assertUnreachable,
+        boolConversionCheck,
         checkInt,
         Closure,
         ConstantMap,
@@ -448,8 +450,27 @@
 
   @patch
   factory List.of(Iterable<E> elements, {bool growable: true}) {
-    // TODO(32937): Specialize to benefit from known element type.
-    return List.from(elements, growable: growable);
+    if (growable == true) return List._of(elements);
+    if (growable == false) return List._fixedOf(elements);
+
+    // [growable] may be `null` in legacy mode. Fail with the same error as if
+    // [growable] was used in a condition position in spec mode.
+    boolConversionCheck(growable);
+    assertUnreachable();
+  }
+
+  factory List._of(Iterable<E> elements) {
+    // This is essentially `addAll`, but without a check for modifiability or
+    // ConcurrentModificationError on the receiver.
+    List<E> list = <E>[];
+    for (final e in elements) {
+      list.add(e);
+    }
+    return list;
+  }
+
+  factory List._fixedOf(Iterable<E> elements) {
+    return makeListFixedLength(List._of(elements));
   }
 
   @patch
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 3b29c45..3b1cca4 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -2995,7 +2995,7 @@
 }
 
 @pragma('dart2js:noInline')
-void assertUnreachable() {
+Never assertUnreachable() {
   throw new _UnreachableError();
 }
 
diff --git a/sdk/lib/_internal/vm/lib/async_patch.dart b/sdk/lib/_internal/vm/lib/async_patch.dart
index 781ba01..659f31f 100644
--- a/sdk/lib/_internal/vm/lib/async_patch.dart
+++ b/sdk/lib/_internal/vm/lib/async_patch.dart
@@ -17,49 +17,6 @@
 // Equivalent of calling FATAL from C++ code.
 _fatal(msg) native "DartAsync_fatal";
 
-class _AsyncAwaitCompleter<T> implements Completer<T> {
-  @pragma("vm:entry-point")
-  final _future = new _Future<T>();
-  @pragma("vm:entry-point")
-  bool isSync;
-
-  @pragma("vm:entry-point")
-  _AsyncAwaitCompleter() : isSync = false;
-
-  @pragma("vm:entry-point")
-  void complete([FutureOr<T>? value]) {
-    // All paths require that if value is null, null as T succeeds.
-    value = (value == null) ? value as T : value;
-    if (!isSync) {
-      _future._asyncComplete(value);
-    } else if (value is Future<T>) {
-      assert(!_future._isComplete);
-      _future._chainFuture(value);
-    } else {
-      // TODO(40014): Remove cast when type promotion works.
-      _future._completeWithValue(value as T);
-    }
-  }
-
-  void completeError(Object e, [StackTrace? st]) {
-    st ??= AsyncError.defaultStackTrace(e);
-    if (isSync) {
-      _future._completeError(e, st);
-    } else {
-      _future._asyncCompleteError(e, st);
-    }
-  }
-
-  @pragma("vm:entry-point")
-  void start(void Function() f) {
-    f();
-    isSync = true;
-  }
-
-  Future<T> get future => _future;
-  bool get isCompleted => !_future._mayComplete;
-}
-
 // We need to pass the value as first argument and leave the second and third
 // arguments empty (used for error handling).
 dynamic Function(dynamic) _asyncThenWrapperHelper(
@@ -287,8 +244,25 @@
 }
 
 @pragma("vm:entry-point", "call")
-void _completeOnAsyncReturn(Completer completer, Object? value) {
-  completer.complete(value);
+void _completeOnAsyncReturn(_Future _future, Object? value, bool is_sync) {
+  // The first awaited expression is invoked sync. so complete is async. to
+  // allow then and error handlers to be attached.
+  // async_jump_var=0 is prior to first await, =1 is first await.
+  if (!is_sync || value is Future) {
+    _future._asyncComplete(value);
+  } else {
+    _future._completeWithValue(value);
+  }
+}
+
+@pragma("vm:entry-point", "call")
+void _completeOnAsyncError(
+    _Future _future, Object e, StackTrace st, bool is_sync) {
+  if (!is_sync) {
+    _future._asyncCompleteError(e, st);
+  } else {
+    _future._completeError(e, st);
+  }
 }
 
 /// Returns a [StackTrace] object containing the synchronous prefix for this
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index 0dc3c97..4c3e4f9 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -835,6 +835,7 @@
 // TODO(lrn): Use common superclass for callback-controllers when VM supports
 // constructors in mixin superclasses.
 
+@pragma("vm:entry-point")
 class _AsyncStreamController<T> = _StreamController<T>
     with _AsyncStreamControllerDispatch<T>;
 
diff --git a/tests/lib_2/isolate/issue_6610_test.dart b/tests/lib_2/isolate/issue_6610_test.dart
index 962955e..2b4a987 100644
--- a/tests/lib_2/isolate/issue_6610_test.dart
+++ b/tests/lib_2/isolate/issue_6610_test.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// VMOptions=--enable-isolate-groups
-// VMOptions=--no-enable-isolate-groups
+// VMOptions=--enable-experiment=no-non-nullable --enable-isolate-groups
+// VMOptions=--enable-experiment=no-non-nullable --no-enable-isolate-groups
 
 // Testing that Isolate.spawn copies the source code of the parent isolate,
 // rather than rereading the parent's source URI.
@@ -28,6 +28,7 @@
     server.listen((HttpRequest request) {
       ++count;
       request.response.write("""
+        // @dart = 2.9
         import 'dart:isolate';
 
         void main(_, SendPort port) {
diff --git a/tests/standalone_2/http_launch_data/http_launch_main.dart b/tests/standalone_2/http_launch_data/http_launch_main.dart
index f9a5b52..b5b40f7 100644
--- a/tests/standalone_2/http_launch_data/http_launch_main.dart
+++ b/tests/standalone_2/http_launch_data/http_launch_main.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 library http_launch_main;
 
 import 'package:simple/simple.dart';
diff --git a/tests/standalone_2/io/named_pipe_script_test.dart b/tests/standalone_2/io/named_pipe_script_test.dart
index 932b46c..fb97a1e 100644
--- a/tests/standalone_2/io/named_pipe_script_test.dart
+++ b/tests/standalone_2/io/named_pipe_script_test.dart
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 // Testing file input stream, VM-only, standalone test.
 
+// VMOptions=--enable-experiment=no-non-nullable
+
 import "dart:convert";
 import "dart:io";
 
diff --git a/tests/standalone_2/io/test_extension_fail_tester.dart b/tests/standalone_2/io/test_extension_fail_tester.dart
index f2e72ae..8b80788 100644
--- a/tests/standalone_2/io/test_extension_fail_tester.dart
+++ b/tests/standalone_2/io/test_extension_fail_tester.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 library test_extension_test;
 
 import "dart:async";
diff --git a/tests/standalone_2/io/test_extension_tester.dart b/tests/standalone_2/io/test_extension_tester.dart
index 7a3308c..7f87d13 100644
--- a/tests/standalone_2/io/test_extension_tester.dart
+++ b/tests/standalone_2/io/test_extension_tester.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 // VMOptions=--enable-isolate-groups
 // VMOptions=--no-enable-isolate-groups
 
diff --git a/tools/VERSION b/tools/VERSION
index b32f56d..fd9047b 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 22
+PRERELEASE 23
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/bots/compare_results.dart b/tools/bots/compare_results.dart
index ef74e02..9edd0f8 100755
--- a/tools/bots/compare_results.dart
+++ b/tools/bots/compare_results.dart
@@ -7,6 +7,8 @@
 // The output contains additional details in the verbose mode. There is a human
 // readable mode that explains the results and how they changed.
 
+// @dart = 2.9
+
 import 'dart:collection';
 import 'dart:io';
 
@@ -126,12 +128,10 @@
     } else {
       output = name;
     }
-    if (logs != null) {
-      final log = logs[event.after.key];
-      final bar = '=' * (output.length + 2);
-      if (log != null) {
-        logSection?.add("\n\n/$bar\\\n| $output |\n\\$bar/\n\n${log["log"]}");
-      }
+    final log = logs[event.after.key];
+    final bar = '=' * (output.length + 2);
+    if (log != null) {
+      logSection?.add("\n\n/$bar\\\n| $output |\n\\$bar/\n\n${log["log"]}");
     }
     if (!options["logs-only"]) {
       print(output);
@@ -247,7 +247,7 @@
       "changed": "began failing",
       null: "failed",
     },
-    null: {
+    "any": {
       "unchanged": "had the same result",
       "changed": "changed result",
       null: "ran",
@@ -261,10 +261,12 @@
   final logSection = <String>[];
   bool judgement = false;
   for (final searchForStatus
-      in searchForStatuses.isNotEmpty ? searchForStatuses : <String>[null]) {
+      in searchForStatuses.isNotEmpty ? searchForStatuses : <String>["any"]) {
     final searchForChanged = options["unchanged"]
         ? "unchanged"
-        : options["changed"] ? "changed" : null;
+        : options["changed"]
+            ? "changed"
+            : null;
     final aboutStatus = filterDescriptions[searchForStatus][searchForChanged];
     final sectionHeader = "The following tests $aboutStatus:";
     final logSectionArg =
@@ -286,8 +288,11 @@
     if (options["human"] && !options["logs-only"] && !firstSection) {
       print("");
     }
-    String oldNew =
-        options["unchanged"] ? "old " : options["changed"] ? "new " : "";
+    String oldNew = options["unchanged"]
+        ? "old "
+        : options["changed"]
+            ? "new "
+            : "";
     if (judgement) {
       if (options["human"] && !options["logs-only"]) {
         print("There were ${oldNew}test failures.");
diff --git a/tools/bots/extend_results.dart b/tools/bots/extend_results.dart
index 859c02b..225cc18 100644
--- a/tools/bots/extend_results.dart
+++ b/tools/bots/extend_results.dart
@@ -5,6 +5,8 @@
 // Add fields with data about the test run and the commit tested, and
 // with the result on the last build tested, to the test results file.
 
+// @dart = 2.9
+
 import 'dart:convert';
 import 'dart:io';
 
diff --git a/tools/bots/find_base_commit.dart b/tools/bots/find_base_commit.dart
index 5da2e31..2a75eca 100755
--- a/tools/bots/find_base_commit.dart
+++ b/tools/bots/find_base_commit.dart
@@ -5,6 +5,8 @@
 
 // Find the newest commit that has a full set of results on the bots.
 
+// @dart = 2.9
+
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
diff --git a/tools/bots/get_builder_status.dart b/tools/bots/get_builder_status.dart
index e464abc..e058e42 100755
--- a/tools/bots/get_builder_status.dart
+++ b/tools/bots/get_builder_status.dart
@@ -8,6 +8,8 @@
 // These cloud functions write a success/failure result to the
 // builder table based on the approvals in Firestore.
 
+// @dart = 2.9
+
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io';
@@ -18,7 +20,7 @@
 const numAttempts = 20;
 const failuresPerConfiguration = 20;
 
-bool useStagingDatabase;
+/*late*/ bool useStagingDatabase;
 
 String get queryUrl {
   var project = useStagingDatabase ? "dart-ci-staging" : "dart-ci";
@@ -26,11 +28,11 @@
       'projects/$project/databases/(default)/documents:runQuery';
 }
 
-String builder;
-String builderBase;
-int buildNumber;
-String token;
-http.Client client;
+/*late*/ String builder;
+/*late*/ String builderBase;
+/*late*/ int buildNumber;
+/*late*/ String token;
+/*late*/ http.Client client;
 
 String get buildTable => builder.endsWith('-try') ? 'try_builds' : 'builds';
 String get resultsTable => builder.endsWith('-try') ? 'try_results' : 'results';
@@ -73,9 +75,9 @@
     usage(parser);
   }
 
-  useStagingDatabase = options['staging'];
-  builder = options['builder'];
-  buildNumber = int.parse(options['build_number']);
+  useStagingDatabase = options['staging'] /*!*/;
+  builder = options['builder'] /*!*/;
+  buildNumber = int.parse(options['build_number'] /*!*/);
   builderBase = builder.replaceFirst(RegExp('-try\$'), '');
   if (options['auth_token'] == null) {
     print('Option "--auth_token (-a)" is required\n');
@@ -139,7 +141,7 @@
   final response = await runFirestoreQuery(configurationsQuery());
   if (response.statusCode == HttpStatus.ok) {
     final documents = jsonDecode(response.body);
-    final groups = <String>{
+    final groups = <String /*!*/ >{
       for (Map document in documents)
         if (document.containsKey('document'))
           document['document']['name'].split('/').last
@@ -154,12 +156,12 @@
 Future<String> commitHash(int index) =>
     commitHashes.putIfAbsent(index, () => fetchCommitHash(index));
 
-Future<String> fetchCommitHash(int index) async {
+Future<String /*!*/ > fetchCommitHash(int index) async {
   final response = await runFirestoreQuery(commitQuery(index));
   if (response.statusCode == HttpStatus.ok) {
     final document = jsonDecode(response.body).first['document'];
     if (document != null) {
-      return document['name'].split('/').last;
+      return document['name'] /*!*/ .split('/').last;
     }
   }
   print('Could not fetch commit with index $index');
@@ -167,7 +169,7 @@
 }
 
 Future<Map<String, List<Map<String, dynamic>>>> fetchActiveFailures(
-    List<String> configurations) async {
+    List<String /*!*/ > configurations) async {
   final failures = <String, List<Map<String, dynamic>>>{};
   for (final configuration in configurations) {
     final response =
diff --git a/tools/bots/lib/src/firestore.dart b/tools/bots/lib/src/firestore.dart
index 6e8cc47..44344e2 100644
--- a/tools/bots/lib/src/firestore.dart
+++ b/tools/bots/lib/src/firestore.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 import 'dart:convert' show jsonDecode, jsonEncode;
 import 'dart:io' show File, HttpStatus;
 
@@ -50,7 +52,7 @@
     };
   }
 
-  Future<List> runQuery(Query query) async {
+  Future<List /*!*/ > runQuery(Query query) async {
     var body = jsonEncode(query.data);
     var response = await _client.post(queryUrl, headers: _headers, body: body);
     if (response.statusCode == HttpStatus.ok) {
@@ -60,14 +62,18 @@
     }
   }
 
-  Future<Object> getDocument(String collectionName, String documentName) async {
+  Future<Map> getDocument(String collectionName, String documentName) async {
     var url = '$documentsUrl/$collectionName/$documentName';
     if (_currentTransaction != null) {
       url = '$url?transaction=${_escapedCurrentTransaction}';
     }
     var response = await _client.get(url, headers: _headers);
     if (response.statusCode == HttpStatus.ok) {
-      return jsonDecode(response.body);
+      var document = jsonDecode(response.body);
+      if (!document is Map) {
+        throw _error(response, message: 'Expected a Map');
+      }
+      return document;
     } else {
       throw _error(response);
     }
diff --git a/tools/bots/update_blamelists.dart b/tools/bots/update_blamelists.dart
index ff795ff..af8d525 100644
--- a/tools/bots/update_blamelists.dart
+++ b/tools/bots/update_blamelists.dart
@@ -6,6 +6,8 @@
 // of active, non-approved failures which include the commit of the current
 // bisection build.
 
+// @dart = 2.9
+
 import 'dart:io';
 
 import 'package:args/args.dart';
@@ -25,7 +27,7 @@
 
   ResultRecord(this.data);
 
-  Map field(String name) => data['fields'][name];
+  Map field(String name) => data['fields'][name] /*!*/;
 
   int get blamelistStartIndex {
     return int.parse(field('blamelist_start_index')['integerValue']);
@@ -39,13 +41,13 @@
     return int.parse(field('blamelist_end_index')['integerValue']);
   }
 
-  String get result => field('result')['stringValue'];
+  String get result => field('result')['stringValue'] /*!*/;
 
-  String get previousResult => field('previous_result')['stringValue'];
+  String get previousResult => field('previous_result')['stringValue'] /*!*/;
 
-  String get name => field('name')['stringValue'];
+  String get name => field('name')['stringValue'] /*!*/;
 
-  String get updateTime => data['updateTime'];
+  String get updateTime => data['updateTime'] /*!*/;
 }
 
 Query unapprovedActiveFailuresQuery(String configuration) {
diff --git a/tools/bots/update_flakiness.dart b/tools/bots/update_flakiness.dart
index 2f4f680..337bf61 100755
--- a/tools/bots/update_flakiness.dart
+++ b/tools/bots/update_flakiness.dart
@@ -5,6 +5,8 @@
 
 // Update the flakiness data with a set of fresh results.
 
+// @dart = 2.9
+
 import 'dart:convert';
 import 'dart:io';
 
@@ -43,9 +45,9 @@
   for (final path in parameters) {
     final results = await loadResults(path);
     for (final resultObject in results) {
-      final String configuration = resultObject['configuration'];
-      final String name = resultObject['name'];
-      final String result = resultObject['result'];
+      final String configuration = resultObject['configuration'] /*!*/;
+      final String name = resultObject['name'] /*!*/;
+      final String result = resultObject['result'] /*!*/;
       final key = '$configuration:$name';
       Map<String, dynamic> newMap() => {};
       final testData = data.putIfAbsent(key, newMap);
diff --git a/tools/diff_results.dart b/tools/diff_results.dart
index 0e5ee51..427534f 100644
--- a/tools/diff_results.dart
+++ b/tools/diff_results.dart
@@ -3,6 +3,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 import 'dart:async';
 import 'dart:io';
 import 'dart:convert';
diff --git a/tools/generate_package_config.dart b/tools/generate_package_config.dart
index e20d36681..24c69c2 100644
--- a/tools/generate_package_config.dart
+++ b/tools/generate_package_config.dart
@@ -1,6 +1,9 @@
 #!/usr/bin/env dart
 
 /// Generates the repo's ".dart_tool/package_config.json" file.
+
+// @dart = 2.9
+
 import 'dart:convert';
 import 'dart:io';
 
diff --git a/tools/line_doc_comments.dart b/tools/line_doc_comments.dart
index 22d736d..cedd1b8 100755
--- a/tools/line_doc_comments.dart
+++ b/tools/line_doc_comments.dart
@@ -1,6 +1,8 @@
 #!/usr/bin/env dart
 
 /// Converts block-style Doc comments in Dart code to line style.
+
+// @dart = 2.9
 library line_doc_comments;
 
 import 'dart:io';
diff --git a/tools/test.dart b/tools/test.dart
index 000a4ccc5..fece115 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -1,8 +1,10 @@
 #!/usr/bin/env dart
-
 // Copyright (c) 2018, 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 'package:test_runner/test_runner.dart';
 
 void main(List<String> args) {
diff --git a/tools/validate_test_matrix.dart b/tools/validate_test_matrix.dart
index 8902eb0..9006b54 100644
--- a/tools/validate_test_matrix.dart
+++ b/tools/validate_test_matrix.dart
@@ -4,6 +4,8 @@
 
 // Test that the test matrix in the SDK can be parsed correctly.
 
+// @dart = 2.9
+
 import 'dart:convert' show jsonDecode;
 import 'dart:io' show File, Platform;
 import 'package:smith/smith.dart' show TestMatrix;
diff --git a/tools/yaml2json.dart b/tools/yaml2json.dart
index 3c7c5a2..8ce4907 100644
--- a/tools/yaml2json.dart
+++ b/tools/yaml2json.dart
@@ -2,6 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// @dart = 2.9
+
 import 'dart:io' show File, exit, stderr;
 
 import 'dart:isolate' show RawReceivePort;