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(: