Version 2.12.0-255.0.dev
Merge commit 'aa03d4a8e0899ba9e3fd92cd425a3d9ce009fd63' into 'dev'
diff --git a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
index 8d9c2bb..e276893 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights2_test.dart
@@ -16,14 +16,13 @@
void main() {
defineReflectiveSuite(() {
defineReflectiveTests(AnalysisNotificationHighlightsTest);
- defineReflectiveTests(HighlightsWithControlFlowCollectionsTest);
- defineReflectiveTests(HighlightsWithNullSafetyTest);
defineReflectiveTests(HighlightTypeTest);
});
}
@reflectiveTest
-class AnalysisNotificationHighlightsTest extends HighlightsTestSupport {
+class AnalysisNotificationHighlightsTest extends HighlightsTestSupport
+ with WithNullSafetyServerAnalysisMixin {
Future<void> test_ANNOTATION_hasArguments() async {
addTestFile('''
class AAA {
@@ -99,6 +98,42 @@
assertHasRegion(HighlightRegionType.BUILT_IN, 'await for');
}
+ Future<void> test_BUILT_IN_awaitForIn_list() async {
+ addTestFile('''
+f(a) async {
+ return [await for(var b in a) b];
+}
+''');
+ await prepareHighlights();
+ assertHasRegion(HighlightRegionType.BUILT_IN, 'await');
+ assertHasRegion(HighlightRegionType.KEYWORD, 'for');
+ assertHasRegion(HighlightRegionType.KEYWORD, 'in');
+ }
+
+ Future<void> test_BUILT_IN_awaitForIn_map() async {
+ addTestFile('''
+f(a) async {
+ return {await for(var b in a) b : 0};
+}
+''');
+ await prepareHighlights();
+ assertHasRegion(HighlightRegionType.BUILT_IN, 'await');
+ assertHasRegion(HighlightRegionType.KEYWORD, 'for');
+ assertHasRegion(HighlightRegionType.KEYWORD, 'in');
+ }
+
+ Future<void> test_BUILT_IN_awaitForIn_set() async {
+ addTestFile('''
+f(a) async {
+ return {await for(var b in a) b};
+}
+''');
+ await prepareHighlights();
+ assertHasRegion(HighlightRegionType.BUILT_IN, 'await');
+ assertHasRegion(HighlightRegionType.KEYWORD, 'for');
+ assertHasRegion(HighlightRegionType.KEYWORD, 'in');
+ }
+
Future<void> test_BUILT_IN_deferred() async {
addTestFile('''
import 'dart:math' deferred as math;
@@ -704,6 +739,93 @@
assertHasRegion(HighlightRegionType.KEYWORD, 'with A;');
}
+ Future<void> test_KEYWORD_const_list() async {
+ addTestFile('''
+var v = const [];
+''');
+ await prepareHighlights();
+ assertHasRegion(HighlightRegionType.KEYWORD, 'const');
+ }
+
+ Future<void> test_KEYWORD_const_map() async {
+ addTestFile('''
+var v = const {0 : 1};
+''');
+ await prepareHighlights();
+ assertHasRegion(HighlightRegionType.KEYWORD, 'const');
+ }
+
+ Future<void> test_KEYWORD_const_set() async {
+ addTestFile('''
+var v = const {0};
+''');
+ await prepareHighlights();
+ assertHasRegion(HighlightRegionType.KEYWORD, 'const');
+ }
+
+ Future<void> test_KEYWORD_if_list() async {
+ addTestFile('''
+f(a, b) {
+ return [if (a < b) 'a'];
+}
+''');
+ await prepareHighlights();
+ assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+ }
+
+ Future<void> test_KEYWORD_if_map() async {
+ addTestFile('''
+f(a, b) {
+ return {if (a < b) 'a' : 1};
+}
+''');
+ await prepareHighlights();
+ assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+ }
+
+ Future<void> test_KEYWORD_if_set() async {
+ addTestFile('''
+f(a, b) {
+ return {if (a < b) 'a'};
+}
+''');
+ await prepareHighlights();
+ assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+ }
+
+ Future<void> test_KEYWORD_ifElse_list() async {
+ addTestFile('''
+f(a, b) {
+ return [if (a < b) 'a' else 'b'];
+}
+''');
+ await prepareHighlights();
+ assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+ assertHasRegion(HighlightRegionType.KEYWORD, 'else');
+ }
+
+ Future<void> test_KEYWORD_ifElse_map() async {
+ addTestFile('''
+f(a, b) {
+ return {if (a < b) 'a' : 1 else 'b' : 2};
+}
+''');
+ await prepareHighlights();
+ assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+ assertHasRegion(HighlightRegionType.KEYWORD, 'else');
+ }
+
+ Future<void> test_KEYWORD_ifElse_set() async {
+ addTestFile('''
+f(a, b) {
+ return {if (a < b) 'a' else 'b'};
+}
+''');
+ await prepareHighlights();
+ assertHasRegion(HighlightRegionType.KEYWORD, 'if');
+ assertHasRegion(HighlightRegionType.KEYWORD, 'else');
+ }
+
Future<void> test_KEYWORD_ifElse_statement() async {
addTestFile('''
f(a, b) {
@@ -715,6 +837,16 @@
assertHasRegion(HighlightRegionType.KEYWORD, 'else');
}
+ Future<void> test_KEYWORD_late() async {
+ addTestFile('''
+class C {
+ late int x;
+}
+''');
+ await prepareHighlights();
+ assertHasRegion(HighlightRegionType.KEYWORD, 'late');
+ }
+
Future<void> test_KEYWORD_mixin() async {
addTestFile('''
mixin M {}
@@ -723,6 +855,14 @@
assertHasRegion(HighlightRegionType.BUILT_IN, 'mixin');
}
+ Future<void> test_KEYWORD_required() async {
+ addTestFile('''
+void f({required int x}) {}
+''');
+ await prepareHighlights();
+ assertHasRegion(HighlightRegionType.KEYWORD, 'required');
+ }
+
Future<void> test_KEYWORD_void() async {
addTestFile('''
void main() {
@@ -1154,179 +1294,6 @@
}
@reflectiveTest
-class HighlightsWithControlFlowCollectionsTest extends HighlightsTestSupport {
- @failingTest
- Future<void> test_KEYWORD_awaitForIn_list() async {
- addTestFile('''
-f(a) async {
- return [await for(var b in a) b];
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'await');
- assertHasRegion(HighlightRegionType.KEYWORD, 'for');
- assertHasRegion(HighlightRegionType.KEYWORD, 'in');
- }
-
- @failingTest
- Future<void> test_KEYWORD_awaitForIn_map() async {
- addTestFile('''
-f(a) async {
- return {await for(var b in a) b : 0};
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'await');
- assertHasRegion(HighlightRegionType.KEYWORD, 'for');
- assertHasRegion(HighlightRegionType.KEYWORD, 'in');
- }
-
- @failingTest
- Future<void> test_KEYWORD_awaitForIn_set() async {
- addTestFile('''
-f(a) async {
- return {await for(var b in a) b};
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'await');
- assertHasRegion(HighlightRegionType.KEYWORD, 'for');
- assertHasRegion(HighlightRegionType.KEYWORD, 'in');
- }
-
- Future<void> test_KEYWORD_const_list() async {
- addTestFile('''
-var v = const [];
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'const');
- }
-
- Future<void> test_KEYWORD_const_map() async {
- addTestFile('''
-var v = const {0 : 1};
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'const');
- }
-
- Future<void> test_KEYWORD_const_set() async {
- addTestFile('''
-var v = const {0};
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'const');
- }
-
- Future<void> test_KEYWORD_if_list() async {
- addTestFile('''
-f(a, b) {
- return [if (a < b) 'a'];
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'if');
- }
-
- Future<void> test_KEYWORD_if_map() async {
- addTestFile('''
-f(a, b) {
- return {if (a < b) 'a' : 1};
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'if');
- }
-
- Future<void> test_KEYWORD_if_set() async {
- addTestFile('''
-f(a, b) {
- return {if (a < b) 'a'};
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'if');
- }
-
- Future<void> test_KEYWORD_ifElse_list() async {
- addTestFile('''
-f(a, b) {
- return [if (a < b) 'a' else 'b'];
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'if');
- assertHasRegion(HighlightRegionType.KEYWORD, 'else');
- }
-
- Future<void> test_KEYWORD_ifElse_map() async {
- addTestFile('''
-f(a, b) {
- return {if (a < b) 'a' : 1 else 'b' : 2};
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'if');
- assertHasRegion(HighlightRegionType.KEYWORD, 'else');
- }
-
- Future<void> test_KEYWORD_ifElse_set() async {
- addTestFile('''
-f(a, b) {
- return {if (a < b) 'a' else 'b'};
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'if');
- assertHasRegion(HighlightRegionType.KEYWORD, 'else');
- }
-
- Future<void> test_LITERAL_LIST() async {
- addTestFile('var V = <int>[1, 2, 3];');
- await prepareHighlights();
- assertHasStringRegion(HighlightRegionType.LITERAL_LIST, '<int>[1, 2, 3]');
- }
-
- Future<void> test_LITERAL_MAP() async {
- addTestFile("var V = const <int, String>{1: 'a', 2: 'b', 3: 'c'};");
- await prepareHighlights();
- assertHasStringRegion(HighlightRegionType.LITERAL_MAP,
- "const <int, String>{1: 'a', 2: 'b', 3: 'c'}");
- }
-}
-
-@reflectiveTest
-class HighlightsWithNullSafetyTest extends HighlightsTestSupport {
- @override
- void createProject({Map<String, String> packageRoots}) {
- addAnalysisOptionsFile('''
-analyzer:
- enable-experiment:
- - non-nullable
-''');
- super.createProject(packageRoots: packageRoots);
- }
-
- Future<void> test_KEYWORD_late() async {
- addTestFile('''
-class C {
- late int x;
-}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'late');
- }
-
- Future<void> test_KEYWORD_required() async {
- addTestFile('''
-void f({required int x}) {}
-''');
- await prepareHighlights();
- assertHasRegion(HighlightRegionType.KEYWORD, 'required');
- }
-}
-
-@reflectiveTest
class HighlightTypeTest {
void test_constructor() {
expect(HighlightRegionType.CLASS,
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index dd5d637..adb4cc3 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -227,3 +227,15 @@
return serverChannel.sendRequest(request, throwOnError: throwOnError);
}
}
+
+mixin WithNullSafetyServerAnalysisMixin on AbstractAnalysisTest {
+ @override
+ void createProject({Map<String, String> packageRoots}) {
+ addAnalysisOptionsFile('''
+analyzer:
+ enable-experiment:
+ - non-nullable
+''');
+ super.createProject(packageRoots: packageRoots);
+ }
+}
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index fe2afbf..a8e8b53 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -4,6 +4,7 @@
* Widened the dependency on package:crypto to include version 3.0.0.
* Deprecated `CompilationUnitElement.functionTypeAliases`.
Use `CompilationUnitElement.typeAliases` instead.
+* Added `AnalysisContext.sdkRoot`.
## 0.41.1
* Updated `PackageBuildWorkspace` that supports `package:build` to stop
diff --git a/pkg/analyzer/lib/dart/analysis/analysis_context.dart b/pkg/analyzer/lib/dart/analysis/analysis_context.dart
index 37035e4..97ff59c 100644
--- a/pkg/analyzer/lib/dart/analysis/analysis_context.dart
+++ b/pkg/analyzer/lib/dart/analysis/analysis_context.dart
@@ -4,6 +4,7 @@
import 'package:analyzer/dart/analysis/context_root.dart';
import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/workspace/workspace.dart';
@@ -27,6 +28,10 @@
/// Return the currently active analysis session.
AnalysisSession get currentSession;
+ /// The root directory of the SDK against which files of this context are
+ /// analyzed, or `null` if the SDK is not directory based.
+ Folder get sdkRoot;
+
/// Return the workspace for containing the context root.
Workspace get workspace;
}
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
index 1d90610..13ebb84 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver_based_analysis_context.dart
@@ -8,6 +8,7 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/dart/analysis/driver.dart' show AnalysisDriver;
+import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptions;
import 'package:analyzer/src/workspace/workspace.dart';
@@ -42,6 +43,15 @@
AnalysisSession get currentSession => driver.currentSession;
@override
+ Folder get sdkRoot {
+ var sdk = driver.sourceFactory.dartSdk;
+ if (sdk is FolderBasedDartSdk) {
+ return sdk.directory;
+ }
+ return null;
+ }
+
+ @override
Workspace get workspace {
return _workspace ??= _buildWorkspace();
}
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 9ac4dc9..146592c 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1153,6 +1153,7 @@
/// A list containing all of the function type aliases contained in this
/// compilation unit.
+ @Deprecated('Use typeAliases instead')
List<FunctionTypeAliasElement> _functionTypeAliases;
/// A list containing all of the type aliases contained in this compilation
diff --git a/pkg/analyzer/lib/src/dart/resolver/prefixed_identifier_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/prefixed_identifier_resolver.dart
index 6d65356..a6e5194 100644
--- a/pkg/analyzer/lib/src/dart/resolver/prefixed_identifier_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/prefixed_identifier_resolver.dart
@@ -61,7 +61,7 @@
node.staticType = type;
identifier.staticType = type;
return;
- } else if (element is FunctionTypeAliasElement) {
+ } else if (element is TypeAliasElement) {
if (node.parent is TypeName) {
// no type
} else {
diff --git a/pkg/analyzer/lib/src/error/assignment_verifier.dart b/pkg/analyzer/lib/src/error/assignment_verifier.dart
index 54f0b21..b3f762b 100644
--- a/pkg/analyzer/lib/src/error/assignment_verifier.dart
+++ b/pkg/analyzer/lib/src/error/assignment_verifier.dart
@@ -59,7 +59,7 @@
if (recovery is ClassElement ||
recovery is DynamicElementImpl ||
- recovery is FunctionTypeAliasElement ||
+ recovery is TypeAliasElement ||
recovery is TypeParameterElement) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.ASSIGNMENT_TO_TYPE,
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 99b2de4..8d51b49 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -10365,7 +10365,7 @@
// }
// ```
static const CompileTimeErrorCode RETURN_WITHOUT_VALUE = CompileTimeErrorCode(
- 'RETURN_WITHOUT_VALUE', "The return value is missing after 'return'.",
+ 'RETURN_WITHOUT_VALUE', "The return value is missing after 'return'.",
hasPublishedDocs: true);
static const CompileTimeErrorCode SET_ELEMENT_FROM_DEFERRED_LIBRARY =
diff --git a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
index 03496ce..57c322d 100644
--- a/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
+++ b/pkg/analyzer/lib/src/error/unused_local_elements_verifier.dart
@@ -343,8 +343,6 @@
_visitFieldElement(element);
} else if (element is FunctionElement) {
_visitFunctionElement(element);
- } else if (element is FunctionTypeAliasElement) {
- _visitFunctionTypeAliasElement(element);
} else if (element is LocalVariableElement) {
_visitLocalVariableElement(element);
} else if (element is MethodElement) {
@@ -353,6 +351,8 @@
_visitPropertyAccessorElement(element);
} else if (element is TopLevelVariableElement) {
_visitTopLevelVariableElement(element);
+ } else if (element is TypeAliasElement) {
+ _visitTypeAliasElement(element);
}
}
}
@@ -580,13 +580,6 @@
}
}
- void _visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
- if (!_isUsedElement(element)) {
- _reportErrorForElement(
- HintCode.UNUSED_ELEMENT, element, [element.displayName]);
- }
- }
-
void _visitLocalVariableElement(LocalVariableElement element) {
if (!_isUsedElement(element) && !_isNamedUnderscore(element)) {
HintCode errorCode;
@@ -621,6 +614,13 @@
HintCode.UNUSED_ELEMENT, element, [element.displayName]);
}
}
+
+ void _visitTypeAliasElement(TypeAliasElement element) {
+ if (!_isUsedElement(element)) {
+ _reportErrorForElement(
+ HintCode.UNUSED_ELEMENT, element, [element.displayName]);
+ }
+ }
}
/// A container with sets of used [Element]s.
diff --git a/pkg/analyzer/lib/src/summary2/default_types_builder.dart b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
index 68cc053..2dcb918 100644
--- a/pkg/analyzer/lib/src/summary2/default_types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/default_types_builder.dart
@@ -257,7 +257,7 @@
if (declaration is ClassElement) {
recurseParameters(declaration.typeParameters);
- } else if (declaration is FunctionTypeAliasElement) {
+ } else if (declaration is TypeAliasElement) {
recurseParameters(declaration.typeParameters);
}
visited.remove(startType.element);
diff --git a/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart b/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
index a54fa1a..8df9d1c 100644
--- a/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/context_builder_test.dart
@@ -88,4 +88,14 @@
expect(context.driver.sourceFactory.dartSdk.mapDartUri('dart:core'),
sdk.mapDartUri('dart:core'));
}
+
+ test_createContext_sdkRoot() {
+ MockSdk(resourceProvider: resourceProvider);
+ DriverBasedAnalysisContext context = contextBuilder.createContext(
+ contextRoot: contextRoot,
+ sdkPath: resourceProvider.convertPath(sdkRoot));
+ expect(context.analysisOptions, isNotNull);
+ expect(context.contextRoot, contextRoot);
+ expect(context.sdkRoot.path, sdkRoot);
+ }
}
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index 0dd6b71..25d5b03 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -7823,7 +7823,7 @@
await resolveTestFile();
FunctionTypeAlias alias = findNode.functionTypeAlias('F<T>');
- FunctionTypeAliasElement aliasElement = alias.declaredElement;
+ TypeAliasElement aliasElement = alias.declaredElement;
FieldDeclaration fDeclaration = findNode.fieldDeclaration('F<int> f');
@@ -7915,7 +7915,7 @@
CompilationUnit unit = result.unit;
FunctionTypeAlias fNode = unit.declarations[1];
- FunctionTypeAliasElement fElement = fNode.declaredElement;
+ TypeAliasElement fElement = fNode.declaredElement;
var statements = _getMainStatements(result);
diff --git a/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart b/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart
index 37f0d93..c3d86dd 100644
--- a/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/prefixed_identifier_test.dart
@@ -167,6 +167,38 @@
);
}
+ test_read_typedef_functionType() async {
+ newFile('$testPackageLibPath/a.dart', content: r'''
+typedef A = void Function();
+''');
+
+ await assertNoErrorsInCode('''
+import 'a.dart' as p;
+
+void f() {
+ p.A;
+}
+''');
+
+ var importFind = findElement.importFind('package:test/a.dart');
+ var A = importFind.typeAlias('A');
+
+ var prefixed = findNode.prefixed('p.A');
+ assertPrefixedIdentifier(
+ prefixed,
+ element: A,
+ type: 'Type',
+ );
+
+ assertImportPrefix(prefixed.prefix, importFind.prefix);
+
+ assertSimpleIdentifier(
+ prefixed.identifier,
+ element: A,
+ type: 'Type',
+ );
+ }
+
test_readWrite_assignment() async {
await assertNoErrorsInCode('''
class A {
@@ -288,6 +320,38 @@
type: 'int',
);
}
+
+ test_read_typedef_interfaceType() async {
+ newFile('$testPackageLibPath/a.dart', content: r'''
+typedef A = List<int>;
+''');
+
+ await assertNoErrorsInCode('''
+import 'a.dart' as p;
+
+void f() {
+ p.A;
+}
+''');
+
+ var importFind = findElement.importFind('package:test/a.dart');
+ var A = importFind.typeAlias('A');
+
+ var prefixed = findNode.prefixed('p.A');
+ assertPrefixedIdentifier(
+ prefixed,
+ element: A,
+ type: 'Type',
+ );
+
+ assertImportPrefix(prefixed.prefix, importFind.prefix);
+
+ assertSimpleIdentifier(
+ prefixed.identifier,
+ element: A,
+ type: 'Type',
+ );
+ }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/assignment_to_type_test.dart b/pkg/analyzer/test/src/diagnostics/assignment_to_type_test.dart
index cdba72f..a8133c3 100644
--- a/pkg/analyzer/test/src/diagnostics/assignment_to_type_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/assignment_to_type_test.dart
@@ -14,7 +14,8 @@
}
@reflectiveTest
-class AssignmentToTypeTest extends PubPackageResolutionTest {
+class AssignmentToTypeTest extends PubPackageResolutionTest
+ with WithNonFunctionTypeAliasesMixin {
test_class() async {
await assertErrorsInCode('''
class C {}
@@ -47,7 +48,7 @@
]);
}
- test_typedef() async {
+ test_typedef_functionType() async {
await assertErrorsInCode('''
typedef void F();
main() {
@@ -58,6 +59,18 @@
]);
}
+ test_typedef_interfaceType() async {
+ await assertErrorsInCode('''
+typedef F = List<int>;
+
+void f() {
+ F = null;
+}
+''', [
+ error(CompileTimeErrorCode.ASSIGNMENT_TO_TYPE, 37, 1),
+ ]);
+ }
+
test_typeParameter() async {
await assertErrorsInCode('''
class C<T> {
diff --git a/pkg/analyzer/test/src/diagnostics/unused_element_test.dart b/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
index 95cf0b8..08e380a 100644
--- a/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/unused_element_test.dart
@@ -11,6 +11,7 @@
defineReflectiveSuite(() {
defineReflectiveTests(UnusedElementTest);
defineReflectiveTests(UnusedElementWithNullSafetyTest);
+ defineReflectiveTests(UnusedElementWithNonFunctionTypeAliasesTest);
});
}
@@ -1526,6 +1527,94 @@
error(HintCode.UNUSED_ELEMENT, 34, 2),
]);
}
+
+ test_typeAlias_functionType_isUsed_isExpression() async {
+ await assertNoErrorsInCode(r'''
+typedef _F = void Function();
+main(f) {
+ if (f is _F) {
+ print('F');
+ }
+}
+''');
+ }
+
+ test_typeAlias_functionType_isUsed_reference() async {
+ await assertNoErrorsInCode(r'''
+typedef _F = void Function();
+main(_F f) {
+}
+''');
+ }
+
+ test_typeAlias_functionType_isUsed_typeArgument() async {
+ await assertNoErrorsInCode(r'''
+typedef _F = void Function();
+main() {
+ var v = new List<_F>();
+ print(v);
+}
+''');
+ }
+
+ test_typeAlias_functionType_isUsed_variableDeclaration() async {
+ await assertNoErrorsInCode(r'''
+typedef _F = void Function();
+class A {
+ _F f;
+}
+''');
+ }
+
+ test_typeAlias_functionType_notUsed_noReference() async {
+ await assertErrorsInCode(r'''
+typedef _F = void Function();
+main() {
+}
+''', [
+ error(HintCode.UNUSED_ELEMENT, 8, 2),
+ ]);
+ }
+}
+
+@reflectiveTest
+class UnusedElementWithNonFunctionTypeAliasesTest
+ extends PubPackageResolutionTest with WithNonFunctionTypeAliasesMixin {
+ test_typeAlias_interfaceType_isUsed_typeName_isExpression() async {
+ await assertNoErrorsInCode(r'''
+typedef _A = List<int>;
+
+void f(a) {
+ a is _A;
+}
+''');
+ }
+
+ test_typeAlias_interfaceType_isUsed_typeName_parameter() async {
+ await assertNoErrorsInCode(r'''
+typedef _A = List<int>;
+
+void f(_A a) {}
+''');
+ }
+
+ test_typeAlias_interfaceType_isUsed_typeName_typeArgument() async {
+ await assertNoErrorsInCode(r'''
+typedef _A = List<int>;
+
+void f() {
+ Map<_A, int>();
+}
+''');
+ }
+
+ test_typeAlias_interfaceType_notUsed() async {
+ await assertErrorsInCode(r'''
+typedef _A = List<int>;
+''', [
+ error(HintCode.UNUSED_ELEMENT, 8, 2),
+ ]);
+ }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index b439e4f..d690b6c 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -1314,7 +1314,7 @@
''');
}
- test_class_notSimplyBounded_complex_by_cycle() async {
+ test_class_notSimplyBounded_complex_by_cycle_class() async {
var library = await checkLibrary('''
class C<T extends D> {}
class D<T extends C> {}
@@ -1327,6 +1327,29 @@
''');
}
+ test_class_notSimplyBounded_complex_by_cycle_typedef_functionType() async {
+ var library = await checkLibrary('''
+typedef C<T extends D> = void Function();
+typedef D<T extends C> = void Function();
+''');
+ checkElementText(library, r'''
+notSimplyBounded typedef C<T extends dynamic Function()> = void Function();
+notSimplyBounded typedef D<T extends dynamic Function()> = void Function();
+''');
+ }
+
+ test_class_notSimplyBounded_complex_by_cycle_typedef_interfaceType() async {
+ featureSet = FeatureSets.nonFunctionTypeAliases;
+ var library = await checkLibrary('''
+typedef C<T extends D> = List<T>;
+typedef D<T extends C> = List<T>;
+''');
+ checkElementText(library, r'''
+notSimplyBounded typedef C<T extends dynamic> = List<T>;
+notSimplyBounded typedef D<T extends dynamic> = List<T>;
+''');
+ }
+
test_class_notSimplyBounded_complex_by_reference_to_cycle() async {
var library = await checkLibrary('''
class C<T extends D> {}
diff --git a/pkg/analyzer/test/util/element_type_matchers.dart b/pkg/analyzer/test/util/element_type_matchers.dart
index 1ace6dd..f286b3f 100644
--- a/pkg/analyzer/test/util/element_type_matchers.dart
+++ b/pkg/analyzer/test/util/element_type_matchers.dart
@@ -24,8 +24,6 @@
const isFunctionElement = TypeMatcher<FunctionElement>();
-const isFunctionTypeAliasElement = TypeMatcher<FunctionTypeAliasElement>();
-
const isFunctionTypedElement = TypeMatcher<FunctionTypedElement>();
const isGenericFunctionTypeElement = TypeMatcher<GenericFunctionTypeElement>();
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index 1fe281f..340a5a4 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -8878,7 +8878,7 @@
### return_without_value
-_The return value is missing after 'return'._
+_The return value is missing after 'return'._
#### Description
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index bf9f4a7..c01275b 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -96,6 +96,7 @@
static const String useNewSourceInfo = '--use-new-source-info';
static const String useOldRti = '--use-old-rti';
static const String verbose = '--verbose';
+ static const String verbosity = '--verbosity';
static const String progress = '--show-internal-progress';
static const String version = '--version';
static const String reportMetrics = '--report-metrics';
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index c528dfb..b1d2000 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -545,6 +545,7 @@
new OptionHandler(Flags.testMode, passThrough),
new OptionHandler('${Flags.dumpSsa}=.+', passThrough),
new OptionHandler('${Flags.cfeInvocationModes}=.+', passThrough),
+ new OptionHandler('${Flags.verbosity}=.+', passThrough),
// Experimental features.
// We don't provide documentation for these yet.
diff --git a/pkg/compiler/lib/src/kernel/loader.dart b/pkg/compiler/lib/src/kernel/loader.dart
index a44d5c5..99a37c5 100644
--- a/pkg/compiler/lib/src/kernel/loader.dart
+++ b/pkg/compiler/lib/src/kernel/loader.dart
@@ -138,8 +138,13 @@
bool verbose = false;
Target target = Dart2jsTarget(targetName, TargetFlags());
fe.FileSystem fileSystem = CompilerFileSystem(_compilerInput);
+ fe.Verbosity verbosity = _options.verbosity;
fe.DiagnosticMessageHandler onDiagnostic =
- (e) => reportFrontEndMessage(_reporter, e);
+ (fe.DiagnosticMessage message) {
+ if (fe.Verbosity.shouldPrint(verbosity, message)) {
+ reportFrontEndMessage(_reporter, message);
+ }
+ };
fe.CompilerOptions options = fe.CompilerOptions()
..target = target
..librariesSpecificationUri = _options.librariesSpecificationUri
@@ -147,7 +152,8 @@
..explicitExperimentalFlags = _options.explicitExperimentalFlags
..verbose = verbose
..fileSystem = fileSystem
- ..onDiagnostic = onDiagnostic;
+ ..onDiagnostic = onDiagnostic
+ ..verbosity = verbosity;
bool isLegacy =
await fe.uriUsesLegacyLanguageVersion(resolvedUri, options);
inferNullSafetyMode(_options.enableNonNullable && !isLegacy);
@@ -171,8 +177,8 @@
nnbdMode: _options.useLegacySubtyping
? fe.NnbdMode.Weak
: fe.NnbdMode.Strong,
- invocationModes:
- fe.InvocationMode.parseArguments(_options.cfeInvocationModes));
+ invocationModes: _options.cfeInvocationModes,
+ verbosity: verbosity);
component = await fe.compile(initializedCompilerState, verbose,
fileSystem, onDiagnostic, resolvedUri);
if (component == null) return null;
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 2e6ffe7..ddb6dd0 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -433,7 +433,10 @@
/// See `InvocationMode` in
/// `pkg/front_end/lib/src/api_prototype/compiler_options.dart` for all
/// possible options.
- String cfeInvocationModes = '';
+ Set<fe.InvocationMode> cfeInvocationModes = {};
+
+ /// Verbosity level used for filtering messages during compilation.
+ fe.Verbosity verbosity = fe.Verbosity.all;
// -------------------------------------------------
// Options for deprecated features
@@ -547,8 +550,13 @@
.._noSoundNullSafety = _hasOption(options, Flags.noSoundNullSafety)
.._mergeFragmentsThreshold =
_extractIntOption(options, '${Flags.mergeFragmentsThreshold}=')
- ..cfeInvocationModes =
- _extractStringOption(options, '${Flags.cfeInvocationModes}=', '');
+ ..cfeInvocationModes = fe.InvocationMode.parseArguments(
+ _extractStringOption(options, '${Flags.cfeInvocationModes}=', ''),
+ onError: onError)
+ ..verbosity = fe.Verbosity.parseArgument(
+ _extractStringOption(
+ options, '${Flags.verbosity}=', fe.Verbosity.defaultValue),
+ onError: onError);
}
void validate() {
diff --git a/pkg/dart2native/bin/dart2native.dart b/pkg/dart2native/bin/dart2native.dart
index 6df0953..7f407416 100644
--- a/pkg/dart2native/bin/dart2native.dart
+++ b/pkg/dart2native/bin/dart2native.dart
@@ -7,6 +7,8 @@
import 'package:args/args.dart';
import 'package:dart2native/generate.dart';
+import 'package:front_end/src/api_prototype/compiler_options.dart'
+ show Verbosity;
void printUsage(final ArgParser parser) {
print('''
@@ -65,7 +67,16 @@
Comma separated list of experimental features.
''')
..addFlag('verbose',
- abbr: 'v', negatable: false, help: 'Show verbose output.');
+ abbr: 'v', negatable: false, help: 'Show verbose output.')
+ ..addOption(
+ 'verbosity',
+ defaultsTo: Verbosity.defaultValue,
+ help: '''
+Sets the verbosity level used for filtering messages during compilation.
+''',
+ allowed: Verbosity.allowedValues,
+ allowedHelp: Verbosity.allowedValuesHelp,
+ );
ArgResults parsedArgs;
try {
@@ -106,6 +117,7 @@
enableExperiment: parsedArgs['enable-experiment'],
enableAsserts: parsedArgs['enable-asserts'],
verbose: parsedArgs['verbose'],
+ verbosity: parsedArgs['verbosity'],
extraOptions: parsedArgs['extra-gen-snapshot-options']);
} catch (e) {
stderr.writeln('Failed to generate native files:');
diff --git a/pkg/dart2native/lib/generate.dart b/pkg/dart2native/lib/generate.dart
index 3579ec8..6bc3abd 100644
--- a/pkg/dart2native/lib/generate.dart
+++ b/pkg/dart2native/lib/generate.dart
@@ -27,6 +27,7 @@
String enableExperiment = '',
bool enableAsserts = false,
bool verbose = false,
+ String verbosity = 'all',
List<String> extraOptions = const [],
}) async {
final Directory tempDir = Directory.systemTemp.createTempSync();
@@ -58,7 +59,10 @@
final kernelResult = await generateAotKernel(Platform.executable, genKernel,
productPlatformDill, sourcePath, kernelFile, packages, defines,
enableExperiment: enableExperiment,
- extraGenKernelOptions: ['--invocation-modes=compile']);
+ extraGenKernelOptions: [
+ '--invocation-modes=compile',
+ '--verbosity=$verbosity'
+ ]);
if (kernelResult.exitCode != 0) {
// We pipe both stdout and stderr to stderr because the CFE doesn't print
// errors to stderr. This unfortunately does emit info-only output in
diff --git a/pkg/dart2native/pubspec.yaml b/pkg/dart2native/pubspec.yaml
index 85a9eac..4c274e7 100644
--- a/pkg/dart2native/pubspec.yaml
+++ b/pkg/dart2native/pubspec.yaml
@@ -12,5 +12,7 @@
dependencies:
args: ^1.4.0
path: any
+ front_end:
+ path: ../front_end
dev_dependencies:
diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart
index 29c5b3e..f3f6e63 100644
--- a/pkg/dartdev/lib/src/commands/compile.dart
+++ b/pkg/dartdev/lib/src/commands/compile.dart
@@ -7,6 +7,8 @@
import 'package:dart2native/generate.dart';
import 'package:path/path.dart' as path;
+import 'package:front_end/src/api_prototype/compiler_options.dart'
+ show Verbosity;
import '../core.dart';
import '../experiments.dart';
@@ -19,8 +21,17 @@
final String flag;
final String help;
final String abbr;
+ final String defaultsTo;
+ final List<String> allowed;
+ final Map<String, String> allowedHelp;
- Option({this.flag, this.help, this.abbr});
+ Option(
+ {this.flag,
+ this.help,
+ this.abbr,
+ this.defaultsTo,
+ this.allowed,
+ this.allowedHelp});
}
final Map<String, Option> commonOptions = {
@@ -32,6 +43,15 @@
This can be an absolute or relative path.
''',
),
+ 'verbosity': Option(
+ flag: 'verbosity',
+ help: '''
+Sets the verbosity level of the compilation.
+''',
+ defaultsTo: Verbosity.defaultValue,
+ allowed: Verbosity.allowedValues,
+ allowedHelp: Verbosity.allowedValuesHelp,
+ ),
};
bool checkFile(String sourcePath) {
@@ -53,6 +73,15 @@
commonOptions['outputFile'].flag,
help: commonOptions['outputFile'].help,
abbr: commonOptions['outputFile'].abbr,
+ defaultsTo: commonOptions['outputFile'].defaultsTo,
+ )
+ ..addOption(
+ commonOptions['verbosity'].flag,
+ help: commonOptions['verbosity'].help,
+ abbr: commonOptions['verbosity'].abbr,
+ defaultsTo: commonOptions['verbosity'].defaultsTo,
+ allowed: commonOptions['verbosity'].allowed,
+ allowedHelp: commonOptions['verbosity'].allowedHelp,
)
..addFlag(
'minified',
@@ -196,6 +225,14 @@
help: commonOptions['outputFile'].help,
abbr: commonOptions['outputFile'].abbr,
)
+ ..addOption(
+ commonOptions['verbosity'].flag,
+ help: commonOptions['verbosity'].help,
+ abbr: commonOptions['verbosity'].abbr,
+ defaultsTo: commonOptions['verbosity'].defaultsTo,
+ allowed: commonOptions['verbosity'].allowed,
+ allowedHelp: commonOptions['verbosity'].allowedHelp,
+ )
..addMultiOption('define', abbr: 'D', valueHelp: 'key=value', help: '''
Define an environment declaration. To specify multiple declarations, use multiple options or use commas to separate key-value pairs.
For example: dart compile $commandName -Da=1,b=2 main.dart''')
@@ -246,6 +283,7 @@
enableExperiment: argResults.enabledExperiments.join(','),
debugFile: argResults['save-debugging-info'],
verbose: verbose,
+ verbosity: argResults['verbosity'],
);
return 0;
} catch (e) {
diff --git a/pkg/dartdev/pubspec.yaml b/pkg/dartdev/pubspec.yaml
index a8fef55..9beb550 100644
--- a/pkg/dartdev/pubspec.yaml
+++ b/pkg/dartdev/pubspec.yaml
@@ -17,6 +17,8 @@
dart2native:
path: ../dart2native
dart_style: any
+ front_end:
+ path: ../front_end
intl: any
meta:
path: ../meta
diff --git a/pkg/dartdev/test/commands/compile_test.dart b/pkg/dartdev/test/commands/compile_test.dart
index 8f2e8b8..5aaf14c 100644
--- a/pkg/dartdev/test/commands/compile_test.dart
+++ b/pkg/dartdev/test/commands/compile_test.dart
@@ -310,6 +310,30 @@
reason: 'File not found: $outFile');
});
+ test('Compile exe without info', () {
+ final p = project(mainSrc: '''void main() {}''');
+ final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
+ final outFile = path.canonicalize(path.join(p.dirPath, 'myexe'));
+
+ var result = p.runSync(
+ [
+ 'compile',
+ 'exe',
+ '--verbosity=warning',
+ '-o',
+ outFile,
+ inFile,
+ ],
+ );
+
+ expect(result.stdout,
+ predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
+ expect(result.stderr, isEmpty);
+ expect(result.exitCode, 0);
+ expect(File(outFile).existsSync(), true,
+ reason: 'File not found: $outFile');
+ });
+
test('Compile JS with sound null safety', () {
final p = project(mainSrc: '''void main() {}''');
final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
@@ -357,6 +381,30 @@
reason: 'File not found: $outFile');
});
+ test('Compile JS without info', () {
+ final p = project(mainSrc: '''void main() {}''');
+ final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
+ final outFile = path.canonicalize(path.join(p.dirPath, 'myjs'));
+
+ var result = p.runSync(
+ [
+ 'compile',
+ 'js',
+ '--verbosity=warning',
+ '-o',
+ outFile,
+ inFile,
+ ],
+ );
+
+ expect(result.stdout,
+ predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
+ expect(result.stderr, isEmpty);
+ expect(result.exitCode, 0);
+ expect(File(outFile).existsSync(), true,
+ reason: 'File not found: $outFile');
+ });
+
test('Compile AOT snapshot with sound null safety', () {
final p = project(mainSrc: '''void main() {}''');
final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
@@ -404,6 +452,30 @@
reason: 'File not found: $outFile');
});
+ test('Compile AOT snapshot without info', () {
+ final p = project(mainSrc: '''void main() {}''');
+ final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
+ final outFile = path.canonicalize(path.join(p.dirPath, 'myaot'));
+
+ var result = p.runSync(
+ [
+ 'compile',
+ 'aot-snapshot',
+ '--verbosity=warning',
+ '-o',
+ outFile,
+ inFile,
+ ],
+ );
+
+ expect(result.stdout,
+ predicate((o) => !'$o'.contains(soundNullSafetyMessage)));
+ expect(result.stderr, isEmpty);
+ expect(result.exitCode, 0);
+ expect(File(outFile).existsSync(), true,
+ reason: 'File not found: $outFile');
+ });
+
test('Compile kernel with sound null safety', () {
final p = project(mainSrc: '''void main() {}''');
final inFile = path.canonicalize(path.join(p.dirPath, p.relativeFilePath));
diff --git a/pkg/front_end/lib/src/api_prototype/compiler_options.dart b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
index 5e0b86b..5e7960f 100644
--- a/pkg/front_end/lib/src/api_prototype/compiler_options.dart
+++ b/pkg/front_end/lib/src/api_prototype/compiler_options.dart
@@ -7,7 +7,8 @@
library front_end.compiler_options;
import 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart'
- show DiagnosticMessageHandler;
+ show DiagnosticMessage, DiagnosticMessageHandler;
+import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
import 'package:kernel/ast.dart' show Version;
@@ -265,6 +266,9 @@
/// compilation mode when the modes includes [InvocationMode.compile].
Set<InvocationMode> invocationModes = {};
+ /// Verbosity level used for filtering emitted messages.
+ Verbosity verbosity = Verbosity.all;
+
bool isExperimentEnabledByDefault(ExperimentalFlag flag) {
return flags.isExperimentEnabled(flag,
defaultExperimentFlagsForTesting: defaultExperimentFlagsForTesting);
@@ -455,13 +459,25 @@
/// Returns the set of information modes from a comma-separated list of
/// invocation mode names.
- static Set<InvocationMode> parseArguments(String arg) {
+ ///
+ /// If a name isn't recognized and [onError] is provided, [onError] is called
+ /// with an error messages and an empty set of invocation modes is returned.
+ ///
+ /// If a name isn't recognized and [onError] isn't provided, an error is
+ /// thrown.
+ static Set<InvocationMode> parseArguments(String arg,
+ {void Function(String) onError}) {
Set<InvocationMode> result = {};
for (String name in arg.split(',')) {
if (name.isNotEmpty) {
InvocationMode mode = fromName(name);
if (mode == null) {
- throw new UnsupportedError("Unknown invocation mode '$name'.");
+ String message = "Unknown invocation mode '$name'.";
+ if (onError != null) {
+ onError(message);
+ } else {
+ throw new UnsupportedError(message);
+ }
} else {
result.add(mode);
}
@@ -482,3 +498,109 @@
static const List<InvocationMode> values = const [compile];
}
+
+/// Verbosity level used for filtering messages during compilation.
+class Verbosity {
+ /// Only error messages are emitted.
+ static const Verbosity error =
+ const Verbosity('error', 'Show only error messages');
+
+ /// Error and warning messages are emitted.
+ static const Verbosity warning =
+ const Verbosity('warning', 'Show only error and warning messages');
+
+ /// Error, warning, and info messages are emitted.
+ static const Verbosity info =
+ const Verbosity('info', 'Show error, warning, and info messages');
+
+ /// All messages are emitted.
+ static const Verbosity all = const Verbosity('all', 'Show all messages');
+
+ static const List<Verbosity> values = const [error, warning, info, all];
+
+ /// Returns the names of all options.
+ static List<String> get allowedValues =>
+ [for (Verbosity value in values) value.name];
+
+ /// Returns a map from option name to option help messages.
+ static Map<String, String> get allowedValuesHelp =>
+ {for (Verbosity value in values) value.name: value.help};
+
+ /// Returns the verbosity corresponding to the given [name].
+ ///
+ /// If [name] isn't recognized and [onError] is provided, [onError] is called
+ /// with an error messages and [defaultValue] is returned.
+ ///
+ /// If [name] isn't recognized and [onError] isn't provided, an error is
+ /// thrown.
+ static Verbosity parseArgument(String name,
+ {void Function(String) onError, Verbosity defaultValue: Verbosity.all}) {
+ for (Verbosity verbosity in values) {
+ if (name == verbosity.name) {
+ return verbosity;
+ }
+ }
+ String message = "Unknown verbosity '$name'.";
+ if (onError != null) {
+ onError(message);
+ return defaultValue;
+ }
+ throw new UnsupportedError(message);
+ }
+
+ static bool shouldPrint(Verbosity verbosity, DiagnosticMessage message) {
+ Severity severity = message.severity;
+ switch (verbosity) {
+ case Verbosity.error:
+ switch (severity) {
+ case Severity.internalProblem:
+ case Severity.error:
+ return true;
+ case Severity.warning:
+ case Severity.info:
+ case Severity.context:
+ case Severity.ignored:
+ return false;
+ }
+ break;
+ case Verbosity.warning:
+ switch (severity) {
+ case Severity.internalProblem:
+ case Severity.error:
+ case Severity.warning:
+ return true;
+ case Severity.info:
+ case Severity.context:
+ case Severity.ignored:
+ return false;
+ }
+ break;
+ case Verbosity.info:
+ switch (severity) {
+ case Severity.internalProblem:
+ case Severity.error:
+ case Severity.warning:
+ case Severity.info:
+ return true;
+ case Severity.context:
+ case Severity.ignored:
+ return false;
+ }
+ break;
+ case Verbosity.all:
+ return true;
+ }
+ throw new UnsupportedError(
+ "Unsupported verbosity $verbosity and severity $severity.");
+ }
+
+ static const String defaultValue = 'all';
+
+ final String name;
+ final String help;
+
+ const Verbosity(this.name, this.help);
+
+ @override
+ String toString() => 'Verbosity($name)';
+}
diff --git a/pkg/front_end/lib/src/api_unstable/dart2js.dart b/pkg/front_end/lib/src/api_unstable/dart2js.dart
index 358c006..c9fbb930 100644
--- a/pkg/front_end/lib/src/api_unstable/dart2js.dart
+++ b/pkg/front_end/lib/src/api_unstable/dart2js.dart
@@ -21,7 +21,7 @@
import 'package:kernel/target/targets.dart' show Target;
import '../api_prototype/compiler_options.dart'
- show CompilerOptions, InvocationMode;
+ show CompilerOptions, InvocationMode, Verbosity;
import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
@@ -103,6 +103,7 @@
show
CompilerOptions,
InvocationMode,
+ Verbosity,
parseExperimentalFlags,
parseExperimentalArguments;
@@ -146,7 +147,8 @@
{Map<ExperimentalFlag, bool> explicitExperimentalFlags,
bool verify: false,
NnbdMode nnbdMode,
- Set<InvocationMode> invocationModes: const <InvocationMode>{}}) {
+ Set<InvocationMode> invocationModes: const <InvocationMode>{},
+ Verbosity verbosity: Verbosity.all}) {
additionalDills.sort((a, b) => a.toString().compareTo(b.toString()));
// We don't check `target` because it doesn't support '==' and each
@@ -160,7 +162,8 @@
explicitExperimentalFlags) &&
oldState.options.verify == verify &&
oldState.options.nnbdMode == nnbdMode &&
- equalSets(oldState.options.invocationModes, invocationModes)) {
+ equalSets(oldState.options.invocationModes, invocationModes) &&
+ oldState.options.verbosity == verbosity) {
return oldState;
}
@@ -171,7 +174,8 @@
..packagesFileUri = packagesFileUri
..explicitExperimentalFlags = explicitExperimentalFlags
..verify = verify
- ..invocationModes = invocationModes;
+ ..invocationModes = invocationModes
+ ..verbosity = verbosity;
if (nnbdMode != null) options.nnbdMode = nnbdMode;
ProcessedOptions processedOpts = new ProcessedOptions(options: options);
diff --git a/pkg/front_end/lib/src/api_unstable/vm.dart b/pkg/front_end/lib/src/api_unstable/vm.dart
index 547bbb2..9bfeea8 100644
--- a/pkg/front_end/lib/src/api_unstable/vm.dart
+++ b/pkg/front_end/lib/src/api_unstable/vm.dart
@@ -13,6 +13,7 @@
show
CompilerOptions,
InvocationMode,
+ Verbosity,
parseExperimentalArguments,
parseExperimentalFlags;
diff --git a/pkg/front_end/lib/src/base/command_line_options.dart b/pkg/front_end/lib/src/base/command_line_options.dart
index 862187a..d2e2f84 100644
--- a/pkg/front_end/lib/src/base/command_line_options.dart
+++ b/pkg/front_end/lib/src/base/command_line_options.dart
@@ -38,6 +38,7 @@
static const String singleRootBase = "--single-root-base";
static const String singleRootScheme = "--single-root-scheme";
static const String verbose = "--verbose";
+ static const String verbosity = "--verbosity";
static const String verify = "--verify";
static const String verifySkipPlatform = "--verify-skip-platform";
static const String warnOnReachabilityCheck = "--warn-on-reachability-check";
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index e768713..bc6c7ad 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -26,7 +26,7 @@
import 'package:package_config/package_config.dart';
import '../api_prototype/compiler_options.dart'
- show CompilerOptions, InvocationMode, DiagnosticMessage;
+ show CompilerOptions, InvocationMode, Verbosity, DiagnosticMessage;
import '../api_prototype/experimental_flags.dart' as flags;
@@ -263,7 +263,9 @@
}
void _defaultDiagnosticMessageHandler(DiagnosticMessage message) {
- printDiagnosticMessage(message, print);
+ if (Verbosity.shouldPrint(_raw.verbosity, message)) {
+ printDiagnosticMessage(message, print);
+ }
}
// TODO(askesc): Remove this and direct callers directly to report.
diff --git a/pkg/front_end/lib/src/fasta/type_inference/closure_context.dart b/pkg/front_end/lib/src/fasta/type_inference/closure_context.dart
index 78dc0c5..4029c5c 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/closure_context.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/closure_context.dart
@@ -546,30 +546,75 @@
statement.expression.fileOffset,
noLength)
..parent = statement;
- } else if (flattenedExpressionType is! VoidType &&
- !inferrer.typeSchemaEnvironment
- .performNullabilityAwareSubtypeCheck(
- flattenedExpressionType, futureValueType)
- .isSubtypeWhenUsingNullabilities()) {
- // It is a compile-time error if s is `return e;`, flatten(S) is not
- // void, S is not assignable to T_v, and flatten(S) is not a subtype
- // of T_v.
- statement.expression = inferrer.ensureAssignable(
- futureValueType, expressionType, statement.expression,
- fileOffset: statement.expression.fileOffset,
- runtimeCheckedType:
- inferrer.computeGreatestClosure2(_returnContext),
- declaredContextType: returnType,
- isVoidAllowed: false,
- errorTemplate: templateInvalidReturnAsync,
- nullabilityErrorTemplate: templateInvalidReturnAsyncNullability,
- nullabilityPartErrorTemplate:
- templateInvalidReturnAsyncPartNullability,
- nullabilityNullErrorTemplate:
- templateInvalidReturnAsyncNullabilityNull,
- nullabilityNullTypeErrorTemplate:
- templateInvalidReturnAsyncNullabilityNullType)
- ..parent = statement;
+ } else {
+ DartType futureOrType =
+ inferrer.computeGreatestClosure2(_returnContext);
+ if (flattenedExpressionType is! VoidType &&
+ !inferrer.typeSchemaEnvironment
+ .performNullabilityAwareSubtypeCheck(
+ flattenedExpressionType, futureValueType)
+ .isSubtypeWhenUsingNullabilities()) {
+ // It is a compile-time error if s is `return e;`, flatten(S) is not
+ // void, S is not assignable to T_v, and flatten(S) is not a subtype
+ // of T_v.
+ statement.expression = inferrer.ensureAssignable(
+ futureValueType, expressionType, statement.expression,
+ fileOffset: statement.expression.fileOffset,
+ runtimeCheckedType: futureOrType,
+ declaredContextType: returnType,
+ isVoidAllowed: false,
+ errorTemplate: templateInvalidReturnAsync,
+ nullabilityErrorTemplate: templateInvalidReturnAsyncNullability,
+ nullabilityPartErrorTemplate:
+ templateInvalidReturnAsyncPartNullability,
+ nullabilityNullErrorTemplate:
+ templateInvalidReturnAsyncNullabilityNull,
+ nullabilityNullTypeErrorTemplate:
+ templateInvalidReturnAsyncNullabilityNullType)
+ ..parent = statement;
+ }
+ // For `return e`:
+ // When `f` is an asynchronous non-generator with future value type
+ // T_v, evaluation proceeds as follows:
+ //
+ // The expression `e` is evaluated to an object `o`.
+ // If the run-time type of `o` is a subtype of `Future<T_v>`,
+ // let `v` be a fresh variable bound to `o` and
+ // evaluate `await v` to an object `r`;
+ // otherwise let `r` be `o`.
+ // A dynamic error occurs unless the dynamic type of `r`
+ // is a subtype of the actual value of T_v.
+ // Then the return statement `s` completes returning `r`.
+ DartType futureType = new InterfaceType(
+ inferrer.coreTypes.futureClass,
+ Nullability.nonNullable,
+ [futureValueType]);
+ VariableDeclaration variable;
+ Expression isOperand;
+ Expression awaitOperand;
+ Expression resultExpression;
+ if (isPureExpression(statement.expression)) {
+ isOperand = clonePureExpression(statement.expression);
+ awaitOperand = clonePureExpression(statement.expression);
+ resultExpression = statement.expression;
+ } else {
+ variable = createVariable(statement.expression, expressionType);
+ isOperand = createVariableGet(variable);
+ awaitOperand = createVariableGet(variable);
+ resultExpression = createVariableGet(variable);
+ }
+ Expression replacement = new ConditionalExpression(
+ new IsExpression(isOperand, futureType)
+ ..fileOffset = statement.fileOffset,
+ new AwaitExpression(awaitOperand)
+ ..fileOffset = statement.fileOffset,
+ resultExpression,
+ futureOrType)
+ ..fileOffset = statement.fileOffset;
+ if (variable != null) {
+ replacement = createLet(variable, replacement);
+ }
+ statement.expression = replacement..parent = statement;
}
}
} else {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 0b50fbb..4dd7287 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -2514,16 +2514,13 @@
// `void` if `B’` contains no `yield` expressions. Otherwise, let `M` be
// the least upper bound of the types of the `return` expressions in `B’`,
// or `void` if `B’` contains no `return` expressions.
- DartType inferredReturnType;
if (needToSetReturnType) {
- inferredReturnType = closureContext.inferReturnType(this,
+ DartType inferredReturnType = closureContext.inferReturnType(this,
hasImplicitReturn: flowAnalysis.isReachable);
- }
- // Then the result of inference is `<T0, ..., Tn>(R0 x0, ..., Rn xn) B` with
- // type `<T0, ..., Tn>(R0, ..., Rn) -> M’` (with some of the `Ri` and `xi`
- // denoted as optional or named parameters, if appropriate).
- if (needToSetReturnType) {
+ // Then the result of inference is `<T0, ..., Tn>(R0 x0, ..., Rn xn) B`
+ // with type `<T0, ..., Tn>(R0, ..., Rn) -> M'` (with some of the `Ri` and
+ // `xi` denoted as optional or named parameters, if appropriate).
instrumentation?.record(uriForInstrumentation, fileOffset, 'returnType',
new InstrumentationValueForType(inferredReturnType));
function.returnType = inferredReturnType;
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 572493d..e422e9d 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -868,6 +868,7 @@
printf
println
proc
+proceeds
producers
product
progresses
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 55be1a1..d3bc3e1a 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -737,6 +737,7 @@
unassignment
unawaited
unbreak
+uncaught
unconverted
uncover
uncovers
diff --git a/pkg/front_end/test/text_representation/data/expressions.dart b/pkg/front_end/test/text_representation/data/expressions.dart
index bf8c23c..4d70d21 100644
--- a/pkg/front_end/test/text_representation/data/expressions.dart
+++ b/pkg/front_end/test/text_representation/data/expressions.dart
@@ -382,7 +382,9 @@
exprMap() => {0: "foo", 1: "bar"};
/*member: exprAwait:await o*/
-exprAwait(o) async => await o;
+exprAwait(o) async {
+ await o;
+}
/*member: exprLoadLibrary:prefix.loadLibrary()*/
exprLoadLibrary() => prefix.loadLibrary();
diff --git a/pkg/front_end/test/text_representation/text_representation_test.dart b/pkg/front_end/test/text_representation/text_representation_test.dart
index f804385..d9019d0 100644
--- a/pkg/front_end/test/text_representation/text_representation_test.dart
+++ b/pkg/front_end/test/text_representation/text_representation_test.dart
@@ -156,14 +156,16 @@
@override
String computeMemberValue(Id id, Member node) {
- if (node.name.text == 'stmtVariableDeclarationMulti') {
- print(node);
- }
if (node.name.text.startsWith(expressionMarker)) {
if (node is Procedure) {
Statement body = node.function.body;
if (body is ReturnStatement) {
return body.expression.toText(strategy);
+ } else if (body is Block &&
+ body.statements.isNotEmpty &&
+ body.statements.first is ExpressionStatement) {
+ ExpressionStatement statement = body.statements.first;
+ return statement.expression.toText(strategy);
}
} else if (node is Field && node.initializer != null) {
return node.initializer.toText(strategy);
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.strong.expect b/pkg/front_end/testcases/late_lowering/later.dart.strong.expect
index 0b84933..74694bf 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.strong.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.strong.expect
@@ -134,28 +134,28 @@
await for (core::String s in asy::Stream::fromIterable<core::String>(<core::String>["hest"])) {
core::print(s);
}
- return "hest";
+ return let final core::String #t8 = "hest" in #t8 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t8 : #t8;
}
static method fisk() → dynamic async {
lowered core::String? #s1;
function #s1#get() → core::String
- return let final core::String? #t8 = #s1 in #t8.==(null) ?{core::String} #s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
+ return let final core::String? #t9 = #s1 in #t9.==(null) ?{core::String} #s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
late String s1 = await hest(); // Error.
- ^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::String : #t8{core::String};
- function #s1#set(core::String #t9) → dynamic
- return #s1 = #t9;
+ ^^^^^" as{TypeError,ForDynamic,ForNonNullableByDefault} core::String : #t9{core::String};
+ function #s1#set(core::String #t10) → dynamic
+ return #s1 = #t10;
lowered core::String? #s2;
function #s2#get() → core::String
- return let final core::String? #t10 = #s2 in #t10.==(null) ?{core::String} #s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
+ return let final core::String? #t11 = #s2 in #t11.==(null) ?{core::String} #s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
late String s2 = '\${fisk}\${await hest()}\${fisk}'; // Error.
- ^^^^^"}${#C1}" : #t10{core::String};
- function #s2#set(core::String #t11) → dynamic
- return #s2 = #t11;
+ ^^^^^"}${#C1}" : #t11{core::String};
+ function #s2#set(core::String #t12) → dynamic
+ return #s2 = #t12;
lowered core::Function? #f;
function #f#get() → core::Function
- return let final core::Function? #t12 = #f in #t12.==(null) ?{core::Function} #f = () → asy::Future<dynamic> async => await self::hest() : #t12{core::Function};
- function #f#set(core::Function #t13) → dynamic
- return #f = #t13;
+ return let final core::Function? #t13 = #f in #t13.==(null) ?{core::Function} #f = () → asy::Future<dynamic> async => let final dynamic #t14 = await self::hest() in #t14 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t14 : #t14 : #t13{core::Function};
+ function #f#set(core::Function #t15) → dynamic
+ return #f = #t15;
}
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 12f0ed3..09236c4 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
@@ -148,6 +148,8 @@
dynamic :saved_try_context_var1;
dynamic :exception0;
dynamic :stack_trace0;
+ FutureOr<dynamic>:async_temporary_0;
+ FutureOr<dynamic>:async_temporary_1;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
@@ -175,7 +177,15 @@
:result;
}
}
- :return_value = "hest";
+ final core::String #t11 = "hest";
+ if(#t11 is asy::Future<dynamic>) {
+ [yield] let dynamic #t12 = asy::_awaitHelper(#t11, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_1 = _in::unsafeCast<core::String>(:result);
+ }
+ else {
+ :async_temporary_1 = #t11;
+ }
+ :return_value = :async_temporary_1;
break #L1;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -204,21 +214,21 @@
{
lowered core::String? #s1;
function #s1#get() → core::String
- return let final core::String? #t11 = #s1 in #t11.==(null) ?{core::String} #s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
+ return let final core::String? #t13 = #s1 in #t13.==(null) ?{core::String} #s1 = invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:40:20: Error: `await` expressions are not supported in late local initializers.
late String s1 = await hest(); // Error.
- ^^^^^" : #t11{core::String};
- function #s1#set(core::String #t12) → dynamic
- return #s1 = #t12;
+ ^^^^^" : #t13{core::String};
+ function #s1#set(core::String #t14) → dynamic
+ return #s1 = #t14;
lowered core::String? #s2;
function #s2#get() → core::String
- return let final core::String? #t13 = #s2 in #t13.==(null) ?{core::String} #s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
+ return let final core::String? #t15 = #s2 in #t15.==(null) ?{core::String} #s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/late_lowering/later.dart:41:30: Error: `await` expressions are not supported in late local initializers.
late String s2 = '\${fisk}\${await hest()}\${fisk}'; // Error.
- ^^^^^"}${#C1}" : #t13{core::String};
- function #s2#set(core::String #t14) → dynamic
- return #s2 = #t14;
+ ^^^^^"}${#C1}" : #t15{core::String};
+ function #s2#set(core::String #t16) → dynamic
+ return #s2 = #t16;
lowered 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 */ {
+ return let final core::Function? #t17 = #f in #t17.==(null) ?{core::Function} #f = () → asy::Future<dynamic> /* originally async */ {
final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
core::bool* :is_sync = false;
FutureOr<dynamic>? :return_value;
@@ -227,12 +237,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
{
- [yield] let dynamic #t16 = asy::_awaitHelper(self::hest(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result;
+ [yield] let dynamic #t18 = asy::_awaitHelper(self::hest(), :async_op_then, :async_op_error, :async_op) in null;
+ final dynamic #t19 = :result;
+ if(#t19 is asy::Future<dynamic>) {
+ [yield] let dynamic #t20 = asy::_awaitHelper(#t19, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = :result;
+ }
+ else {
+ :async_temporary_0 = #t19;
+ }
+ :return_value = :async_temporary_0;
break #L4;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -246,9 +265,9 @@
:async_op.call();
:is_sync = true;
return :async_future;
- } : #t15{core::Function};
- function #f#set(core::Function #t17) → dynamic
- return #f = #t17;
+ } : #t17{core::Function};
+ function #f#set(core::Function #t21) → dynamic
+ return #f = #t21;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
return;
@@ -270,4 +289,4 @@
Extra constant evaluation status:
Evaluated: VariableGet @ org-dartlang-testcase:///later.dart:46:18 -> IntConstant(42)
-Extra constant evaluation: evaluated: 207, effectively constant: 1
+Extra constant evaluation: evaluated: 234, effectively constant: 1
diff --git a/pkg/front_end/testcases/late_lowering/later.dart.weak.expect b/pkg/front_end/testcases/late_lowering/later.dart.weak.expect
index 7123dd80..0d0243b 100644
--- a/pkg/front_end/testcases/late_lowering/later.dart.weak.expect
+++ b/pkg/front_end/testcases/late_lowering/later.dart.weak.expect
@@ -154,7 +154,7 @@
await for (core::String s in asy::Stream::fromIterable<core::String>(<core::String>["hest"])) {
core::print(s);
}
- return "hest";
+ return let final core::String #t8 = "hest" in #t8 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t8 : #t8;
}
static method fisk() → dynamic async {
lowered core::String? #s1;
@@ -168,9 +168,9 @@
}
return #s1{core::String};
}
- function #s1#set(core::String #t8) → dynamic {
+ function #s1#set(core::String #t9) → dynamic {
#s1#isSet = true;
- return #s1 = #t8;
+ return #s1 = #t9;
}
lowered core::String? #s2;
lowered core::bool #s2#isSet = false;
@@ -183,22 +183,22 @@
}
return #s2{core::String};
}
- function #s2#set(core::String #t9) → dynamic {
+ function #s2#set(core::String #t10) → dynamic {
#s2#isSet = true;
- return #s2 = #t9;
+ return #s2 = #t10;
}
lowered core::Function? #f;
lowered core::bool #f#isSet = false;
function #f#get() → core::Function {
if(!#f#isSet) {
- #f = () → asy::Future<dynamic> async => await self::hest();
+ #f = () → asy::Future<dynamic> async => let final dynamic #t11 = await self::hest() in #t11 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t11 : #t11;
#f#isSet = true;
}
return #f{core::Function};
}
- function #f#set(core::Function #t10) → dynamic {
+ function #f#set(core::Function #t12) → dynamic {
#f#isSet = true;
- return #f = #t10;
+ return #f = #t12;
}
}
static method main() → dynamic {}
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 3bcf2b7..7fe5b1b 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
@@ -168,6 +168,8 @@
dynamic :saved_try_context_var1;
dynamic :exception0;
dynamic :stack_trace0;
+ FutureOr<dynamic>:async_temporary_0;
+ FutureOr<dynamic>:async_temporary_1;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
@@ -195,7 +197,15 @@
:result;
}
}
- :return_value = "hest";
+ final core::String #t11 = "hest";
+ if(#t11 is asy::Future<dynamic>) {
+ [yield] let dynamic #t12 = asy::_awaitHelper(#t11, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_1 = _in::unsafeCast<core::String>(:result);
+ }
+ else {
+ :async_temporary_1 = #t11;
+ }
+ :return_value = :async_temporary_1;
break #L1;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -233,9 +243,9 @@
}
return #s1{core::String};
}
- function #s1#set(core::String #t11) → dynamic {
+ function #s1#set(core::String #t13) → dynamic {
#s1#isSet = true;
- return #s1 = #t11;
+ return #s1 = #t13;
}
lowered core::String? #s2;
lowered core::bool #s2#isSet = false;
@@ -248,9 +258,9 @@
}
return #s2{core::String};
}
- function #s2#set(core::String #t12) → dynamic {
+ function #s2#set(core::String #t14) → dynamic {
#s2#isSet = true;
- return #s2 = #t12;
+ return #s2 = #t14;
}
lowered core::Function? #f;
lowered core::bool #f#isSet = false;
@@ -265,12 +275,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
{
- [yield] let dynamic #t13 = asy::_awaitHelper(self::hest(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result;
+ [yield] let dynamic #t15 = asy::_awaitHelper(self::hest(), :async_op_then, :async_op_error, :async_op) in null;
+ final dynamic #t16 = :result;
+ if(#t16 is asy::Future<dynamic>) {
+ [yield] let dynamic #t17 = asy::_awaitHelper(#t16, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = :result;
+ }
+ else {
+ :async_temporary_0 = #t16;
+ }
+ :return_value = :async_temporary_0;
break #L4;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -289,9 +308,9 @@
}
return #f{core::Function};
}
- function #f#set(core::Function #t14) → dynamic {
+ function #f#set(core::Function #t18) → dynamic {
#f#isSet = true;
- return #f = #t14;
+ return #f = #t18;
}
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
diff --git a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.expect b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.expect
index 0e66be9..6769397 100644
--- a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.expect
@@ -263,35 +263,35 @@
}
function local() → FutureOr<self::A> async {
if(true) {
- return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:43:14: Error: A value of type 'B?' can't be returned from an async function with return type 'FutureOr<A>' because 'B?' is nullable and 'FutureOr<A>' isn't.
+ return let final self::B? #t6 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:43:14: Error: A value of type 'B?' can't be returned from an async function with return type 'FutureOr<A>' because 'B?' is nullable and 'FutureOr<A>' isn't.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return x; // Error.
- ^" in x as{TypeError,ForNonNullableByDefault} self::A;
+ ^" in x as{TypeError,ForNonNullableByDefault} self::A in #t6 is asy::Future<self::A> ?{FutureOr<self::A>} await #t6 : #t6;
}
else {
- return let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:45:18: Error: A value of type 'Future<B?>' can't be returned from an async function with return type 'FutureOr<A>'.
+ return let final asy::Future<self::B?> #t8 = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:45:18: Error: A value of type 'Future<B?>' can't be returned from an async function with return type 'FutureOr<A>'.
- 'Future' is from 'dart:async'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return new Future<B?>.value(x); // Error.
- ^" in asy::Future::value<self::B?>(x) as{TypeError,ForNonNullableByDefault} self::A;
+ ^" in asy::Future::value<self::B?>(x) as{TypeError,ForNonNullableByDefault} self::A in #t8 is asy::Future<self::A> ?{FutureOr<self::A>} await #t8 : #t8;
}
}
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:49:10: Error: A value of type 'B?' can't be returned from a function with return type 'A' because 'B?' is nullable and 'A' isn't.
+ return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:49:10: Error: A value of type 'B?' can't be returned from a function with return type 'A' because 'B?' is nullable and 'A' isn't.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return x; // Error.
^" in x as{TypeError,ForNonNullableByDefault} self::A;
}
static method bar(core::List<self::B?> x, core::List<core::List<self::B?>> l, core::Map<core::List<self::B?>, core::List<self::B?>> m) → core::List<self::A> {
- self::barContext(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:53:14: Error: The argument type 'List<B?>' can't be assigned to the parameter type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ self::barContext(let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:53:14: Error: The argument type 'List<B?>' can't be assigned to the parameter type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
barContext(x); // Error.
^" in x as{TypeError,ForNonNullableByDefault} core::List<self::A>);
- core::List<self::A> y = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:54:15: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ core::List<self::A> y = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:54:15: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
@@ -314,16 +314,16 @@
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
<List<A>, List<A>>{...m}; // Error.
^"};
- for (final core::List<self::B?> #t11 in l) {
- core::List<self::A> y = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:57:16: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ for (final core::List<self::B?> #t13 in l) {
+ core::List<self::A> y = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:57:16: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
Try changing the type of the variable.
for (List<A> y in l) {} // Error.
- ^" in #t11 as{TypeError,ForNonNullableByDefault} core::List<self::A>;
+ ^" in #t13 as{TypeError,ForNonNullableByDefault} core::List<self::A>;
}
- return let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:58:10: Error: A value of type 'List<B?>' can't be returned from a function with return type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ return let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:58:10: Error: A value of type 'List<B?>' can't be returned from a function with return type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
@@ -331,52 +331,52 @@
^" in x as{TypeError,ForNonNullableByDefault} core::List<self::A>;
}
static method baz(self::C c) → void {
- self::bazContext(let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:62:14: Error: The argument type 'num? Function()' can't be assigned to the parameter type 'num Function()' because 'num?' is nullable and 'num' isn't.
+ self::bazContext(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:62:14: Error: The argument type 'num? Function()' can't be assigned to the parameter type 'num Function()' because 'num?' is nullable and 'num' isn't.
bazContext(c);
- ^" in (let final self::C #t15 = c in #t15.==(null) ?{() → core::num?} null : #t15.{self::C::call}) as{TypeError,ForNonNullableByDefault} () → core::num);
+ ^" in (let final self::C #t17 = c in #t17.==(null) ?{() → core::num?} null : #t17.{self::C::call}) as{TypeError,ForNonNullableByDefault} () → core::num);
}
static method boz(Null x) → self::A {
- self::fooContext(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:66:14: Error: The argument type 'Null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
+ self::fooContext(let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:66:14: Error: The argument type 'Null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
fooContext(x); // Error.
^" in x as{TypeError,ForNonNullableByDefault} self::A);
- self::fooContext(let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:67:14: Error: The value 'null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
+ self::fooContext(let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:67:14: Error: The value 'null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
fooContext(null); // Error.
^" in null as{TypeError,ForNonNullableByDefault} self::A);
- self::A a1 = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:68:10: Error: A value of type 'Null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
+ self::A a1 = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:68:10: Error: A value of type 'Null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
A a1 = x; // Error.
^" in x as{TypeError,ForNonNullableByDefault} self::A;
- self::A a2 = let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:69:10: Error: The value 'null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
+ self::A a2 = let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:69:10: Error: The value 'null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
A a2 = null; // Error.
^" in null as{TypeError,ForNonNullableByDefault} self::A;
if(true) {
- return let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:71:12: Error: A value of type 'Null' can't be returned from a function with return type 'A' because 'A' is not nullable.
+ return let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:71:12: Error: A value of type 'Null' can't be returned from a function with return type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return x; // Error.
^" in x as{TypeError,ForNonNullableByDefault} self::A;
}
else {
- return let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:73:12: Error: The value 'null' can't be returned from a function with return type 'A' because 'A' is not nullable.
+ return let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:73:12: Error: The value 'null' can't be returned from a function with return type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return null; // Error.
^" in null as{TypeError,ForNonNullableByDefault} self::A;
}
function local() → FutureOr<self::A> async {
if(true) {
- return let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:77:14: Error: The value 'null' can't be returned from an async function with return type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
+ return let final Null #t24 = let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:77:14: Error: The value 'null' can't be returned from an async function with return type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return null; // Error.
- ^" in null as{TypeError,ForNonNullableByDefault} self::A;
+ ^" in null as{TypeError,ForNonNullableByDefault} self::A in #t24 is asy::Future<self::A> ?{FutureOr<self::A>} await #t24 : #t24;
}
else {
- return let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:79:18: Error: A value of type 'Future<Null>' can't be returned from an async function with return type 'FutureOr<A>'.
+ return let final asy::Future<Null> #t26 = let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:79:18: Error: A value of type 'Future<Null>' can't be returned from an async function with return type 'FutureOr<A>'.
- 'Future' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return new Future<Null>.value(null); // Error.
- ^" in asy::Future::value<Null>(null) as{TypeError,ForNonNullableByDefault} self::A;
+ ^" in asy::Future::value<Null>(null) as{TypeError,ForNonNullableByDefault} self::A in #t26 is asy::Future<self::A> ?{FutureOr<self::A>} await #t26 : #t26;
}
}
}
diff --git a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect
index bdd60d8..c855781 100644
--- a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.strong.transformed.expect
@@ -180,6 +180,7 @@
import self as self;
import "dart:core" as core;
import "dart:async" as asy;
+import "dart:_internal" as _in;
import "dart:async";
@@ -280,25 +281,45 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<self::A>:async_temporary_0;
+ FutureOr<self::A>:async_temporary_1;
+ FutureOr<self::A>:async_temporary_2;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
{
if(true) {
- :return_value = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:43:14: Error: A value of type 'B?' can't be returned from an async function with return type 'FutureOr<A>' because 'B?' is nullable and 'FutureOr<A>' isn't.
+ final self::B? #t10 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:43:14: Error: A value of type 'B?' can't be returned from an async function with return type 'FutureOr<A>' because 'B?' is nullable and 'FutureOr<A>' isn't.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return x; // Error.
- ^" in let self::B? #t11 = x in #t11.==(null) ?{self::A} #t11 as{TypeError,ForNonNullableByDefault} self::A : #t11{self::A};
+ ^" in let self::B? #t12 = x in #t12.==(null) ?{self::A} #t12 as{TypeError,ForNonNullableByDefault} self::A : #t12{self::A};
+ if(#t10 is asy::Future<self::A>) {
+ [yield] let dynamic #t13 = asy::_awaitHelper(#t10, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<self::B?>(:result);
+ }
+ else {
+ :async_temporary_0 = #t10;
+ }
+ :return_value = :async_temporary_0;
break #L4;
}
else {
- :return_value = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:45:18: Error: A value of type 'Future<B?>' can't be returned from an async function with return type 'FutureOr<A>'.
+ final asy::Future<self::B?> #t14 = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:45:18: Error: A value of type 'Future<B?>' can't be returned from an async function with return type 'FutureOr<A>'.
- 'Future' is from 'dart:async'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return new Future<B?>.value(x); // Error.
^" in asy::Future::value<self::B?>(x) as{TypeError,ForNonNullableByDefault} self::A;
+ if(#t14 is asy::Future<self::A>) {
+ [yield] let dynamic #t16 = asy::_awaitHelper(#t14, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<self::B?>(:result);
+ }
+ else {
+ :async_temporary_2 = #t14;
+ }
+ :return_value = :async_temporary_2;
break #L4;
}
}
@@ -314,20 +335,20 @@
:is_sync = true;
return :async_future;
}
- return let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:49:10: Error: A value of type 'B?' can't be returned from a function with return type 'A' because 'B?' is nullable and 'A' isn't.
+ return let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:49:10: Error: A value of type 'B?' can't be returned from a function with return type 'A' because 'B?' is nullable and 'A' isn't.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return x; // Error.
- ^" in let self::B? #t14 = x in #t14.==(null) ?{self::A} #t14 as{TypeError,ForNonNullableByDefault} self::A : #t14{self::A};
+ ^" in let self::B? #t18 = x in #t18.==(null) ?{self::A} #t18 as{TypeError,ForNonNullableByDefault} self::A : #t18{self::A};
}
static method bar(core::List<self::B?> x, core::List<core::List<self::B?>> l, core::Map<core::List<self::B?>, core::List<self::B?>> m) → core::List<self::A> {
- self::barContext(let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:53:14: Error: The argument type 'List<B?>' can't be assigned to the parameter type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ self::barContext(let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:53:14: Error: The argument type 'List<B?>' can't be assigned to the parameter type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
barContext(x); // Error.
^" in x as{TypeError,ForNonNullableByDefault} core::List<self::A>);
- core::List<self::A> y = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:54:15: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ core::List<self::A> y = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:54:15: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
@@ -353,19 +374,19 @@
{
core::Iterator<core::List<self::B?>> :sync-for-iterator = l.{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final core::List<self::B?> #t17 = :sync-for-iterator.{core::Iterator::current};
+ final core::List<self::B?> #t21 = :sync-for-iterator.{core::Iterator::current};
{
- core::List<self::A> y = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:57:16: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ core::List<self::A> y = let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:57:16: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
Try changing the type of the variable.
for (List<A> y in l) {} // Error.
- ^" in #t17 as{TypeError,ForNonNullableByDefault} core::List<self::A>;
+ ^" in #t21 as{TypeError,ForNonNullableByDefault} core::List<self::A>;
}
}
}
- return let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:58:10: Error: A value of type 'List<B?>' can't be returned from a function with return type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ return let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:58:10: Error: A value of type 'List<B?>' can't be returned from a function with return type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
@@ -373,38 +394,38 @@
^" in x as{TypeError,ForNonNullableByDefault} core::List<self::A>;
}
static method baz(self::C c) → void {
- self::bazContext(let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:62:14: Error: The argument type 'num? Function()' can't be assigned to the parameter type 'num Function()' because 'num?' is nullable and 'num' isn't.
+ self::bazContext(let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:62:14: Error: The argument type 'num? Function()' can't be assigned to the parameter type 'num Function()' because 'num?' is nullable and 'num' isn't.
bazContext(c);
- ^" in (let final self::C #t21 = c in #t21.==(null) ?{() → core::num?} null : #t21.{self::C::call}) as{TypeError,ForNonNullableByDefault} () → core::num);
+ ^" in (let final self::C #t25 = c in #t25.==(null) ?{() → core::num?} null : #t25.{self::C::call}) as{TypeError,ForNonNullableByDefault} () → core::num);
}
static method boz(Null x) → self::A {
- self::fooContext(let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:66:14: Error: The argument type 'Null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
+ self::fooContext(let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:66:14: Error: The argument type 'Null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
fooContext(x); // Error.
- ^" in let Null #t23 = x in #t23.==(null) ?{self::A} #t23 as{TypeError,ForNonNullableByDefault} self::A : #t23{self::A});
- self::fooContext(let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:67:14: Error: The value 'null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
+ ^" in let Null #t27 = x in #t27.==(null) ?{self::A} #t27 as{TypeError,ForNonNullableByDefault} self::A : #t27{self::A});
+ self::fooContext(let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:67:14: Error: The value 'null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
fooContext(null); // Error.
- ^" in let Null #t25 = null in #t25.==(null) ?{self::A} #t25 as{TypeError,ForNonNullableByDefault} self::A : #t25{self::A});
- self::A a1 = let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:68:10: Error: A value of type 'Null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
+ ^" in let Null #t29 = null in #t29.==(null) ?{self::A} #t29 as{TypeError,ForNonNullableByDefault} self::A : #t29{self::A});
+ self::A a1 = let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:68:10: Error: A value of type 'Null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
A a1 = x; // Error.
- ^" in let Null #t27 = x in #t27.==(null) ?{self::A} #t27 as{TypeError,ForNonNullableByDefault} self::A : #t27{self::A};
- self::A a2 = let final<BottomType> #t28 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:69:10: Error: The value 'null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
+ ^" in let Null #t31 = x in #t31.==(null) ?{self::A} #t31 as{TypeError,ForNonNullableByDefault} self::A : #t31{self::A};
+ self::A a2 = let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:69:10: Error: The value 'null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
A a2 = null; // Error.
- ^" in let Null #t29 = null in #t29.==(null) ?{self::A} #t29 as{TypeError,ForNonNullableByDefault} self::A : #t29{self::A};
+ ^" in let Null #t33 = null in #t33.==(null) ?{self::A} #t33 as{TypeError,ForNonNullableByDefault} self::A : #t33{self::A};
if(true) {
- return let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:71:12: Error: A value of type 'Null' can't be returned from a function with return type 'A' because 'A' is not nullable.
+ return let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:71:12: Error: A value of type 'Null' can't be returned from a function with return type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return x; // Error.
- ^" in let Null #t31 = x in #t31.==(null) ?{self::A} #t31 as{TypeError,ForNonNullableByDefault} self::A : #t31{self::A};
+ ^" in let Null #t35 = x in #t35.==(null) ?{self::A} #t35 as{TypeError,ForNonNullableByDefault} self::A : #t35{self::A};
}
else {
- return let final<BottomType> #t32 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:73:12: Error: The value 'null' can't be returned from a function with return type 'A' because 'A' is not nullable.
+ return let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:73:12: Error: The value 'null' can't be returned from a function with return type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return null; // Error.
- ^" in let Null #t33 = null in #t33.==(null) ?{self::A} #t33 as{TypeError,ForNonNullableByDefault} self::A : #t33{self::A};
+ ^" in let Null #t37 = null in #t37.==(null) ?{self::A} #t37 as{TypeError,ForNonNullableByDefault} self::A : #t37{self::A};
}
function local() → FutureOr<self::A> /* originally async */ {
final asy::_Future<self::A> :async_future = new asy::_Future::•<self::A>();
@@ -414,23 +435,43 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<self::A>:async_temporary_0;
+ FutureOr<self::A>:async_temporary_1;
+ FutureOr<self::A>:async_temporary_2;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L5:
{
if(true) {
- :return_value = let final<BottomType> #t34 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:77:14: Error: The value 'null' can't be returned from an async function with return type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
+ final Null #t38 = let final<BottomType> #t39 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:77:14: Error: The value 'null' can't be returned from an async function with return type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return null; // Error.
- ^" in let Null #t35 = null in #t35.==(null) ?{self::A} #t35 as{TypeError,ForNonNullableByDefault} self::A : #t35{self::A};
+ ^" in let Null #t40 = null in #t40.==(null) ?{self::A} #t40 as{TypeError,ForNonNullableByDefault} self::A : #t40{self::A};
+ if(#t38 is asy::Future<self::A>) {
+ [yield] let dynamic #t41 = asy::_awaitHelper(#t38, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Null>(:result);
+ }
+ else {
+ :async_temporary_0 = #t38;
+ }
+ :return_value = :async_temporary_0;
break #L5;
}
else {
- :return_value = let final<BottomType> #t36 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:79:18: Error: A value of type 'Future<Null>' can't be returned from an async function with return type 'FutureOr<A>'.
+ final asy::Future<Null> #t42 = let final<BottomType> #t43 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:79:18: Error: A value of type 'Future<Null>' can't be returned from an async function with return type 'FutureOr<A>'.
- 'Future' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return new Future<Null>.value(null); // Error.
^" in asy::Future::value<Null>(null) as{TypeError,ForNonNullableByDefault} self::A;
+ if(#t42 is asy::Future<self::A>) {
+ [yield] let dynamic #t44 = asy::_awaitHelper(#t42, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<Null>(:result);
+ }
+ else {
+ :async_temporary_2 = #t42;
+ }
+ :return_value = :async_temporary_2;
break #L5;
}
}
@@ -466,7 +507,7 @@
Evaluated: MethodInvocation @ org-dartlang-testcase:///assignability_error_messages.dart:77:14 -> BoolConstant(true)
Evaluated: VariableGet @ org-dartlang-testcase:///assignability_error_messages.dart:77:14 -> NullConstant(null)
Evaluated: VariableGet @ org-dartlang-testcase:///assignability_error_messages.dart:77:14 -> NullConstant(null)
-Extra constant evaluation: evaluated: 210, effectively constant: 12
+Extra constant evaluation: evaluated: 266, effectively constant: 12
Constructor coverage from constants:
diff --git a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.expect b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.expect
index 0e66be9..6769397 100644
--- a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.expect
@@ -263,35 +263,35 @@
}
function local() → FutureOr<self::A> async {
if(true) {
- return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:43:14: Error: A value of type 'B?' can't be returned from an async function with return type 'FutureOr<A>' because 'B?' is nullable and 'FutureOr<A>' isn't.
+ return let final self::B? #t6 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:43:14: Error: A value of type 'B?' can't be returned from an async function with return type 'FutureOr<A>' because 'B?' is nullable and 'FutureOr<A>' isn't.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return x; // Error.
- ^" in x as{TypeError,ForNonNullableByDefault} self::A;
+ ^" in x as{TypeError,ForNonNullableByDefault} self::A in #t6 is asy::Future<self::A> ?{FutureOr<self::A>} await #t6 : #t6;
}
else {
- return let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:45:18: Error: A value of type 'Future<B?>' can't be returned from an async function with return type 'FutureOr<A>'.
+ return let final asy::Future<self::B?> #t8 = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:45:18: Error: A value of type 'Future<B?>' can't be returned from an async function with return type 'FutureOr<A>'.
- 'Future' is from 'dart:async'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return new Future<B?>.value(x); // Error.
- ^" in asy::Future::value<self::B?>(x) as{TypeError,ForNonNullableByDefault} self::A;
+ ^" in asy::Future::value<self::B?>(x) as{TypeError,ForNonNullableByDefault} self::A in #t8 is asy::Future<self::A> ?{FutureOr<self::A>} await #t8 : #t8;
}
}
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:49:10: Error: A value of type 'B?' can't be returned from a function with return type 'A' because 'B?' is nullable and 'A' isn't.
+ return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:49:10: Error: A value of type 'B?' can't be returned from a function with return type 'A' because 'B?' is nullable and 'A' isn't.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return x; // Error.
^" in x as{TypeError,ForNonNullableByDefault} self::A;
}
static method bar(core::List<self::B?> x, core::List<core::List<self::B?>> l, core::Map<core::List<self::B?>, core::List<self::B?>> m) → core::List<self::A> {
- self::barContext(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:53:14: Error: The argument type 'List<B?>' can't be assigned to the parameter type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ self::barContext(let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:53:14: Error: The argument type 'List<B?>' can't be assigned to the parameter type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
barContext(x); // Error.
^" in x as{TypeError,ForNonNullableByDefault} core::List<self::A>);
- core::List<self::A> y = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:54:15: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ core::List<self::A> y = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:54:15: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
@@ -314,16 +314,16 @@
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
<List<A>, List<A>>{...m}; // Error.
^"};
- for (final core::List<self::B?> #t11 in l) {
- core::List<self::A> y = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:57:16: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ for (final core::List<self::B?> #t13 in l) {
+ core::List<self::A> y = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:57:16: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
Try changing the type of the variable.
for (List<A> y in l) {} // Error.
- ^" in #t11 as{TypeError,ForNonNullableByDefault} core::List<self::A>;
+ ^" in #t13 as{TypeError,ForNonNullableByDefault} core::List<self::A>;
}
- return let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:58:10: Error: A value of type 'List<B?>' can't be returned from a function with return type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ return let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:58:10: Error: A value of type 'List<B?>' can't be returned from a function with return type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
@@ -331,52 +331,52 @@
^" in x as{TypeError,ForNonNullableByDefault} core::List<self::A>;
}
static method baz(self::C c) → void {
- self::bazContext(let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:62:14: Error: The argument type 'num? Function()' can't be assigned to the parameter type 'num Function()' because 'num?' is nullable and 'num' isn't.
+ self::bazContext(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:62:14: Error: The argument type 'num? Function()' can't be assigned to the parameter type 'num Function()' because 'num?' is nullable and 'num' isn't.
bazContext(c);
- ^" in (let final self::C #t15 = c in #t15.==(null) ?{() → core::num?} null : #t15.{self::C::call}) as{TypeError,ForNonNullableByDefault} () → core::num);
+ ^" in (let final self::C #t17 = c in #t17.==(null) ?{() → core::num?} null : #t17.{self::C::call}) as{TypeError,ForNonNullableByDefault} () → core::num);
}
static method boz(Null x) → self::A {
- self::fooContext(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:66:14: Error: The argument type 'Null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
+ self::fooContext(let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:66:14: Error: The argument type 'Null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
fooContext(x); // Error.
^" in x as{TypeError,ForNonNullableByDefault} self::A);
- self::fooContext(let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:67:14: Error: The value 'null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
+ self::fooContext(let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:67:14: Error: The value 'null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
fooContext(null); // Error.
^" in null as{TypeError,ForNonNullableByDefault} self::A);
- self::A a1 = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:68:10: Error: A value of type 'Null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
+ self::A a1 = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:68:10: Error: A value of type 'Null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
A a1 = x; // Error.
^" in x as{TypeError,ForNonNullableByDefault} self::A;
- self::A a2 = let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:69:10: Error: The value 'null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
+ self::A a2 = let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:69:10: Error: The value 'null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
A a2 = null; // Error.
^" in null as{TypeError,ForNonNullableByDefault} self::A;
if(true) {
- return let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:71:12: Error: A value of type 'Null' can't be returned from a function with return type 'A' because 'A' is not nullable.
+ return let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:71:12: Error: A value of type 'Null' can't be returned from a function with return type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return x; // Error.
^" in x as{TypeError,ForNonNullableByDefault} self::A;
}
else {
- return let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:73:12: Error: The value 'null' can't be returned from a function with return type 'A' because 'A' is not nullable.
+ return let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:73:12: Error: The value 'null' can't be returned from a function with return type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return null; // Error.
^" in null as{TypeError,ForNonNullableByDefault} self::A;
}
function local() → FutureOr<self::A> async {
if(true) {
- return let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:77:14: Error: The value 'null' can't be returned from an async function with return type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
+ return let final Null #t24 = let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:77:14: Error: The value 'null' can't be returned from an async function with return type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return null; // Error.
- ^" in null as{TypeError,ForNonNullableByDefault} self::A;
+ ^" in null as{TypeError,ForNonNullableByDefault} self::A in #t24 is asy::Future<self::A> ?{FutureOr<self::A>} await #t24 : #t24;
}
else {
- return let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:79:18: Error: A value of type 'Future<Null>' can't be returned from an async function with return type 'FutureOr<A>'.
+ return let final asy::Future<Null> #t26 = let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:79:18: Error: A value of type 'Future<Null>' can't be returned from an async function with return type 'FutureOr<A>'.
- 'Future' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return new Future<Null>.value(null); // Error.
- ^" in asy::Future::value<Null>(null) as{TypeError,ForNonNullableByDefault} self::A;
+ ^" in asy::Future::value<Null>(null) as{TypeError,ForNonNullableByDefault} self::A in #t26 is asy::Future<self::A> ?{FutureOr<self::A>} await #t26 : #t26;
}
}
}
diff --git a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.transformed.expect
index 4ba3fa1..242b2b4 100644
--- a/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/assignability_error_messages.dart.weak.transformed.expect
@@ -180,6 +180,7 @@
import self as self;
import "dart:core" as core;
import "dart:async" as asy;
+import "dart:_internal" as _in;
import "dart:async";
@@ -280,25 +281,45 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<self::A>:async_temporary_0;
+ FutureOr<self::A>:async_temporary_1;
+ FutureOr<self::A>:async_temporary_2;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
{
if(true) {
- :return_value = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:43:14: Error: A value of type 'B?' can't be returned from an async function with return type 'FutureOr<A>' because 'B?' is nullable and 'FutureOr<A>' isn't.
+ final self::B? #t6 = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:43:14: Error: A value of type 'B?' can't be returned from an async function with return type 'FutureOr<A>' because 'B?' is nullable and 'FutureOr<A>' isn't.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return x; // Error.
^" in x;
+ if(#t6 is asy::Future<self::A>) {
+ [yield] let dynamic #t8 = asy::_awaitHelper(#t6, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<self::B?>(:result);
+ }
+ else {
+ :async_temporary_0 = #t6;
+ }
+ :return_value = :async_temporary_0;
break #L4;
}
else {
- :return_value = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:45:18: Error: A value of type 'Future<B?>' can't be returned from an async function with return type 'FutureOr<A>'.
+ final asy::Future<self::B?> #t9 = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:45:18: Error: A value of type 'Future<B?>' can't be returned from an async function with return type 'FutureOr<A>'.
- 'Future' is from 'dart:async'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return new Future<B?>.value(x); // Error.
^" in asy::Future::value<self::B?>(x) as{TypeError,ForNonNullableByDefault} self::A;
+ if(#t9 is asy::Future<self::A>) {
+ [yield] let dynamic #t11 = asy::_awaitHelper(#t9, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<self::B?>(:result);
+ }
+ else {
+ :async_temporary_2 = #t9;
+ }
+ :return_value = :async_temporary_2;
break #L4;
}
}
@@ -314,20 +335,20 @@
:is_sync = true;
return :async_future;
}
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:49:10: Error: A value of type 'B?' can't be returned from a function with return type 'A' because 'B?' is nullable and 'A' isn't.
+ return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:49:10: Error: A value of type 'B?' can't be returned from a function with return type 'A' because 'B?' is nullable and 'A' isn't.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return x; // Error.
^" in x;
}
static method bar(core::List<self::B?> x, core::List<core::List<self::B?>> l, core::Map<core::List<self::B?>, core::List<self::B?>> m) → core::List<self::A> {
- self::barContext(let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:53:14: Error: The argument type 'List<B?>' can't be assigned to the parameter type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ self::barContext(let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:53:14: Error: The argument type 'List<B?>' can't be assigned to the parameter type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
barContext(x); // Error.
^" in x);
- core::List<self::A> y = let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:54:15: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ core::List<self::A> y = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:54:15: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
@@ -353,19 +374,19 @@
{
core::Iterator<core::List<self::B?>> :sync-for-iterator = l.{core::Iterable::iterator};
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
- final core::List<self::B?> #t11 = :sync-for-iterator.{core::Iterator::current};
+ final core::List<self::B?> #t15 = :sync-for-iterator.{core::Iterator::current};
{
- core::List<self::A> y = let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:57:16: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ core::List<self::A> y = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:57:16: Error: A value of type 'List<B?>' can't be assigned to a variable of type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
Try changing the type of the variable.
for (List<A> y in l) {} // Error.
- ^" in #t11;
+ ^" in #t15;
}
}
}
- return let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:58:10: Error: A value of type 'List<B?>' can't be returned from a function with return type 'List<A>' because 'B?' is nullable and 'A' isn't.
+ return let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:58:10: Error: A value of type 'List<B?>' can't be returned from a function with return type 'List<A>' because 'B?' is nullable and 'A' isn't.
- 'List' is from 'dart:core'.
- 'B' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
@@ -373,35 +394,35 @@
^" in x;
}
static method baz(self::C c) → void {
- self::bazContext(let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:62:14: Error: The argument type 'num? Function()' can't be assigned to the parameter type 'num Function()' because 'num?' is nullable and 'num' isn't.
+ self::bazContext(let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:62:14: Error: The argument type 'num? Function()' can't be assigned to the parameter type 'num Function()' because 'num?' is nullable and 'num' isn't.
bazContext(c);
- ^" in let final self::C #t15 = c in #t15.==(null) ?{() → core::num?} null : #t15.{self::C::call});
+ ^" in let final self::C #t19 = c in #t19.==(null) ?{() → core::num?} null : #t19.{self::C::call});
}
static method boz(Null x) → self::A {
- self::fooContext(let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:66:14: Error: The argument type 'Null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
+ self::fooContext(let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:66:14: Error: The argument type 'Null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
fooContext(x); // Error.
^" in x);
- self::fooContext(let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:67:14: Error: The value 'null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
+ self::fooContext(let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:67:14: Error: The value 'null' can't be assigned to the parameter type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
fooContext(null); // Error.
^" in null);
- self::A a1 = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:68:10: Error: A value of type 'Null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
+ self::A a1 = let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:68:10: Error: A value of type 'Null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
A a1 = x; // Error.
^" in x;
- self::A a2 = let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:69:10: Error: The value 'null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
+ self::A a2 = let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:69:10: Error: The value 'null' can't be assigned to a variable of type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
A a2 = null; // Error.
^" in null;
if(true) {
- return let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:71:12: Error: A value of type 'Null' can't be returned from a function with return type 'A' because 'A' is not nullable.
+ return let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:71:12: Error: A value of type 'Null' can't be returned from a function with return type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return x; // Error.
^" in x;
}
else {
- return let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:73:12: Error: The value 'null' can't be returned from a function with return type 'A' because 'A' is not nullable.
+ return let final<BottomType> #t25 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:73:12: Error: The value 'null' can't be returned from a function with return type 'A' because 'A' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return null; // Error.
^" in null;
@@ -414,23 +435,43 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<self::A>:async_temporary_0;
+ FutureOr<self::A>:async_temporary_1;
+ FutureOr<self::A>:async_temporary_2;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L5:
{
if(true) {
- :return_value = let final<BottomType> #t22 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:77:14: Error: The value 'null' can't be returned from an async function with return type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
+ final Null #t26 = let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:77:14: Error: The value 'null' can't be returned from an async function with return type 'FutureOr<A>' because 'FutureOr<A>' is not nullable.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return null; // Error.
^" in null;
+ if(#t26 is asy::Future<self::A>) {
+ [yield] let dynamic #t28 = asy::_awaitHelper(#t26, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Null>(:result);
+ }
+ else {
+ :async_temporary_0 = #t26;
+ }
+ :return_value = :async_temporary_0;
break #L5;
}
else {
- :return_value = let final<BottomType> #t23 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:79:18: Error: A value of type 'Future<Null>' can't be returned from an async function with return type 'FutureOr<A>'.
+ final asy::Future<Null> #t29 = let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/assignability_error_messages.dart:79:18: Error: A value of type 'Future<Null>' can't be returned from an async function with return type 'FutureOr<A>'.
- 'Future' is from 'dart:async'.
- 'A' is from 'pkg/front_end/testcases/nnbd/assignability_error_messages.dart'.
return new Future<Null>.value(null); // Error.
^" in asy::Future::value<Null>(null) as{TypeError,ForNonNullableByDefault} self::A;
+ if(#t29 is asy::Future<self::A>) {
+ [yield] let dynamic #t31 = asy::_awaitHelper(#t29, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<Null>(:result);
+ }
+ else {
+ :async_temporary_2 = #t29;
+ }
+ :return_value = :async_temporary_2;
break #L5;
}
}
diff --git a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.expect b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.expect
index f39bdfbd..bda20dd 100644
--- a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.strong.expect
@@ -21,7 +21,7 @@
else {
throw core::Exception::•("Invalid response type");
}
- return result;
+ return let final self::TestMixin::T% #t1 = result in #t1 is asy::Future<self::TestMixin::T%> ?{FutureOr<self::TestMixin::T%>} await #t1 : #t1;
}
}
class PagingResponse<T extends core::Object? = dynamic> extends core::Object {
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 76b3473..e23e8dd 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
@@ -14,6 +14,7 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<self::TestMixin::T%>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
@@ -35,7 +36,15 @@
else {
throw core::Exception::•("Invalid response type");
}
- :return_value = result;
+ final self::TestMixin::T% #t2 = result;
+ if(#t2 is asy::Future<self::TestMixin::T%>) {
+ [yield] let dynamic #t3 = asy::_awaitHelper(#t2, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<self::TestMixin::T%>(:result);
+ }
+ else {
+ :async_temporary_0 = #t2;
+ }
+ :return_value = :async_temporary_0;
break #L1;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -82,11 +91,12 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L2:
{
- [yield] let dynamic #t2 = asy::_awaitHelper(fetch, :async_op_then, :async_op_error, :async_op) in null;
+ [yield] let dynamic #t4 = asy::_awaitHelper(fetch, :async_op_then, :async_op_error, :async_op) in null;
final self::Response<core::String> response = _in::unsafeCast<self::Response<core::String>>(:result);
core::String result;
if(response is{ForNonNullableByDefault} self::Response<dynamic>) {
@@ -103,7 +113,15 @@
else {
throw core::Exception::•("Invalid response type");
}
- :return_value = result;
+ final core::String #t5 = result;
+ if(#t5 is asy::Future<core::String>) {
+ [yield] let dynamic #t6 = asy::_awaitHelper(#t5, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::String>(:result);
+ }
+ else {
+ :async_temporary_0 = #t5;
+ }
+ :return_value = :async_temporary_0;
break #L2;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -141,11 +159,12 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L3:
{
- [yield] let dynamic #t3 = asy::_awaitHelper(fetch, :async_op_then, :async_op_error, :async_op) in null;
+ [yield] let dynamic #t7 = asy::_awaitHelper(fetch, :async_op_then, :async_op_error, :async_op) in null;
final self::PagingResponse<core::String> response = _in::unsafeCast<self::PagingResponse<core::String>>(:result);
core::String result;
if(response is{ForNonNullableByDefault} self::Response<dynamic>) {
@@ -162,7 +181,15 @@
else {
throw core::Exception::•("Invalid response type");
}
- :return_value = result;
+ final core::String #t8 = result;
+ if(#t8 is asy::Future<core::String>) {
+ [yield] let dynamic #t9 = asy::_awaitHelper(#t8, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::String>(:result);
+ }
+ else {
+ :async_temporary_0 = #t8;
+ }
+ :return_value = :async_temporary_0;
break #L3;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
diff --git a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.expect b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.expect
index f39bdfbd..bda20dd 100644
--- a/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/flutter_issue64155.dart.weak.expect
@@ -21,7 +21,7 @@
else {
throw core::Exception::•("Invalid response type");
}
- return result;
+ return let final self::TestMixin::T% #t1 = result in #t1 is asy::Future<self::TestMixin::T%> ?{FutureOr<self::TestMixin::T%>} await #t1 : #t1;
}
}
class PagingResponse<T extends core::Object? = dynamic> extends core::Object {
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 76b3473..e23e8dd 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
@@ -14,6 +14,7 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<self::TestMixin::T%>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
@@ -35,7 +36,15 @@
else {
throw core::Exception::•("Invalid response type");
}
- :return_value = result;
+ final self::TestMixin::T% #t2 = result;
+ if(#t2 is asy::Future<self::TestMixin::T%>) {
+ [yield] let dynamic #t3 = asy::_awaitHelper(#t2, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<self::TestMixin::T%>(:result);
+ }
+ else {
+ :async_temporary_0 = #t2;
+ }
+ :return_value = :async_temporary_0;
break #L1;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -82,11 +91,12 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L2:
{
- [yield] let dynamic #t2 = asy::_awaitHelper(fetch, :async_op_then, :async_op_error, :async_op) in null;
+ [yield] let dynamic #t4 = asy::_awaitHelper(fetch, :async_op_then, :async_op_error, :async_op) in null;
final self::Response<core::String> response = _in::unsafeCast<self::Response<core::String>>(:result);
core::String result;
if(response is{ForNonNullableByDefault} self::Response<dynamic>) {
@@ -103,7 +113,15 @@
else {
throw core::Exception::•("Invalid response type");
}
- :return_value = result;
+ final core::String #t5 = result;
+ if(#t5 is asy::Future<core::String>) {
+ [yield] let dynamic #t6 = asy::_awaitHelper(#t5, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::String>(:result);
+ }
+ else {
+ :async_temporary_0 = #t5;
+ }
+ :return_value = :async_temporary_0;
break #L2;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -141,11 +159,12 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L3:
{
- [yield] let dynamic #t3 = asy::_awaitHelper(fetch, :async_op_then, :async_op_error, :async_op) in null;
+ [yield] let dynamic #t7 = asy::_awaitHelper(fetch, :async_op_then, :async_op_error, :async_op) in null;
final self::PagingResponse<core::String> response = _in::unsafeCast<self::PagingResponse<core::String>>(:result);
core::String result;
if(response is{ForNonNullableByDefault} self::Response<dynamic>) {
@@ -162,7 +181,15 @@
else {
throw core::Exception::•("Invalid response type");
}
- :return_value = result;
+ final core::String #t8 = result;
+ if(#t8 is asy::Future<core::String>) {
+ [yield] let dynamic #t9 = asy::_awaitHelper(#t8, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::String>(:result);
+ }
+ else {
+ :async_temporary_0 = #t8;
+ }
+ :return_value = :async_temporary_0;
break #L3;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.strong.expect
index 11217a1..ca6b488 100644
--- a/pkg/front_end/testcases/nnbd/issue41156.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.strong.expect
@@ -55,19 +55,19 @@
(core::int) → core::String x6 = (core::int v) → Never {
return self::throwing();
};
- (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> async => throw v;
+ (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> async => let final Never #t1 = throw v in #t1 is asy::Future<Never> ?{FutureOr<core::String>} await #t1 : #t1;
(core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> async {
throw v;
};
(core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> async {
- return throw v;
+ return let final Never #t2 = throw v in #t2 is asy::Future<Never> ?{FutureOr<core::String>} await #t2 : #t2;
};
- (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> async => self::throwing();
+ (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> async => let final Never #t3 = self::throwing() in #t3 is asy::Future<Never> ?{FutureOr<core::String>} await #t3 : #t3;
(core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> async {
self::throwing();
};
(core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> async {
- return self::throwing();
+ return let final Never #t4 = self::throwing() in #t4 is asy::Future<Never> ?{FutureOr<core::String>} await #t4 : #t4;
};
}
static method errors() → void async {
@@ -77,7 +77,7 @@
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:39:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:39:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x2 = (int v) /* error */ {
^" in null;
};
@@ -87,7 +87,7 @@
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:44:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:44:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x3 = (int v) /* error */ {
^" in null;
};
@@ -97,7 +97,7 @@
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:49:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:49:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x5 = (int v) /* error */ {
^" in null;
};
@@ -107,7 +107,7 @@
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:54:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:54:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x6 = (int v) /* error */ {
^" in null;
};
@@ -117,17 +117,17 @@
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:59:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:59:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y2 = (int v) async /* error */ {
^" in null;
};
(core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<core::String> async {
try {
- return throw v;
+ return let final Never #t10 = throw v in #t10 is asy::Future<core::String> ?{FutureOr<core::String>} await #t10 : #t10;
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:64:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:64:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y3 = (int v) async /* error */ {
^" in null;
};
@@ -137,17 +137,17 @@
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:69:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:69:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y5 = (int v) async /* error */ {
^" in null;
};
(core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<core::String> async {
try {
- return self::throwing();
+ return let final Never #t13 = self::throwing() in #t13 is asy::Future<core::String> ?{FutureOr<core::String>} await #t13 : #t13;
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:74:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:74:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y6 = (int v) async /* error */ {
^" in null;
};
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 3e9bef1..515ceec 100644
--- a/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.strong.transformed.expect
@@ -37,6 +37,7 @@
import self as self;
import "dart:core" as core;
import "dart:async" as asy;
+import "dart:_internal" as _in;
static method throwing() → Never
return throw "";
@@ -63,11 +64,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
{
- :return_value = throw v;
+ final Never #t1 = throw v;
+ if(#t1 is asy::Future<Never>) {
+ [yield] let dynamic #t2 = asy::_awaitHelper(#t1, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Never>(:result);
+ }
+ else {
+ :async_temporary_0 = #t1;
+ }
+ :return_value = :async_temporary_0;
break #L1;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -116,11 +127,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L3:
{
- :return_value = throw v;
+ final Never #t3 = throw v;
+ if(#t3 is asy::Future<Never>) {
+ [yield] let dynamic #t4 = asy::_awaitHelper(#t3, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Never>(:result);
+ }
+ else {
+ :async_temporary_0 = #t3;
+ }
+ :return_value = :async_temporary_0;
break #L3;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -143,11 +164,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
{
- :return_value = self::throwing();
+ final Never #t5 = self::throwing();
+ if(#t5 is asy::Future<Never>) {
+ [yield] let dynamic #t6 = asy::_awaitHelper(#t5, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Never>(:result);
+ }
+ else {
+ :async_temporary_0 = #t5;
+ }
+ :return_value = :async_temporary_0;
break #L4;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -196,11 +227,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L6:
{
- :return_value = self::throwing();
+ final Never #t7 = self::throwing();
+ if(#t7 is asy::Future<Never>) {
+ [yield] let dynamic #t8 = asy::_awaitHelper(#t7, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Never>(:result);
+ }
+ else {
+ :async_temporary_0 = #t7;
+ }
+ :return_value = :async_temporary_0;
break #L6;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -234,7 +275,7 @@
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:39:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:39:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x2 = (int v) /* error */ {
^" in null;
};
@@ -244,7 +285,7 @@
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:44:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:44:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x3 = (int v) /* error */ {
^" in null;
};
@@ -254,7 +295,7 @@
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:49:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:49:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x5 = (int v) /* error */ {
^" in null;
};
@@ -264,7 +305,7 @@
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:54:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:54:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x6 = (int v) /* error */ {
^" in null;
};
@@ -285,7 +326,7 @@
}
on core::Object catch(final core::Object _) {
}
- :return_value = let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:59:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ :return_value = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:59:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y2 = (int v) async /* error */ {
^" in null;
break #L8;
@@ -310,17 +351,28 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L9:
{
try {
- :return_value = throw v;
+ final Never #t14 = throw v;
+ if(#t14 is asy::Future<core::String>) {
+ [yield] let dynamic #t15 = asy::_awaitHelper(#t14, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Never>(:result);
+ }
+ else {
+ :async_temporary_0 = #t14;
+ }
+ :return_value = :async_temporary_0;
break #L9;
}
on core::Object catch(final core::Object _) {
}
- :return_value = let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:64:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ :return_value = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:64:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y3 = (int v) async /* error */ {
^" in null;
break #L9;
@@ -354,7 +406,7 @@
}
on core::Object catch(final core::Object _) {
}
- :return_value = let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:69:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ :return_value = let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:69:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y5 = (int v) async /* error */ {
^" in null;
break #L10;
@@ -379,17 +431,28 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L11:
{
try {
- :return_value = self::throwing();
+ final Never #t18 = self::throwing();
+ if(#t18 is asy::Future<core::String>) {
+ [yield] let dynamic #t19 = asy::_awaitHelper(#t18, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Never>(:result);
+ }
+ else {
+ :async_temporary_0 = #t18;
+ }
+ :return_value = :async_temporary_0;
break #L11;
}
on core::Object catch(final core::Object _) {
}
- :return_value = let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:74:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ :return_value = let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:74:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y6 = (int v) async /* error */ {
^" in null;
break #L11;
diff --git a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.expect
index 3ced126..344471e 100644
--- a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.expect
@@ -56,19 +56,19 @@
(core::int) → core::String x6 = (core::int v) → Never {
return let final Never #t3 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
};
- (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> async => throw v;
+ (core::int) → asy::Future<core::String> y1 = (core::int v) → asy::Future<Never> async => let final Never #t4 = throw v in #t4 is asy::Future<Never> ?{FutureOr<core::String>} await #t4 : #t4;
(core::int) → asy::Future<core::String> y2 = (core::int v) → asy::Future<Never> async {
throw v;
};
(core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<Never> async {
- return throw v;
+ return let final Never #t5 = throw v in #t5 is asy::Future<Never> ?{FutureOr<core::String>} await #t5 : #t5;
};
- (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> async => let final Never #t4 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ (core::int) → asy::Future<core::String> y4 = (core::int v) → asy::Future<Never> async => let final Never #t6 = let final Never #t7 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in #t6 is asy::Future<Never> ?{FutureOr<core::String>} await #t6 : #t6;
(core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<Never> async {
- let final Never #t5 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ let final Never #t8 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
};
(core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<Never> async {
- return let final Never #t6 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ return let final Never #t9 = let final Never #t10 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in #t9 is asy::Future<Never> ?{FutureOr<core::String>} await #t9 : #t9;
};
}
static method errors() → void async {
@@ -78,7 +78,7 @@
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:39:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:39:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x2 = (int v) /* error */ {
^" in null;
};
@@ -88,27 +88,27 @@
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:44:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:44:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x3 = (int v) /* error */ {
^" in null;
};
(core::int) → core::String x5 = (core::int v) → core::String {
try {
- let final Never #t9 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ let final Never #t13 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:49:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:49:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x5 = (int v) /* error */ {
^" in null;
};
(core::int) → core::String x6 = (core::int v) → core::String {
try {
- return let final Never #t11 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ return let final Never #t15 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:54:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:54:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x6 = (int v) /* error */ {
^" in null;
};
@@ -118,37 +118,37 @@
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:59:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:59:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y2 = (int v) async /* error */ {
^" in null;
};
(core::int) → asy::Future<core::String> y3 = (core::int v) → asy::Future<core::String> async {
try {
- return throw v;
+ return let final Never #t18 = throw v in #t18 is asy::Future<core::String> ?{FutureOr<core::String>} await #t18 : #t18;
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:64:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t19 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:64:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y3 = (int v) async /* error */ {
^" in null;
};
(core::int) → asy::Future<core::String> y5 = (core::int v) → asy::Future<core::String> async {
try {
- let final Never #t15 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ let final Never #t20 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:69:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:69:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y5 = (int v) async /* error */ {
^" in null;
};
(core::int) → asy::Future<core::String> y6 = (core::int v) → asy::Future<core::String> async {
try {
- return let final Never #t17 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ return let final Never #t22 = let final Never #t23 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.") in #t22 is asy::Future<core::String> ?{FutureOr<core::String>} await #t22 : #t22;
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:74:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:74:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y6 = (int v) async /* error */ {
^" in null;
};
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 e3ff8f7..5ebb180 100644
--- a/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41156.dart.weak.transformed.expect
@@ -64,11 +64,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
{
- :return_value = throw v;
+ final Never #t4 = throw v;
+ if(#t4 is asy::Future<Never>) {
+ [yield] let dynamic #t5 = asy::_awaitHelper(#t4, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Never>(:result);
+ }
+ else {
+ :async_temporary_0 = #t4;
+ }
+ :return_value = :async_temporary_0;
break #L1;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -117,11 +127,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L3:
{
- :return_value = throw v;
+ final Never #t6 = throw v;
+ if(#t6 is asy::Future<Never>) {
+ [yield] let dynamic #t7 = asy::_awaitHelper(#t6, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Never>(:result);
+ }
+ else {
+ :async_temporary_0 = #t6;
+ }
+ :return_value = :async_temporary_0;
break #L3;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -144,11 +164,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
{
- :return_value = let final Never #t4 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ final Never #t8 = let final Never #t9 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ if(#t8 is asy::Future<Never>) {
+ [yield] let dynamic #t10 = asy::_awaitHelper(#t8, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Never>(:result);
+ }
+ else {
+ :async_temporary_0 = #t8;
+ }
+ :return_value = :async_temporary_0;
break #L4;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -175,7 +205,7 @@
try {
#L5:
{
- let final Never #t5 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ let final Never #t11 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
return;
@@ -197,11 +227,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L6:
{
- :return_value = let final Never #t6 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ final Never #t12 = let final Never #t13 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ if(#t12 is asy::Future<Never>) {
+ [yield] let dynamic #t14 = asy::_awaitHelper(#t12, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Never>(:result);
+ }
+ else {
+ :async_temporary_0 = #t12;
+ }
+ :return_value = :async_temporary_0;
break #L6;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -235,7 +275,7 @@
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:39:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:39:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x2 = (int v) /* error */ {
^" in null;
};
@@ -245,27 +285,27 @@
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:44:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:44:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x3 = (int v) /* error */ {
^" in null;
};
(core::int) → core::String x5 = (core::int v) → core::String {
try {
- let final Never #t9 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ let final Never #t17 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:49:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:49:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x5 = (int v) /* error */ {
^" in null;
};
(core::int) → core::String x6 = (core::int v) → core::String {
try {
- return let final Never #t11 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ return let final Never #t19 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
on core::Object catch(final core::Object _) {
}
- return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:54:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:54:29: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String Function(int) x6 = (int v) /* error */ {
^" in null;
};
@@ -286,7 +326,7 @@
}
on core::Object catch(final core::Object _) {
}
- :return_value = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:59:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ :return_value = let final<BottomType> #t21 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:59:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y2 = (int v) async /* error */ {
^" in null;
break #L8;
@@ -311,17 +351,28 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L9:
{
try {
- :return_value = throw v;
+ final Never #t22 = throw v;
+ if(#t22 is asy::Future<core::String>) {
+ [yield] let dynamic #t23 = asy::_awaitHelper(#t22, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Never>(:result);
+ }
+ else {
+ :async_temporary_0 = #t22;
+ }
+ :return_value = :async_temporary_0;
break #L9;
}
on core::Object catch(final core::Object _) {
}
- :return_value = let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:64:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ :return_value = let final<BottomType> #t24 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:64:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y3 = (int v) async /* error */ {
^" in null;
break #L9;
@@ -351,11 +402,11 @@
#L10:
{
try {
- let final Never #t15 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ let final Never #t25 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
}
on core::Object catch(final core::Object _) {
}
- :return_value = let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:69:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ :return_value = let final<BottomType> #t26 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:69:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y5 = (int v) async /* error */ {
^" in null;
break #L10;
@@ -380,17 +431,28 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ FutureOr<core::String>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L11:
{
try {
- :return_value = let final Never #t17 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ final Never #t27 = let final Never #t28 = self::throwing() in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+ if(#t27 is asy::Future<core::String>) {
+ [yield] let dynamic #t29 = asy::_awaitHelper(#t27, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Never>(:result);
+ }
+ else {
+ :async_temporary_0 = #t27;
+ }
+ :return_value = :async_temporary_0;
break #L11;
}
on core::Object catch(final core::Object _) {
}
- :return_value = let final<BottomType> #t18 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:74:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ :return_value = let final<BottomType> #t30 = invalid-expression "pkg/front_end/testcases/nnbd/issue41156.dart:74:37: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
Future<String> Function(int) y6 = (int v) async /* error */ {
^" in null;
break #L11;
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.expect
index fbcd99e..d7881ae 100644
--- a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.expect
@@ -34,61 +34,61 @@
static method getNull() → dynamic
return null;
static method getFutureNull() → asy::Future<dynamic> async {
- return null;
+ return let final Null #t1 = null in #t1 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t1 : #t1;
}
static method getFutureBool() → asy::Future<core::bool> async {
- return true;
+ return let final core::bool #t2 = true in #t2 is asy::Future<core::bool> ?{FutureOr<core::bool>} await #t2 : #t2;
}
static method test1() → asy::Future<core::bool> async
- return await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ return let final dynamic #t3 = await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool> in #t3 is asy::Future<core::bool> ?{FutureOr<core::bool>} await #t3 : #t3;
static method test2() → asy::Future<core::bool>
return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
static method test3() → core::bool
return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
static method test4() → asy::Future<core::bool> async
- return await self::getFutureNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ return let final dynamic #t4 = await self::getFutureNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool> in #t4 is asy::Future<core::bool> ?{FutureOr<core::bool>} await #t4 : #t4;
static method test5() → asy::Future<core::bool>
- return let final<BottomType> #t1 = 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>'.
+ return let final<BottomType> #t5 = 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>'.
- 'Future' is from 'dart:async'.
Future<bool> test5() => getFutureNull(); // error
^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
static method test6() → asy::Future<core::bool>
return self::getFutureBool();
static method test7() → asy::Future<core::bool> async
- return self::getFutureBool();
+ return let final asy::Future<core::bool> #t6 = self::getFutureBool() in #t6 is asy::Future<core::bool> ?{FutureOr<core::bool>} await #t6 : #t6;
static method test() → dynamic async {
function test1() → asy::Future<core::bool> async
- return await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ return let final dynamic #t7 = await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool> in #t7 is asy::Future<core::bool> ?{FutureOr<core::bool>} await #t7 : #t7;
function test2() → asy::Future<core::bool>
return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
function test3() → core::bool
return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
function test4() → asy::Future<core::bool> async
- return await self::getFutureNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ return let final dynamic #t8 = await self::getFutureNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool> in #t8 is asy::Future<core::bool> ?{FutureOr<core::bool>} await #t8 : #t8;
function test5() → asy::Future<core::bool>
- return let final<BottomType> #t2 = 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>'.
+ return let final<BottomType> #t9 = 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>'.
- 'Future' is from 'dart:async'.
Future<bool> test5() => getFutureNull(); // error
^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
function test6() → asy::Future<core::bool>
return self::getFutureBool();
function test7() → asy::Future<core::bool> async
- return self::getFutureBool();
- asy::Future<core::bool> var1 = let final<BottomType> #t3 = 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>'.
+ return let final asy::Future<core::bool> #t10 = self::getFutureBool() in #t10 is asy::Future<core::bool> ?{FutureOr<core::bool>} await #t10 : #t10;
+ asy::Future<core::bool> var1 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
- 'Future' is from 'dart:async'.
Future<bool> var1 = (() async => await getNull())(); // error
- ^" in (() → asy::Future<dynamic> async => await self::getNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ ^" in (() → asy::Future<dynamic> async => let final dynamic #t12 = await self::getNull() in #t12 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t12 : #t12).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;
- asy::Future<core::bool> var4 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ asy::Future<core::bool> var4 = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
- 'Future' is from 'dart:async'.
Future<bool> var4 = (() async => await getFutureNull())(); // error
- ^" in (() → asy::Future<dynamic> async => await self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
- asy::Future<core::bool> var5 = let final<BottomType> #t5 = 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>'.
+ ^" in (() → asy::Future<dynamic> async => let final dynamic #t14 = await self::getFutureNull() in #t14 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t14 : #t14).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ asy::Future<core::bool> var5 = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
- 'Future' is from 'dart:async'.
Future<bool> var5 = (() => getFutureNull())(); // error
^" in (() → asy::Future<dynamic> => self::getFutureNull()).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> async => self::getFutureBool()).call();
+ asy::Future<core::bool> var7 = (() → asy::Future<core::bool> async => let final asy::Future<core::bool> #t16 = self::getFutureBool() in #t16 is asy::Future<core::bool> ?{FutureOr<dynamic>} await #t16 : #t16).call();
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
index b4ab7d2..2b35c4f 100644
--- a/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.strong.transformed.expect
@@ -30,6 +30,7 @@
import self as self;
import "dart:async" as asy;
import "dart:core" as core;
+import "dart:_internal" as _in;
static method getNull() → dynamic
return null;
@@ -41,11 +42,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
{
- :return_value = null;
+ final Null #t1 = null;
+ if(#t1 is asy::Future<dynamic>) {
+ [yield] let dynamic #t2 = asy::_awaitHelper(#t1, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Null>(:result);
+ }
+ else {
+ :async_temporary_0 = #t1;
+ }
+ :return_value = :async_temporary_0;
break #L1;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -68,11 +79,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::bool>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L2:
{
- :return_value = true;
+ final core::bool #t3 = true;
+ if(#t3 is asy::Future<core::bool>) {
+ [yield] let dynamic #t4 = asy::_awaitHelper(#t3, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t3;
+ }
+ :return_value = :async_temporary_0;
break #L2;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -96,12 +117,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<core::bool>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L3:
{
- [yield] let dynamic #t1 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ [yield] let dynamic #t5 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+ final FutureOr<core::bool>#t6 = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ if(#t6 is asy::Future<core::bool>) {
+ [yield] let dynamic #t7 = asy::_awaitHelper(#t6, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t6;
+ }
+ :return_value = :async_temporary_0;
break #L3;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -129,12 +159,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<core::bool>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
{
- [yield] let dynamic #t2 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ [yield] let dynamic #t8 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+ final FutureOr<core::bool>#t9 = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ if(#t9 is asy::Future<core::bool>) {
+ [yield] let dynamic #t10 = asy::_awaitHelper(#t9, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t9;
+ }
+ :return_value = :async_temporary_0;
break #L4;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -150,7 +189,7 @@
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>'.
+ return let final<BottomType> #t11 = 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>'.
- 'Future' is from 'dart:async'.
Future<bool> test5() => getFutureNull(); // error
^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
@@ -164,11 +203,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::bool>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L5:
{
- :return_value = self::getFutureBool();
+ final asy::Future<core::bool> #t12 = self::getFutureBool();
+ if(#t12 is asy::Future<core::bool>) {
+ [yield] let dynamic #t13 = asy::_awaitHelper(#t12, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t12;
+ }
+ :return_value = :async_temporary_0;
break #L5;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -204,12 +253,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<core::bool>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L7:
{
- [yield] let dynamic #t4 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ [yield] let dynamic #t14 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+ final FutureOr<core::bool>#t15 = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ if(#t15 is asy::Future<core::bool>) {
+ [yield] let dynamic #t16 = asy::_awaitHelper(#t15, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t15;
+ }
+ :return_value = :async_temporary_0;
break #L7;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -237,12 +295,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<core::bool>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L8:
{
- [yield] let dynamic #t5 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ [yield] let dynamic #t17 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+ final FutureOr<core::bool>#t18 = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ if(#t18 is asy::Future<core::bool>) {
+ [yield] let dynamic #t19 = asy::_awaitHelper(#t18, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t18;
+ }
+ :return_value = :async_temporary_0;
break #L8;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -258,7 +325,7 @@
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>'.
+ return let final<BottomType> #t20 = 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>'.
- 'Future' is from 'dart:async'.
Future<bool> test5() => getFutureNull(); // error
^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
@@ -272,11 +339,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::bool>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L9:
{
- :return_value = self::getFutureBool();
+ final asy::Future<core::bool> #t21 = self::getFutureBool();
+ if(#t21 is asy::Future<core::bool>) {
+ [yield] let dynamic #t22 = asy::_awaitHelper(#t21, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t21;
+ }
+ :return_value = :async_temporary_0;
break #L9;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -291,7 +368,7 @@
: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>'.
+ asy::Future<core::bool> var1 = let final<BottomType> #t23 = 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 */ {
@@ -303,12 +380,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L10:
{
- [yield] let dynamic #t8 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result;
+ [yield] let dynamic #t24 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+ final dynamic #t25 = :result;
+ if(#t25 is asy::Future<dynamic>) {
+ [yield] let dynamic #t26 = asy::_awaitHelper(#t25, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = :result;
+ }
+ else {
+ :async_temporary_0 = #t25;
+ }
+ :return_value = :async_temporary_0;
break #L10;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -325,7 +411,7 @@
}).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;
- asy::Future<core::bool> var4 = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ asy::Future<core::bool> var4 = let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
- 'Future' is from 'dart:async'.
Future<bool> var4 = (() async => await getFutureNull())(); // error
^" in (() → asy::Future<dynamic> /* originally async */ {
@@ -337,12 +423,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L11:
{
- [yield] let dynamic #t10 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result;
+ [yield] let dynamic #t28 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+ final dynamic #t29 = :result;
+ if(#t29 is asy::Future<dynamic>) {
+ [yield] let dynamic #t30 = asy::_awaitHelper(#t29, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = :result;
+ }
+ else {
+ :async_temporary_0 = #t29;
+ }
+ :return_value = :async_temporary_0;
break #L11;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -357,7 +452,7 @@
: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>'.
+ asy::Future<core::bool> var5 = let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
- 'Future' is from 'dart:async'.
Future<bool> var5 = (() => getFutureNull())(); // error
^" in (() → asy::Future<dynamic> => self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
@@ -370,11 +465,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L12:
{
- :return_value = self::getFutureBool();
+ final asy::Future<core::bool> #t32 = self::getFutureBool();
+ if(#t32 is asy::Future<core::bool>) {
+ [yield] let dynamic #t33 = asy::_awaitHelper(#t32, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t32;
+ }
+ :return_value = :async_temporary_0;
break #L12;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
diff --git a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.expect
index fbcd99e..d7881ae 100644
--- a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.expect
@@ -34,61 +34,61 @@
static method getNull() → dynamic
return null;
static method getFutureNull() → asy::Future<dynamic> async {
- return null;
+ return let final Null #t1 = null in #t1 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t1 : #t1;
}
static method getFutureBool() → asy::Future<core::bool> async {
- return true;
+ return let final core::bool #t2 = true in #t2 is asy::Future<core::bool> ?{FutureOr<core::bool>} await #t2 : #t2;
}
static method test1() → asy::Future<core::bool> async
- return await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ return let final dynamic #t3 = await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool> in #t3 is asy::Future<core::bool> ?{FutureOr<core::bool>} await #t3 : #t3;
static method test2() → asy::Future<core::bool>
return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
static method test3() → core::bool
return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
static method test4() → asy::Future<core::bool> async
- return await self::getFutureNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ return let final dynamic #t4 = await self::getFutureNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool> in #t4 is asy::Future<core::bool> ?{FutureOr<core::bool>} await #t4 : #t4;
static method test5() → asy::Future<core::bool>
- return let final<BottomType> #t1 = 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>'.
+ return let final<BottomType> #t5 = 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>'.
- 'Future' is from 'dart:async'.
Future<bool> test5() => getFutureNull(); // error
^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
static method test6() → asy::Future<core::bool>
return self::getFutureBool();
static method test7() → asy::Future<core::bool> async
- return self::getFutureBool();
+ return let final asy::Future<core::bool> #t6 = self::getFutureBool() in #t6 is asy::Future<core::bool> ?{FutureOr<core::bool>} await #t6 : #t6;
static method test() → dynamic async {
function test1() → asy::Future<core::bool> async
- return await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ return let final dynamic #t7 = await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool> in #t7 is asy::Future<core::bool> ?{FutureOr<core::bool>} await #t7 : #t7;
function test2() → asy::Future<core::bool>
return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<core::bool>;
function test3() → core::bool
return self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::bool;
function test4() → asy::Future<core::bool> async
- return await self::getFutureNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ return let final dynamic #t8 = await self::getFutureNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool> in #t8 is asy::Future<core::bool> ?{FutureOr<core::bool>} await #t8 : #t8;
function test5() → asy::Future<core::bool>
- return let final<BottomType> #t2 = 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>'.
+ return let final<BottomType> #t9 = 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>'.
- 'Future' is from 'dart:async'.
Future<bool> test5() => getFutureNull(); // error
^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
function test6() → asy::Future<core::bool>
return self::getFutureBool();
function test7() → asy::Future<core::bool> async
- return self::getFutureBool();
- asy::Future<core::bool> var1 = let final<BottomType> #t3 = 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>'.
+ return let final asy::Future<core::bool> #t10 = self::getFutureBool() in #t10 is asy::Future<core::bool> ?{FutureOr<core::bool>} await #t10 : #t10;
+ asy::Future<core::bool> var1 = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:31:52: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
- 'Future' is from 'dart:async'.
Future<bool> var1 = (() async => await getNull())(); // error
- ^" in (() → asy::Future<dynamic> async => await self::getNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ ^" in (() → asy::Future<dynamic> async => let final dynamic #t12 = await self::getNull() in #t12 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t12 : #t12).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;
- asy::Future<core::bool> var4 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ asy::Future<core::bool> var4 = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
- 'Future' is from 'dart:async'.
Future<bool> var4 = (() async => await getFutureNull())(); // error
- ^" in (() → asy::Future<dynamic> async => await self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
- asy::Future<core::bool> var5 = let final<BottomType> #t5 = 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>'.
+ ^" in (() → asy::Future<dynamic> async => let final dynamic #t14 = await self::getFutureNull() in #t14 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t14 : #t14).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
+ asy::Future<core::bool> var5 = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
- 'Future' is from 'dart:async'.
Future<bool> var5 = (() => getFutureNull())(); // error
^" in (() → asy::Future<dynamic> => self::getFutureNull()).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> async => self::getFutureBool()).call();
+ asy::Future<core::bool> var7 = (() → asy::Future<core::bool> async => let final asy::Future<core::bool> #t16 = self::getFutureBool() in #t16 is asy::Future<core::bool> ?{FutureOr<dynamic>} await #t16 : #t16).call();
}
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 b4ab7d2..2b35c4f 100644
--- a/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41437a.dart.weak.transformed.expect
@@ -30,6 +30,7 @@
import self as self;
import "dart:async" as asy;
import "dart:core" as core;
+import "dart:_internal" as _in;
static method getNull() → dynamic
return null;
@@ -41,11 +42,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
{
- :return_value = null;
+ final Null #t1 = null;
+ if(#t1 is asy::Future<dynamic>) {
+ [yield] let dynamic #t2 = asy::_awaitHelper(#t1, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Null>(:result);
+ }
+ else {
+ :async_temporary_0 = #t1;
+ }
+ :return_value = :async_temporary_0;
break #L1;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -68,11 +79,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::bool>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L2:
{
- :return_value = true;
+ final core::bool #t3 = true;
+ if(#t3 is asy::Future<core::bool>) {
+ [yield] let dynamic #t4 = asy::_awaitHelper(#t3, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t3;
+ }
+ :return_value = :async_temporary_0;
break #L2;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -96,12 +117,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<core::bool>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L3:
{
- [yield] let dynamic #t1 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ [yield] let dynamic #t5 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+ final FutureOr<core::bool>#t6 = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ if(#t6 is asy::Future<core::bool>) {
+ [yield] let dynamic #t7 = asy::_awaitHelper(#t6, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t6;
+ }
+ :return_value = :async_temporary_0;
break #L3;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -129,12 +159,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<core::bool>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
{
- [yield] let dynamic #t2 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ [yield] let dynamic #t8 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+ final FutureOr<core::bool>#t9 = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ if(#t9 is asy::Future<core::bool>) {
+ [yield] let dynamic #t10 = asy::_awaitHelper(#t9, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t9;
+ }
+ :return_value = :async_temporary_0;
break #L4;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -150,7 +189,7 @@
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>'.
+ return let final<BottomType> #t11 = 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>'.
- 'Future' is from 'dart:async'.
Future<bool> test5() => getFutureNull(); // error
^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
@@ -164,11 +203,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::bool>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L5:
{
- :return_value = self::getFutureBool();
+ final asy::Future<core::bool> #t12 = self::getFutureBool();
+ if(#t12 is asy::Future<core::bool>) {
+ [yield] let dynamic #t13 = asy::_awaitHelper(#t12, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t12;
+ }
+ :return_value = :async_temporary_0;
break #L5;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -204,12 +253,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<core::bool>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L7:
{
- [yield] let dynamic #t4 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ [yield] let dynamic #t14 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+ final FutureOr<core::bool>#t15 = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ if(#t15 is asy::Future<core::bool>) {
+ [yield] let dynamic #t16 = asy::_awaitHelper(#t15, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t15;
+ }
+ :return_value = :async_temporary_0;
break #L7;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -237,12 +295,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<core::bool>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L8:
{
- [yield] let dynamic #t5 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ [yield] let dynamic #t17 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+ final FutureOr<core::bool>#t18 = :result as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::bool>;
+ if(#t18 is asy::Future<core::bool>) {
+ [yield] let dynamic #t19 = asy::_awaitHelper(#t18, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t18;
+ }
+ :return_value = :async_temporary_0;
break #L8;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -258,7 +325,7 @@
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>'.
+ return let final<BottomType> #t20 = 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>'.
- 'Future' is from 'dart:async'.
Future<bool> test5() => getFutureNull(); // error
^" in self::getFutureNull() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
@@ -272,11 +339,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::bool>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L9:
{
- :return_value = self::getFutureBool();
+ final asy::Future<core::bool> #t21 = self::getFutureBool();
+ if(#t21 is asy::Future<core::bool>) {
+ [yield] let dynamic #t22 = asy::_awaitHelper(#t21, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t21;
+ }
+ :return_value = :async_temporary_0;
break #L9;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -291,7 +368,7 @@
: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>'.
+ asy::Future<core::bool> var1 = let final<BottomType> #t23 = 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 */ {
@@ -303,12 +380,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L10:
{
- [yield] let dynamic #t8 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result;
+ [yield] let dynamic #t24 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
+ final dynamic #t25 = :result;
+ if(#t25 is asy::Future<dynamic>) {
+ [yield] let dynamic #t26 = asy::_awaitHelper(#t25, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = :result;
+ }
+ else {
+ :async_temporary_0 = #t25;
+ }
+ :return_value = :async_temporary_0;
break #L10;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -325,7 +411,7 @@
}).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;
- asy::Future<core::bool> var4 = let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
+ asy::Future<core::bool> var4 = let final<BottomType> #t27 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:34:58: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
- 'Future' is from 'dart:async'.
Future<bool> var4 = (() async => await getFutureNull())(); // error
^" in (() → asy::Future<dynamic> /* originally async */ {
@@ -337,12 +423,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L11:
{
- [yield] let dynamic #t10 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result;
+ [yield] let dynamic #t28 = asy::_awaitHelper(self::getFutureNull(), :async_op_then, :async_op_error, :async_op) in null;
+ final dynamic #t29 = :result;
+ if(#t29 is asy::Future<dynamic>) {
+ [yield] let dynamic #t30 = asy::_awaitHelper(#t29, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = :result;
+ }
+ else {
+ :async_temporary_0 = #t29;
+ }
+ :return_value = :async_temporary_0;
break #L11;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -357,7 +452,7 @@
: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>'.
+ asy::Future<core::bool> var5 = let final<BottomType> #t31 = invalid-expression "pkg/front_end/testcases/nnbd/issue41437a.dart:35:46: Error: A value of type 'Future<dynamic>' can't be assigned to a variable of type 'Future<bool>'.
- 'Future' is from 'dart:async'.
Future<bool> var5 = (() => getFutureNull())(); // error
^" in (() → asy::Future<dynamic> => self::getFutureNull()).call() as{TypeError,ForNonNullableByDefault} asy::Future<core::bool>;
@@ -370,11 +465,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L12:
{
- :return_value = self::getFutureBool();
+ final asy::Future<core::bool> #t32 = self::getFutureBool();
+ if(#t32 is asy::Future<core::bool>) {
+ [yield] let dynamic #t33 = asy::_awaitHelper(#t32, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::bool>(:result);
+ }
+ else {
+ :async_temporary_0 = #t32;
+ }
+ :return_value = :async_temporary_0;
break #L12;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
diff --git a/pkg/front_end/testcases/nnbd/issue41697.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue41697.dart.strong.expect
index f0b15fb..58eebef 100644
--- a/pkg/front_end/testcases/nnbd/issue41697.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue41697.dart.strong.expect
@@ -34,23 +34,23 @@
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> async {
- return (await t).{core::num::+}(1);
+ return let final core::num #t1 = (await t).{core::num::+}(1) in #t1 is asy::Future<core::num> ?{FutureOr<dynamic>} await #t1 : #t1;
};
}
static method test2(self::C<core::num?> c) → dynamic {
<S extends core::num? = core::num?>(S%) → core::num f1 = c.{self::C::field1} = <S extends core::num? = core::num?>(S% s) → core::num {
- return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:33:14: Error: Operator '+' cannot be called on 'S' because it is potentially null.
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:33:14: Error: Operator '+' cannot be called on 'S' because it is potentially null.
return s + 1; // error
^" 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> async {
- return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:36:22: Error: Operator '+' cannot be called on 'num?' because it is potentially null.
+ return let final core::num #t3 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:36:22: Error: Operator '+' cannot be called on 'num?' because it is potentially null.
return (await t) + 1; // error
- ^" in (await t).{core::num::+}(1);
+ ^" in (await t).{core::num::+}(1) in #t3 is asy::Future<core::num> ?{FutureOr<dynamic>} await #t3 : #t3;
};
}
static method test3<S extends core::num? = core::num?>(self::test3::S% s) → dynamic
- return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:40:33: Error: Operator '+' cannot be called on 'S' because it is potentially null.
+ return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:40:33: Error: Operator '+' cannot be called on 'S' because it is potentially null.
test3<S extends num?>(S s) => s + 1; // error
^" in s.{core::num::+}(1);
static method main() → dynamic {}
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 b287a57..b08be8f 100644
--- a/pkg/front_end/testcases/nnbd/issue41697.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41697.dart.strong.transformed.expect
@@ -43,12 +43,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
{
[yield] let dynamic #t1 = asy::_awaitHelper(t, :async_op_then, :async_op_error, :async_op) in null;
- :return_value = _in::unsafeCast<core::num>(:result).{core::num::+}(1);
+ final core::num #t2 = _in::unsafeCast<core::num>(:result).{core::num::+}(1);
+ if(#t2 is asy::Future<core::num>) {
+ [yield] let dynamic #t3 = asy::_awaitHelper(#t2, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::num>(:result);
+ }
+ else {
+ :async_temporary_0 = #t2;
+ }
+ :return_value = :async_temporary_0;
break #L1;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -66,7 +75,7 @@
}
static method test2(self::C<core::num?> c) → dynamic {
<S extends core::num? = core::num?>(S%) → core::num f1 = c.{self::C::field1} = <S extends core::num? = core::num?>(S% s) → core::num {
- return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:33:14: Error: Operator '+' cannot be called on 'S' because it is potentially null.
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:33:14: Error: Operator '+' cannot be called on 'S' because it is potentially null.
return s + 1; // error
^" in s.{core::num::+}(1);
};
@@ -79,15 +88,24 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L2:
{
- final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:36:22: Error: Operator '+' cannot be called on 'num?' because it is potentially null.
+ final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:36:22: Error: Operator '+' cannot be called on 'num?' because it is potentially null.
return (await t) + 1; // error
^";
- [yield] let dynamic #t4 = asy::_awaitHelper(t, :async_op_then, :async_op_error, :async_op) in null;
- :return_value = _in::unsafeCast<core::num?>(:result).{core::num::+}(1);
+ [yield] let dynamic #t6 = asy::_awaitHelper(t, :async_op_then, :async_op_error, :async_op) in null;
+ final core::num #t7 = _in::unsafeCast<core::num?>(:result).{core::num::+}(1);
+ if(#t7 is asy::Future<core::num>) {
+ [yield] let dynamic #t8 = asy::_awaitHelper(#t7, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::num>(:result);
+ }
+ else {
+ :async_temporary_0 = #t7;
+ }
+ :return_value = :async_temporary_0;
break #L2;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -104,7 +122,7 @@
};
}
static method test3<S extends core::num? = core::num?>(self::test3::S% s) → dynamic
- return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:40:33: Error: Operator '+' cannot be called on 'S' because it is potentially null.
+ return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:40:33: Error: Operator '+' cannot be called on 'S' because it is potentially null.
test3<S extends num?>(S s) => s + 1; // error
^" in s.{core::num::+}(1);
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue41697.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue41697.dart.weak.expect
index f0b15fb..58eebef 100644
--- a/pkg/front_end/testcases/nnbd/issue41697.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue41697.dart.weak.expect
@@ -34,23 +34,23 @@
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> async {
- return (await t).{core::num::+}(1);
+ return let final core::num #t1 = (await t).{core::num::+}(1) in #t1 is asy::Future<core::num> ?{FutureOr<dynamic>} await #t1 : #t1;
};
}
static method test2(self::C<core::num?> c) → dynamic {
<S extends core::num? = core::num?>(S%) → core::num f1 = c.{self::C::field1} = <S extends core::num? = core::num?>(S% s) → core::num {
- return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:33:14: Error: Operator '+' cannot be called on 'S' because it is potentially null.
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:33:14: Error: Operator '+' cannot be called on 'S' because it is potentially null.
return s + 1; // error
^" 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> async {
- return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:36:22: Error: Operator '+' cannot be called on 'num?' because it is potentially null.
+ return let final core::num #t3 = let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:36:22: Error: Operator '+' cannot be called on 'num?' because it is potentially null.
return (await t) + 1; // error
- ^" in (await t).{core::num::+}(1);
+ ^" in (await t).{core::num::+}(1) in #t3 is asy::Future<core::num> ?{FutureOr<dynamic>} await #t3 : #t3;
};
}
static method test3<S extends core::num? = core::num?>(self::test3::S% s) → dynamic
- return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:40:33: Error: Operator '+' cannot be called on 'S' because it is potentially null.
+ return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:40:33: Error: Operator '+' cannot be called on 'S' because it is potentially null.
test3<S extends num?>(S s) => s + 1; // error
^" in s.{core::num::+}(1);
static method main() → 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 b287a57..b08be8f 100644
--- a/pkg/front_end/testcases/nnbd/issue41697.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue41697.dart.weak.transformed.expect
@@ -43,12 +43,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
{
[yield] let dynamic #t1 = asy::_awaitHelper(t, :async_op_then, :async_op_error, :async_op) in null;
- :return_value = _in::unsafeCast<core::num>(:result).{core::num::+}(1);
+ final core::num #t2 = _in::unsafeCast<core::num>(:result).{core::num::+}(1);
+ if(#t2 is asy::Future<core::num>) {
+ [yield] let dynamic #t3 = asy::_awaitHelper(#t2, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::num>(:result);
+ }
+ else {
+ :async_temporary_0 = #t2;
+ }
+ :return_value = :async_temporary_0;
break #L1;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -66,7 +75,7 @@
}
static method test2(self::C<core::num?> c) → dynamic {
<S extends core::num? = core::num?>(S%) → core::num f1 = c.{self::C::field1} = <S extends core::num? = core::num?>(S% s) → core::num {
- return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:33:14: Error: Operator '+' cannot be called on 'S' because it is potentially null.
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:33:14: Error: Operator '+' cannot be called on 'S' because it is potentially null.
return s + 1; // error
^" in s.{core::num::+}(1);
};
@@ -79,15 +88,24 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L2:
{
- final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:36:22: Error: Operator '+' cannot be called on 'num?' because it is potentially null.
+ final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:36:22: Error: Operator '+' cannot be called on 'num?' because it is potentially null.
return (await t) + 1; // error
^";
- [yield] let dynamic #t4 = asy::_awaitHelper(t, :async_op_then, :async_op_error, :async_op) in null;
- :return_value = _in::unsafeCast<core::num?>(:result).{core::num::+}(1);
+ [yield] let dynamic #t6 = asy::_awaitHelper(t, :async_op_then, :async_op_error, :async_op) in null;
+ final core::num #t7 = _in::unsafeCast<core::num?>(:result).{core::num::+}(1);
+ if(#t7 is asy::Future<core::num>) {
+ [yield] let dynamic #t8 = asy::_awaitHelper(#t7, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::num>(:result);
+ }
+ else {
+ :async_temporary_0 = #t7;
+ }
+ :return_value = :async_temporary_0;
break #L2;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -104,7 +122,7 @@
};
}
static method test3<S extends core::num? = core::num?>(self::test3::S% s) → dynamic
- return let final<BottomType> #t5 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:40:33: Error: Operator '+' cannot be called on 'S' because it is potentially null.
+ return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/issue41697.dart:40:33: Error: Operator '+' cannot be called on 'S' because it is potentially null.
test3<S extends num?>(S s) => s + 1; // error
^" in s.{core::num::+}(1);
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42540.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42540.dart.strong.expect
index aaf931d..c1d787d 100644
--- a/pkg/front_end/testcases/nnbd/issue42540.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue42540.dart.strong.expect
@@ -7,6 +7,6 @@
return null;
static method fn() → asy::Future<core::Object> async {
core::Object o = await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Object;
- return await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::Object>;
+ return let final dynamic #t1 = await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::Object> in #t1 is asy::Future<core::Object> ?{FutureOr<core::Object>} await #t1 : #t1;
}
static method main() → 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 4e127a6..b5edde0 100644
--- a/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42540.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
import self as self;
import "dart:async" as asy;
import "dart:core" as core;
+import "dart:_internal" as _in;
static method getNull() → dynamic
return null;
@@ -14,6 +15,7 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<core::Object>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
@@ -21,7 +23,15 @@
[yield] let dynamic #t1 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
core::Object o = let dynamic #t2 = :result in #t2.==(null) ?{core::Object} #t2 as{TypeError,ForDynamic,ForNonNullableByDefault} core::Object : #t2{core::Object};
[yield] let dynamic #t3 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = let dynamic #t4 = :result in #t4.==(null) ?{FutureOr<core::Object>} #t4 as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::Object> : #t4{FutureOr<core::Object>};
+ final FutureOr<core::Object>#t4 = let dynamic #t5 = :result in #t5.==(null) ?{FutureOr<core::Object>} #t5 as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::Object> : #t5{FutureOr<core::Object>};
+ if(#t4 is asy::Future<core::Object>) {
+ [yield] let dynamic #t6 = asy::_awaitHelper(#t4, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::Object>(:result);
+ }
+ else {
+ :async_temporary_0 = #t4;
+ }
+ :return_value = :async_temporary_0;
break #L1;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
diff --git a/pkg/front_end/testcases/nnbd/issue42540.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42540.dart.weak.expect
index aaf931d..c1d787d 100644
--- a/pkg/front_end/testcases/nnbd/issue42540.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue42540.dart.weak.expect
@@ -7,6 +7,6 @@
return null;
static method fn() → asy::Future<core::Object> async {
core::Object o = await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} core::Object;
- return await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::Object>;
+ return let final dynamic #t1 = await self::getNull() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::Object> in #t1 is asy::Future<core::Object> ?{FutureOr<core::Object>} await #t1 : #t1;
}
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 e61b30d..36497a3 100644
--- a/pkg/front_end/testcases/nnbd/issue42540.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42540.dart.weak.transformed.expect
@@ -2,6 +2,7 @@
import self as self;
import "dart:async" as asy;
import "dart:core" as core;
+import "dart:_internal" as _in;
static method getNull() → dynamic
return null;
@@ -14,6 +15,7 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<core::Object>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
@@ -21,7 +23,15 @@
[yield] let dynamic #t1 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
core::Object o = :result;
[yield] let dynamic #t2 = asy::_awaitHelper(self::getNull(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result;
+ final FutureOr<core::Object>#t3 = :result;
+ if(#t3 is asy::Future<core::Object>) {
+ [yield] let dynamic #t4 = asy::_awaitHelper(#t3, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::Object>(:result);
+ }
+ else {
+ :async_temporary_0 = #t3;
+ }
+ :return_value = :async_temporary_0;
break #L1;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.strong.expect
index e5372a7..e446f7c 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.strong.expect
@@ -42,11 +42,11 @@
- 'Future' is from 'dart:async'.
- 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
- ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> async => let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:58: Error: A value of type 'Divergent<int>' can't be returned from an async function with return type 'Future<Divergent<Divergent<Divergent<int>>>>'.
+ ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> async => let final self::Divergent<core::int> #t2 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:58: Error: A value of type 'Divergent<int>' can't be returned from an async function with return type 'Future<Divergent<Divergent<Divergent<int>>>>'.
- 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
- 'Future' is from 'dart:async'.
Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
- ^" in new self::Divergent::•<core::int>() as{TypeError,ForNonNullableByDefault} self::Divergent<self::Divergent<self::Divergent<core::int>>>).call() as{TypeError,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<core::int>>>;
+ ^" in new self::Divergent::•<core::int>() as{TypeError,ForNonNullableByDefault} self::Divergent<self::Divergent<self::Divergent<core::int>>> in #t2 is asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> ?{FutureOr<dynamic>} await #t2 : #t2).call() as{TypeError,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<core::int>>>;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.strong.transformed.expect
new file mode 100644
index 0000000..5ae2bec
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.strong.transformed.expect
@@ -0,0 +1,126 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue42546.dart:14:58: Error: A value of type 'Divergent<int>' can't be returned from an async function with return type 'Future<Divergent<Divergent<Divergent<int>>>>'.
+// - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
+// - 'Future' is from 'dart:async'.
+// Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue42546.dart:14:75: Error: A value of type 'Future<Divergent<Divergent<Divergent<int>>>>' can't be assigned to a variable of type 'Future<Divergent<Divergent<int>>>'.
+// - 'Future' is from 'dart:async'.
+// - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
+// Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
+// ^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "dart:_internal" as _in;
+
+import "dart:async";
+
+class Divergent<T extends core::Object? = dynamic> extends core::Object implements asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>> {
+ synthetic constructor •() → self::Divergent<self::Divergent::T%>
+ : super core::Object::•()
+ ;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return super.{core::Object::noSuchMethod}(invocation);
+ no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+ return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))) as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
+ no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+ return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C7))) as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
+ no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () →? FutureOr<self::Divergent<self::Divergent<self::Divergent::T%>>>onTimeout = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+ return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C8, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C9: onTimeout}))) as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
+ no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ then<R extends core::Object? = dynamic>((self::Divergent<self::Divergent<self::Divergent::T%>>) → FutureOr<self::Divergent::then::R%>onValue, {core::Function? onError = #C1}) → asy::Future<self::Divergent::then::R%>
+ return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C10, 0, core::List::unmodifiable<core::Type*>(core::_GrowableList::_literal1<core::Type*>(self::Divergent::then::R%)), core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onValue)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C11: onError}))) as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent::then::R%>;
+ no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
+ return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C12, 0, #C3, #C6, core::Map::unmodifiable<core::Symbol*, dynamic>(#C7))) as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>;
+}
+static method test() → dynamic /* originally async */ {
+ final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+ core::bool* :is_sync = false;
+ FutureOr<dynamic>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L1:
+ {
+ asy::Future<self::Divergent<self::Divergent<core::int>>> x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:75: Error: A value of type 'Future<Divergent<Divergent<Divergent<int>>>>' can't be assigned to a variable of type 'Future<Divergent<Divergent<int>>>'.
+ - 'Future' is from 'dart:async'.
+ - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
+ Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
+ ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> /* originally async */ {
+ final asy::_Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> :async_future = new asy::_Future::•<self::Divergent<self::Divergent<self::Divergent<core::int>>>>();
+ core::bool* :is_sync = false;
+ FutureOr<self::Divergent<self::Divergent<self::Divergent<core::int>>>>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L2:
+ {
+ final self::Divergent<core::int> #t2 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:58: Error: A value of type 'Divergent<int>' can't be returned from an async function with return type 'Future<Divergent<Divergent<Divergent<int>>>>'.
+ - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
+ - 'Future' is from 'dart:async'.
+ Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
+ ^" in new self::Divergent::•<core::int>() as{TypeError,ForNonNullableByDefault} self::Divergent<self::Divergent<self::Divergent<core::int>>>;
+ if(#t2 is asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>>) {
+ [yield] let dynamic #t4 = asy::_awaitHelper(#t2, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<self::Divergent<self::Divergent<core::int>>>(:result);
+ }
+ else {
+ :async_temporary_0 = #t2;
+ }
+ :return_value = :async_temporary_0;
+ break #L2;
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+ }).call() as{TypeError,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<core::int>>>;
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = null
+ #C2 = #catchError
+ #C3 = <core::Type*>[]
+ #C4 = #test
+ #C5 = #whenComplete
+ #C6 = <dynamic>[]
+ #C7 = core::_ImmutableMap<core::Symbol*, dynamic> {_kvPairs:#C6}
+ #C8 = #timeout
+ #C9 = #onTimeout
+ #C10 = #then
+ #C11 = #onError
+ #C12 = #asStream
+}
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.expect
index e5372a7..e446f7c 100644
--- a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.expect
@@ -42,11 +42,11 @@
- 'Future' is from 'dart:async'.
- 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
- ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> async => let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:58: Error: A value of type 'Divergent<int>' can't be returned from an async function with return type 'Future<Divergent<Divergent<Divergent<int>>>>'.
+ ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> async => let final self::Divergent<core::int> #t2 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:58: Error: A value of type 'Divergent<int>' can't be returned from an async function with return type 'Future<Divergent<Divergent<Divergent<int>>>>'.
- 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
- 'Future' is from 'dart:async'.
Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
- ^" in new self::Divergent::•<core::int>() as{TypeError,ForNonNullableByDefault} self::Divergent<self::Divergent<self::Divergent<core::int>>>).call() as{TypeError,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<core::int>>>;
+ ^" in new self::Divergent::•<core::int>() as{TypeError,ForNonNullableByDefault} self::Divergent<self::Divergent<self::Divergent<core::int>>> in #t2 is asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> ?{FutureOr<dynamic>} await #t2 : #t2).call() as{TypeError,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<core::int>>>;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/issue42546.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.transformed.expect
new file mode 100644
index 0000000..5ae2bec
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/issue42546.dart.weak.transformed.expect
@@ -0,0 +1,126 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/issue42546.dart:14:58: Error: A value of type 'Divergent<int>' can't be returned from an async function with return type 'Future<Divergent<Divergent<Divergent<int>>>>'.
+// - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
+// - 'Future' is from 'dart:async'.
+// Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
+// ^
+//
+// pkg/front_end/testcases/nnbd/issue42546.dart:14:75: Error: A value of type 'Future<Divergent<Divergent<Divergent<int>>>>' can't be assigned to a variable of type 'Future<Divergent<Divergent<int>>>'.
+// - 'Future' is from 'dart:async'.
+// - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
+// Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
+// ^
+//
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "dart:_internal" as _in;
+
+import "dart:async";
+
+class Divergent<T extends core::Object? = dynamic> extends core::Object implements asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>> {
+ synthetic constructor •() → self::Divergent<self::Divergent::T%>
+ : super core::Object::•()
+ ;
+ method noSuchMethod(core::Invocation invocation) → dynamic
+ return super.{core::Object::noSuchMethod}(invocation);
+ no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) →? core::bool test = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+ return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C2, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onError)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C4: test}))) as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
+ no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ whenComplete(() → FutureOr<void>action) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+ return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C5, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(action)), core::Map::unmodifiable<core::Symbol*, dynamic>(#C7))) as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
+ no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () →? FutureOr<self::Divergent<self::Divergent<self::Divergent::T%>>>onTimeout = #C1}) → asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>
+ return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C8, 0, #C3, core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(timeLimit)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C9: onTimeout}))) as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<self::Divergent::T%>>>;
+ no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ then<R extends core::Object? = dynamic>((self::Divergent<self::Divergent<self::Divergent::T%>>) → FutureOr<self::Divergent::then::R%>onValue, {core::Function? onError = #C1}) → asy::Future<self::Divergent::then::R%>
+ return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C10, 0, core::List::unmodifiable<core::Type*>(core::_GrowableList::_literal1<core::Type*>(self::Divergent::then::R%)), core::List::unmodifiable<dynamic>(core::_GrowableList::_literal1<dynamic>(onValue)), core::Map::unmodifiable<core::Symbol*, dynamic>(<core::Symbol*, dynamic>{#C11: onError}))) as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Future<self::Divergent::then::R%>;
+ no-such-method-forwarder method /* from org-dartlang-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>
+ return this.{self::Divergent::noSuchMethod}(new core::_InvocationMirror::_withType(#C12, 0, #C3, #C6, core::Map::unmodifiable<core::Symbol*, dynamic>(#C7))) as{TypeError,ForDynamic,ForNonNullableByDefault} asy::Stream<self::Divergent<self::Divergent<self::Divergent::T%>>>;
+}
+static method test() → dynamic /* originally async */ {
+ final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+ core::bool* :is_sync = false;
+ FutureOr<dynamic>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L1:
+ {
+ asy::Future<self::Divergent<self::Divergent<core::int>>> x = let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:75: Error: A value of type 'Future<Divergent<Divergent<Divergent<int>>>>' can't be assigned to a variable of type 'Future<Divergent<Divergent<int>>>'.
+ - 'Future' is from 'dart:async'.
+ - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
+ Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
+ ^" in (() → asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> /* originally async */ {
+ final asy::_Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>> :async_future = new asy::_Future::•<self::Divergent<self::Divergent<self::Divergent<core::int>>>>();
+ core::bool* :is_sync = false;
+ FutureOr<self::Divergent<self::Divergent<self::Divergent<core::int>>>>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L2:
+ {
+ final self::Divergent<core::int> #t2 = let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/issue42546.dart:14:58: Error: A value of type 'Divergent<int>' can't be returned from an async function with return type 'Future<Divergent<Divergent<Divergent<int>>>>'.
+ - 'Divergent' is from 'pkg/front_end/testcases/nnbd/issue42546.dart'.
+ - 'Future' is from 'dart:async'.
+ Future<Divergent<Divergent<int>>> x = (() async => new Divergent<int>())();
+ ^" in new self::Divergent::•<core::int>() as{TypeError,ForNonNullableByDefault} self::Divergent<self::Divergent<self::Divergent<core::int>>>;
+ if(#t2 is asy::Future<self::Divergent<self::Divergent<self::Divergent<core::int>>>>) {
+ [yield] let dynamic #t4 = asy::_awaitHelper(#t2, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<self::Divergent<self::Divergent<core::int>>>(:result);
+ }
+ else {
+ :async_temporary_0 = #t2;
+ }
+ :return_value = :async_temporary_0;
+ break #L2;
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+ }).call() as{TypeError,ForNonNullableByDefault} asy::Future<self::Divergent<self::Divergent<core::int>>>;
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method main() → dynamic {}
+
+constants {
+ #C1 = null
+ #C2 = #catchError
+ #C3 = <core::Type*>[]
+ #C4 = #test
+ #C5 = #whenComplete
+ #C6 = <dynamic>[]
+ #C7 = core::_ImmutableMap<core::Symbol*, dynamic> {_kvPairs:#C6}
+ #C8 = #timeout
+ #C9 = #onTimeout
+ #C10 = #then
+ #C11 = #onError
+ #C12 = #asStream
+}
diff --git a/pkg/front_end/testcases/nnbd/issue42743.dart.strong.expect b/pkg/front_end/testcases/nnbd/issue42743.dart.strong.expect
index 1d21b07..eaaabba4 100644
--- a/pkg/front_end/testcases/nnbd/issue42743.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/issue42743.dart.strong.expect
@@ -11,6 +11,6 @@
};
(dynamic _) → asy::Future<core::int?> async {
if(b)
- return 42;
+ return let final core::int #t1 = 42 in #t1 is asy::Future<core::int?> ?{FutureOr<dynamic>} await #t1 : #t1;
};
}
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 0ab4a75..1509333 100644
--- a/pkg/front_end/testcases/nnbd/issue42743.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42743.dart.strong.transformed.expect
@@ -2,6 +2,7 @@
import self as self;
import "dart:async" as asy;
import "dart:core" as core;
+import "dart:_internal" as _in;
static method main() → dynamic /* originally async */ {
final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
@@ -28,12 +29,22 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L2:
{
if(b) {
- :return_value = 42;
+ final core::int #t1 = 42;
+ if(#t1 is asy::Future<core::int?>) {
+ [yield] let dynamic #t2 = asy::_awaitHelper(#t1, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t1;
+ }
+ :return_value = :async_temporary_0;
break #L2;
}
}
diff --git a/pkg/front_end/testcases/nnbd/issue42743.dart.weak.expect b/pkg/front_end/testcases/nnbd/issue42743.dart.weak.expect
index 1d21b07..eaaabba4 100644
--- a/pkg/front_end/testcases/nnbd/issue42743.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/issue42743.dart.weak.expect
@@ -11,6 +11,6 @@
};
(dynamic _) → asy::Future<core::int?> async {
if(b)
- return 42;
+ return let final core::int #t1 = 42 in #t1 is asy::Future<core::int?> ?{FutureOr<dynamic>} await #t1 : #t1;
};
}
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 0ab4a75..1509333 100644
--- a/pkg/front_end/testcases/nnbd/issue42743.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/issue42743.dart.weak.transformed.expect
@@ -2,6 +2,7 @@
import self as self;
import "dart:async" as asy;
import "dart:core" as core;
+import "dart:_internal" as _in;
static method main() → dynamic /* originally async */ {
final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
@@ -28,12 +29,22 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L2:
{
if(b) {
- :return_value = 42;
+ final core::int #t1 = 42;
+ if(#t1 is asy::Future<core::int?>) {
+ [yield] let dynamic #t2 = asy::_awaitHelper(#t1, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t1;
+ }
+ :return_value = :async_temporary_0;
break #L2;
}
}
diff --git a/pkg/front_end/testcases/nnbd/later.dart.strong.expect b/pkg/front_end/testcases/nnbd/later.dart.strong.expect
index df47af6..17dcee5 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.strong.expect
@@ -120,7 +120,7 @@
await for (core::String s in asy::Stream::fromIterable<core::String>(<core::String>["hest"])) {
core::print(s);
}
- return "hest";
+ return let final core::String #t2 = "hest" in #t2 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t2 : #t2;
}
static method fisk() → dynamic async {
late core::String s1 = invalid-expression "pkg/front_end/testcases/nnbd/later.dart:38:20: Error: `await` expressions are not supported in late local initializers.
@@ -129,7 +129,7 @@
late core::String s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/nnbd/later.dart:39:30: Error: `await` expressions are not supported in late local initializers.
late String s2 = '\${fisk}\${await hest()}\${fisk}';
^^^^^"}${#C1}";
- late core::Function f = () → asy::Future<dynamic> async => await self::hest();
+ late core::Function f = () → asy::Future<dynamic> async => let final dynamic #t3 = await self::hest() in #t3 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t3 : #t3;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
index 2aba575..53a4028 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.strong.transformed.expect
@@ -135,6 +135,8 @@
dynamic :saved_try_context_var1;
dynamic :exception0;
dynamic :stack_trace0;
+ FutureOr<dynamic>:async_temporary_0;
+ FutureOr<dynamic>:async_temporary_1;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
@@ -162,7 +164,15 @@
:result;
}
}
- :return_value = "hest";
+ final core::String #t5 = "hest";
+ if(#t5 is asy::Future<dynamic>) {
+ [yield] let dynamic #t6 = asy::_awaitHelper(#t5, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_1 = _in::unsafeCast<core::String>(:result);
+ }
+ else {
+ :async_temporary_1 = #t5;
+ }
+ :return_value = :async_temporary_1;
break #L1;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -209,12 +219,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
{
- [yield] let dynamic #t5 = asy::_awaitHelper(self::hest(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result;
+ [yield] let dynamic #t7 = asy::_awaitHelper(self::hest(), :async_op_then, :async_op_error, :async_op) in null;
+ final dynamic #t8 = :result;
+ if(#t8 is asy::Future<dynamic>) {
+ [yield] let dynamic #t9 = asy::_awaitHelper(#t8, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = :result;
+ }
+ else {
+ :async_temporary_0 = #t8;
+ }
+ :return_value = :async_temporary_0;
break #L4;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
diff --git a/pkg/front_end/testcases/nnbd/later.dart.weak.expect b/pkg/front_end/testcases/nnbd/later.dart.weak.expect
index df47af6..17dcee5 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.weak.expect
@@ -120,7 +120,7 @@
await for (core::String s in asy::Stream::fromIterable<core::String>(<core::String>["hest"])) {
core::print(s);
}
- return "hest";
+ return let final core::String #t2 = "hest" in #t2 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t2 : #t2;
}
static method fisk() → dynamic async {
late core::String s1 = invalid-expression "pkg/front_end/testcases/nnbd/later.dart:38:20: Error: `await` expressions are not supported in late local initializers.
@@ -129,7 +129,7 @@
late core::String s2 = "${#C1}${invalid-expression "pkg/front_end/testcases/nnbd/later.dart:39:30: Error: `await` expressions are not supported in late local initializers.
late String s2 = '\${fisk}\${await hest()}\${fisk}';
^^^^^"}${#C1}";
- late core::Function f = () → asy::Future<dynamic> async => await self::hest();
+ late core::Function f = () → asy::Future<dynamic> async => let final dynamic #t3 = await self::hest() in #t3 is asy::Future<dynamic> ?{FutureOr<dynamic>} await #t3 : #t3;
}
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 2aba575..53a4028 100644
--- a/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/later.dart.weak.transformed.expect
@@ -135,6 +135,8 @@
dynamic :saved_try_context_var1;
dynamic :exception0;
dynamic :stack_trace0;
+ FutureOr<dynamic>:async_temporary_0;
+ FutureOr<dynamic>:async_temporary_1;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L1:
@@ -162,7 +164,15 @@
:result;
}
}
- :return_value = "hest";
+ final core::String #t5 = "hest";
+ if(#t5 is asy::Future<dynamic>) {
+ [yield] let dynamic #t6 = asy::_awaitHelper(#t5, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_1 = _in::unsafeCast<core::String>(:result);
+ }
+ else {
+ :async_temporary_1 = #t5;
+ }
+ :return_value = :async_temporary_1;
break #L1;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -209,12 +219,21 @@
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
dynamic :saved_try_context_var0;
+ FutureOr<dynamic>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
{
- [yield] let dynamic #t5 = asy::_awaitHelper(self::hest(), :async_op_then, :async_op_error, :async_op) in null;
- :return_value = :result;
+ [yield] let dynamic #t7 = asy::_awaitHelper(self::hest(), :async_op_then, :async_op_error, :async_op) in null;
+ final dynamic #t8 = :result;
+ if(#t8 is asy::Future<dynamic>) {
+ [yield] let dynamic #t9 = asy::_awaitHelper(#t8, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = :result;
+ }
+ else {
+ :async_temporary_0 = #t8;
+ }
+ :return_value = :async_temporary_0;
break #L4;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
diff --git a/pkg/front_end/testcases/nnbd/return_async.dart.strong.expect b/pkg/front_end/testcases/nnbd/return_async.dart.strong.expect
index 2c50b42..7fe1ab7 100644
--- a/pkg/front_end/testcases/nnbd/return_async.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/return_async.dart.strong.expect
@@ -28,6 +28,6 @@
}, (core::Object e, core::StackTrace s) → void {
completer.{asy::Completer::completeError}(e, s);
});
- return completer.{asy::Completer::future};
+ return let final asy::Future<void> #t1 = completer.{asy::Completer::future} in #t1 is asy::Future<void> ?{FutureOr<void>} await #t1 : #t1;
}
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 b9094ae..d88bd46 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
@@ -106,6 +106,8 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<void>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
@@ -142,7 +144,15 @@
}, (core::Object e, core::StackTrace s) → void {
completer.{asy::Completer::completeError}(e, s);
});
- :return_value = completer.{asy::Completer::future};
+ final asy::Future<void> #t7 = completer.{asy::Completer::future};
+ if(#t7 is asy::Future<void>) {
+ [yield] let dynamic #t8 = asy::_awaitHelper(#t7, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<void>(:result);
+ }
+ else {
+ :async_temporary_0 = #t7;
+ }
+ :return_value = :async_temporary_0;
break #L4;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
diff --git a/pkg/front_end/testcases/nnbd/return_async.dart.weak.expect b/pkg/front_end/testcases/nnbd/return_async.dart.weak.expect
index 2c50b42..7fe1ab7 100644
--- a/pkg/front_end/testcases/nnbd/return_async.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/return_async.dart.weak.expect
@@ -28,6 +28,6 @@
}, (core::Object e, core::StackTrace s) → void {
completer.{asy::Completer::completeError}(e, s);
});
- return completer.{asy::Completer::future};
+ return let final asy::Future<void> #t1 = completer.{asy::Completer::future} in #t1 is asy::Future<void> ?{FutureOr<void>} await #t1 : #t1;
}
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 b9094ae..d88bd46 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
@@ -106,6 +106,8 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<void>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L4:
@@ -142,7 +144,15 @@
}, (core::Object e, core::StackTrace s) → void {
completer.{asy::Completer::completeError}(e, s);
});
- :return_value = completer.{asy::Completer::future};
+ final asy::Future<void> #t7 = completer.{asy::Completer::future};
+ if(#t7 is asy::Future<void>) {
+ [yield] let dynamic #t8 = asy::_awaitHelper(#t7, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<void>(:result);
+ }
+ else {
+ :async_temporary_0 = #t7;
+ }
+ :return_value = :async_temporary_0;
break #L4;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
diff --git a/pkg/front_end/testcases/nnbd/return_from_async.dart b/pkg/front_end/testcases/nnbd/return_from_async.dart
new file mode 100644
index 0000000..93e646e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_from_async.dart
@@ -0,0 +1,98 @@
+// 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 file.
+
+import 'dart:async';
+
+bool caughtFutureOrInt = false;
+
+FutureOr<int> throwFutureOrInt() async {
+ throw 'FutureOr<int>';
+}
+
+Future<int> callFutureOrInt() async {
+ try {
+ return throwFutureOrInt();
+ } catch (e) {
+ print('Caught "$e"');
+ caughtFutureOrInt = true;
+ return 0;
+ }
+}
+
+bool caughtInt = false;
+
+int throwInt() {
+ throw 'int';
+}
+
+Future<int> callInt() async {
+ try {
+ return throwInt();
+ } catch (e) {
+ print('Caught "$e"');
+ caughtInt = true;
+ return 0;
+ }
+}
+
+bool caughtFutureInt = false;
+
+Future<int> throwFutureInt() async {
+ throw 'Future<int>';
+}
+
+Future<int> callFutureInt() async {
+ try {
+ return throwFutureInt();
+ } catch (e) {
+ print('Caught "$e"');
+ caughtFutureInt = true;
+ return 0;
+ }
+}
+
+bool caughtDynamic = false;
+
+dynamic throwDynamic() {
+ throw 'dynamic';
+}
+
+Future<int> callDynamic() async {
+ try {
+ return throwDynamic();
+ } catch (e) {
+ print('Caught "$e"');
+ caughtDynamic = true;
+ return 0;
+ }
+}
+
+bool caughtFutureNum = false;
+
+Future<int> throwFutureNum() async {
+ throw 'Future<num>';
+}
+
+Future<num> callFutureNum() async {
+ try {
+ return throwFutureNum();
+ } catch (e) {
+ print('Caught "$e"');
+ caughtFutureNum = true;
+ return 0;
+ }
+}
+
+void main() async {
+ await callFutureOrInt();
+ if (!caughtFutureOrInt) throw 'Uncaught async return';
+ await callInt();
+ if (!caughtInt) throw 'Uncaught async return';
+ await callFutureInt();
+ if (!caughtFutureInt) throw 'Uncaught async return';
+ await callDynamic();
+ if (!caughtDynamic) throw 'Uncaught async return';
+ await callFutureNum();
+ if (!caughtFutureNum) throw 'Uncaught async return';
+}
diff --git a/pkg/front_end/testcases/nnbd/return_from_async.dart.outline.expect b/pkg/front_end/testcases/nnbd/return_from_async.dart.outline.expect
new file mode 100644
index 0000000..fce58f8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_from_async.dart.outline.expect
@@ -0,0 +1,34 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+static field core::bool caughtFutureOrInt;
+static field core::bool caughtInt;
+static field core::bool caughtFutureInt;
+static field core::bool caughtDynamic;
+static field core::bool caughtFutureNum;
+static method throwFutureOrInt() → FutureOr<core::int> async
+ ;
+static method callFutureOrInt() → asy::Future<core::int> async
+ ;
+static method throwInt() → core::int
+ ;
+static method callInt() → asy::Future<core::int> async
+ ;
+static method throwFutureInt() → asy::Future<core::int> async
+ ;
+static method callFutureInt() → asy::Future<core::int> async
+ ;
+static method throwDynamic() → dynamic
+ ;
+static method callDynamic() → asy::Future<core::int> async
+ ;
+static method throwFutureNum() → asy::Future<core::int> async
+ ;
+static method callFutureNum() → asy::Future<core::num> async
+ ;
+static method main() → void async
+ ;
diff --git a/pkg/front_end/testcases/nnbd/return_from_async.dart.strong.expect b/pkg/front_end/testcases/nnbd/return_from_async.dart.strong.expect
new file mode 100644
index 0000000..07f9c6e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_from_async.dart.strong.expect
@@ -0,0 +1,94 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+static field core::bool caughtFutureOrInt = false;
+static field core::bool caughtInt = false;
+static field core::bool caughtFutureInt = false;
+static field core::bool caughtDynamic = false;
+static field core::bool caughtFutureNum = false;
+static method throwFutureOrInt() → FutureOr<core::int> async {
+ throw "FutureOr<int>";
+}
+static method callFutureOrInt() → asy::Future<core::int> async {
+ try {
+ return let final FutureOr<core::int>#t1 = self::throwFutureOrInt() in #t1 is asy::Future<core::int> ?{FutureOr<core::int>} await #t1 : #t1;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureOrInt = true;
+ return let final core::int #t2 = 0 in #t2 is asy::Future<core::int> ?{FutureOr<core::int>} await #t2 : #t2;
+ }
+}
+static method throwInt() → core::int {
+ throw "int";
+}
+static method callInt() → asy::Future<core::int> async {
+ try {
+ return let final core::int #t3 = self::throwInt() in #t3 is asy::Future<core::int> ?{FutureOr<core::int>} await #t3 : #t3;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtInt = true;
+ return let final core::int #t4 = 0 in #t4 is asy::Future<core::int> ?{FutureOr<core::int>} await #t4 : #t4;
+ }
+}
+static method throwFutureInt() → asy::Future<core::int> async {
+ throw "Future<int>";
+}
+static method callFutureInt() → asy::Future<core::int> async {
+ try {
+ return let final asy::Future<core::int> #t5 = self::throwFutureInt() in #t5 is asy::Future<core::int> ?{FutureOr<core::int>} await #t5 : #t5;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureInt = true;
+ return let final core::int #t6 = 0 in #t6 is asy::Future<core::int> ?{FutureOr<core::int>} await #t6 : #t6;
+ }
+}
+static method throwDynamic() → dynamic {
+ throw "dynamic";
+}
+static method callDynamic() → asy::Future<core::int> async {
+ try {
+ return let final dynamic #t7 = self::throwDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::int> in #t7 is asy::Future<core::int> ?{FutureOr<core::int>} await #t7 : #t7;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtDynamic = true;
+ return let final core::int #t8 = 0 in #t8 is asy::Future<core::int> ?{FutureOr<core::int>} await #t8 : #t8;
+ }
+}
+static method throwFutureNum() → asy::Future<core::int> async {
+ throw "Future<num>";
+}
+static method callFutureNum() → asy::Future<core::num> async {
+ try {
+ return let final asy::Future<core::int> #t9 = self::throwFutureNum() in #t9 is asy::Future<core::num> ?{FutureOr<core::num>} await #t9 : #t9;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureNum = true;
+ return let final core::int #t10 = 0 in #t10 is asy::Future<core::num> ?{FutureOr<core::num>} await #t10 : #t10;
+ }
+}
+static method main() → void async {
+ await self::callFutureOrInt();
+ if(!self::caughtFutureOrInt)
+ throw "Uncaught async return";
+ await self::callInt();
+ if(!self::caughtInt)
+ throw "Uncaught async return";
+ await self::callFutureInt();
+ if(!self::caughtFutureInt)
+ throw "Uncaught async return";
+ await self::callDynamic();
+ if(!self::caughtDynamic)
+ throw "Uncaught async return";
+ await self::callFutureNum();
+ if(!self::caughtFutureNum)
+ throw "Uncaught async return";
+}
diff --git a/pkg/front_end/testcases/nnbd/return_from_async.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/return_from_async.dart.strong.transformed.expect
new file mode 100644
index 0000000..5bd5d9f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_from_async.dart.strong.transformed.expect
@@ -0,0 +1,433 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "dart:_internal" as _in;
+
+import "dart:async";
+
+static field core::bool caughtFutureOrInt = false;
+static field core::bool caughtInt = false;
+static field core::bool caughtFutureInt = false;
+static field core::bool caughtDynamic = false;
+static field core::bool caughtFutureNum = false;
+static method throwFutureOrInt() → FutureOr<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L1:
+ {
+ throw "FutureOr<int>";
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method callFutureOrInt() → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ dynamic :exception0;
+ dynamic :stack_trace0;
+ FutureOr<core::int>:async_temporary_0;
+ FutureOr<core::int>:async_temporary_1;
+ FutureOr<core::int>:async_temporary_2;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L2:
+ {
+ try {
+ final FutureOr<core::int>#t1 = self::throwFutureOrInt();
+ if(#t1 is asy::Future<core::int>) {
+ [yield] let dynamic #t2 = asy::_awaitHelper(#t1, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t1;
+ }
+ :return_value = :async_temporary_0;
+ break #L2;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureOrInt = true;
+ final core::int #t3 = 0;
+ if(#t3 is asy::Future<core::int>) {
+ [yield] let dynamic #t4 = asy::_awaitHelper(#t3, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_2 = #t3;
+ }
+ :return_value = :async_temporary_2;
+ break #L2;
+ }
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method throwInt() → core::int {
+ throw "int";
+}
+static method callInt() → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ dynamic :exception0;
+ dynamic :stack_trace0;
+ FutureOr<core::int>:async_temporary_0;
+ FutureOr<core::int>:async_temporary_1;
+ FutureOr<core::int>:async_temporary_2;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L3:
+ {
+ try {
+ final core::int #t5 = self::throwInt();
+ if(#t5 is asy::Future<core::int>) {
+ [yield] let dynamic #t6 = asy::_awaitHelper(#t5, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t5;
+ }
+ :return_value = :async_temporary_0;
+ break #L3;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtInt = true;
+ final core::int #t7 = 0;
+ if(#t7 is asy::Future<core::int>) {
+ [yield] let dynamic #t8 = asy::_awaitHelper(#t7, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_2 = #t7;
+ }
+ :return_value = :async_temporary_2;
+ break #L3;
+ }
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method throwFutureInt() → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L4:
+ {
+ throw "Future<int>";
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method callFutureInt() → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ dynamic :exception0;
+ dynamic :stack_trace0;
+ FutureOr<core::int>:async_temporary_0;
+ FutureOr<core::int>:async_temporary_1;
+ FutureOr<core::int>:async_temporary_2;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L5:
+ {
+ try {
+ final asy::Future<core::int> #t9 = self::throwFutureInt();
+ if(#t9 is asy::Future<core::int>) {
+ [yield] let dynamic #t10 = asy::_awaitHelper(#t9, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t9;
+ }
+ :return_value = :async_temporary_0;
+ break #L5;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureInt = true;
+ final core::int #t11 = 0;
+ if(#t11 is asy::Future<core::int>) {
+ [yield] let dynamic #t12 = asy::_awaitHelper(#t11, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_2 = #t11;
+ }
+ :return_value = :async_temporary_2;
+ break #L5;
+ }
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method throwDynamic() → dynamic {
+ throw "dynamic";
+}
+static method callDynamic() → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ dynamic :exception0;
+ dynamic :stack_trace0;
+ FutureOr<core::int>:async_temporary_0;
+ FutureOr<core::int>:async_temporary_1;
+ FutureOr<core::int>:async_temporary_2;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L6:
+ {
+ try {
+ final FutureOr<core::int>#t13 = self::throwDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::int>;
+ if(#t13 is asy::Future<core::int>) {
+ [yield] let dynamic #t14 = asy::_awaitHelper(#t13, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t13;
+ }
+ :return_value = :async_temporary_0;
+ break #L6;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtDynamic = true;
+ final core::int #t15 = 0;
+ if(#t15 is asy::Future<core::int>) {
+ [yield] let dynamic #t16 = asy::_awaitHelper(#t15, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_2 = #t15;
+ }
+ :return_value = :async_temporary_2;
+ break #L6;
+ }
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method throwFutureNum() → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L7:
+ {
+ throw "Future<num>";
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method callFutureNum() → asy::Future<core::num> /* originally async */ {
+ final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
+ core::bool* :is_sync = false;
+ FutureOr<core::num>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ dynamic :exception0;
+ dynamic :stack_trace0;
+ FutureOr<core::num>:async_temporary_0;
+ FutureOr<core::num>:async_temporary_1;
+ FutureOr<core::num>:async_temporary_2;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L8:
+ {
+ try {
+ final asy::Future<core::int> #t17 = self::throwFutureNum();
+ if(#t17 is asy::Future<core::num>) {
+ [yield] let dynamic #t18 = asy::_awaitHelper(#t17, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t17;
+ }
+ :return_value = :async_temporary_0;
+ break #L8;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureNum = true;
+ final core::int #t19 = 0;
+ if(#t19 is asy::Future<core::num>) {
+ [yield] let dynamic #t20 = asy::_awaitHelper(#t19, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_2 = #t19;
+ }
+ :return_value = :async_temporary_2;
+ break #L8;
+ }
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method main() → void /* originally async */ {
+ final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+ core::bool* :is_sync = false;
+ FutureOr<dynamic>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L9:
+ {
+ [yield] let dynamic #t21 = asy::_awaitHelper(self::callFutureOrInt(), :async_op_then, :async_op_error, :async_op) in null;
+ _in::unsafeCast<core::int>(:result);
+ if(!self::caughtFutureOrInt)
+ throw "Uncaught async return";
+ [yield] let dynamic #t22 = asy::_awaitHelper(self::callInt(), :async_op_then, :async_op_error, :async_op) in null;
+ _in::unsafeCast<core::int>(:result);
+ if(!self::caughtInt)
+ throw "Uncaught async return";
+ [yield] let dynamic #t23 = asy::_awaitHelper(self::callFutureInt(), :async_op_then, :async_op_error, :async_op) in null;
+ _in::unsafeCast<core::int>(:result);
+ if(!self::caughtFutureInt)
+ throw "Uncaught async return";
+ [yield] let dynamic #t24 = asy::_awaitHelper(self::callDynamic(), :async_op_then, :async_op_error, :async_op) in null;
+ _in::unsafeCast<core::int>(:result);
+ if(!self::caughtDynamic)
+ throw "Uncaught async return";
+ [yield] let dynamic #t25 = asy::_awaitHelper(self::callFutureNum(), :async_op_then, :async_op_error, :async_op) in null;
+ _in::unsafeCast<core::num>(:result);
+ if(!self::caughtFutureNum)
+ throw "Uncaught async return";
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
diff --git a/pkg/front_end/testcases/nnbd/return_from_async.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/return_from_async.dart.textual_outline.expect
new file mode 100644
index 0000000..bc32d23
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_from_async.dart.textual_outline.expect
@@ -0,0 +1,18 @@
+import 'dart:async';
+
+bool caughtFutureOrInt = false;
+FutureOr<int> throwFutureOrInt() async {}
+Future<int> callFutureOrInt() async {}
+bool caughtInt = false;
+int throwInt() {}
+Future<int> callInt() async {}
+bool caughtFutureInt = false;
+Future<int> throwFutureInt() async {}
+Future<int> callFutureInt() async {}
+bool caughtDynamic = false;
+dynamic throwDynamic() {}
+Future<int> callDynamic() async {}
+bool caughtFutureNum = false;
+Future<int> throwFutureNum() async {}
+Future<num> callFutureNum() async {}
+void main() async {}
diff --git a/pkg/front_end/testcases/nnbd/return_from_async.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/return_from_async.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..7a7e905
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_from_async.dart.textual_outline_modelled.expect
@@ -0,0 +1,18 @@
+import 'dart:async';
+
+Future<int> callDynamic() async {}
+Future<int> callFutureInt() async {}
+Future<int> callFutureOrInt() async {}
+Future<int> callInt() async {}
+Future<int> throwFutureInt() async {}
+Future<int> throwFutureNum() async {}
+Future<num> callFutureNum() async {}
+FutureOr<int> throwFutureOrInt() async {}
+bool caughtDynamic = false;
+bool caughtFutureInt = false;
+bool caughtFutureNum = false;
+bool caughtFutureOrInt = false;
+bool caughtInt = false;
+dynamic throwDynamic() {}
+int throwInt() {}
+void main() async {}
diff --git a/pkg/front_end/testcases/nnbd/return_from_async.dart.weak.expect b/pkg/front_end/testcases/nnbd/return_from_async.dart.weak.expect
new file mode 100644
index 0000000..07f9c6e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_from_async.dart.weak.expect
@@ -0,0 +1,94 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+
+import "dart:async";
+
+static field core::bool caughtFutureOrInt = false;
+static field core::bool caughtInt = false;
+static field core::bool caughtFutureInt = false;
+static field core::bool caughtDynamic = false;
+static field core::bool caughtFutureNum = false;
+static method throwFutureOrInt() → FutureOr<core::int> async {
+ throw "FutureOr<int>";
+}
+static method callFutureOrInt() → asy::Future<core::int> async {
+ try {
+ return let final FutureOr<core::int>#t1 = self::throwFutureOrInt() in #t1 is asy::Future<core::int> ?{FutureOr<core::int>} await #t1 : #t1;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureOrInt = true;
+ return let final core::int #t2 = 0 in #t2 is asy::Future<core::int> ?{FutureOr<core::int>} await #t2 : #t2;
+ }
+}
+static method throwInt() → core::int {
+ throw "int";
+}
+static method callInt() → asy::Future<core::int> async {
+ try {
+ return let final core::int #t3 = self::throwInt() in #t3 is asy::Future<core::int> ?{FutureOr<core::int>} await #t3 : #t3;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtInt = true;
+ return let final core::int #t4 = 0 in #t4 is asy::Future<core::int> ?{FutureOr<core::int>} await #t4 : #t4;
+ }
+}
+static method throwFutureInt() → asy::Future<core::int> async {
+ throw "Future<int>";
+}
+static method callFutureInt() → asy::Future<core::int> async {
+ try {
+ return let final asy::Future<core::int> #t5 = self::throwFutureInt() in #t5 is asy::Future<core::int> ?{FutureOr<core::int>} await #t5 : #t5;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureInt = true;
+ return let final core::int #t6 = 0 in #t6 is asy::Future<core::int> ?{FutureOr<core::int>} await #t6 : #t6;
+ }
+}
+static method throwDynamic() → dynamic {
+ throw "dynamic";
+}
+static method callDynamic() → asy::Future<core::int> async {
+ try {
+ return let final dynamic #t7 = self::throwDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::int> in #t7 is asy::Future<core::int> ?{FutureOr<core::int>} await #t7 : #t7;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtDynamic = true;
+ return let final core::int #t8 = 0 in #t8 is asy::Future<core::int> ?{FutureOr<core::int>} await #t8 : #t8;
+ }
+}
+static method throwFutureNum() → asy::Future<core::int> async {
+ throw "Future<num>";
+}
+static method callFutureNum() → asy::Future<core::num> async {
+ try {
+ return let final asy::Future<core::int> #t9 = self::throwFutureNum() in #t9 is asy::Future<core::num> ?{FutureOr<core::num>} await #t9 : #t9;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureNum = true;
+ return let final core::int #t10 = 0 in #t10 is asy::Future<core::num> ?{FutureOr<core::num>} await #t10 : #t10;
+ }
+}
+static method main() → void async {
+ await self::callFutureOrInt();
+ if(!self::caughtFutureOrInt)
+ throw "Uncaught async return";
+ await self::callInt();
+ if(!self::caughtInt)
+ throw "Uncaught async return";
+ await self::callFutureInt();
+ if(!self::caughtFutureInt)
+ throw "Uncaught async return";
+ await self::callDynamic();
+ if(!self::caughtDynamic)
+ throw "Uncaught async return";
+ await self::callFutureNum();
+ if(!self::caughtFutureNum)
+ throw "Uncaught async return";
+}
diff --git a/pkg/front_end/testcases/nnbd/return_from_async.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/return_from_async.dart.weak.transformed.expect
new file mode 100644
index 0000000..5bd5d9f
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/return_from_async.dart.weak.transformed.expect
@@ -0,0 +1,433 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "dart:_internal" as _in;
+
+import "dart:async";
+
+static field core::bool caughtFutureOrInt = false;
+static field core::bool caughtInt = false;
+static field core::bool caughtFutureInt = false;
+static field core::bool caughtDynamic = false;
+static field core::bool caughtFutureNum = false;
+static method throwFutureOrInt() → FutureOr<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L1:
+ {
+ throw "FutureOr<int>";
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method callFutureOrInt() → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ dynamic :exception0;
+ dynamic :stack_trace0;
+ FutureOr<core::int>:async_temporary_0;
+ FutureOr<core::int>:async_temporary_1;
+ FutureOr<core::int>:async_temporary_2;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L2:
+ {
+ try {
+ final FutureOr<core::int>#t1 = self::throwFutureOrInt();
+ if(#t1 is asy::Future<core::int>) {
+ [yield] let dynamic #t2 = asy::_awaitHelper(#t1, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t1;
+ }
+ :return_value = :async_temporary_0;
+ break #L2;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureOrInt = true;
+ final core::int #t3 = 0;
+ if(#t3 is asy::Future<core::int>) {
+ [yield] let dynamic #t4 = asy::_awaitHelper(#t3, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_2 = #t3;
+ }
+ :return_value = :async_temporary_2;
+ break #L2;
+ }
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method throwInt() → core::int {
+ throw "int";
+}
+static method callInt() → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ dynamic :exception0;
+ dynamic :stack_trace0;
+ FutureOr<core::int>:async_temporary_0;
+ FutureOr<core::int>:async_temporary_1;
+ FutureOr<core::int>:async_temporary_2;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L3:
+ {
+ try {
+ final core::int #t5 = self::throwInt();
+ if(#t5 is asy::Future<core::int>) {
+ [yield] let dynamic #t6 = asy::_awaitHelper(#t5, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t5;
+ }
+ :return_value = :async_temporary_0;
+ break #L3;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtInt = true;
+ final core::int #t7 = 0;
+ if(#t7 is asy::Future<core::int>) {
+ [yield] let dynamic #t8 = asy::_awaitHelper(#t7, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_2 = #t7;
+ }
+ :return_value = :async_temporary_2;
+ break #L3;
+ }
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method throwFutureInt() → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L4:
+ {
+ throw "Future<int>";
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method callFutureInt() → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ dynamic :exception0;
+ dynamic :stack_trace0;
+ FutureOr<core::int>:async_temporary_0;
+ FutureOr<core::int>:async_temporary_1;
+ FutureOr<core::int>:async_temporary_2;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L5:
+ {
+ try {
+ final asy::Future<core::int> #t9 = self::throwFutureInt();
+ if(#t9 is asy::Future<core::int>) {
+ [yield] let dynamic #t10 = asy::_awaitHelper(#t9, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t9;
+ }
+ :return_value = :async_temporary_0;
+ break #L5;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureInt = true;
+ final core::int #t11 = 0;
+ if(#t11 is asy::Future<core::int>) {
+ [yield] let dynamic #t12 = asy::_awaitHelper(#t11, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_2 = #t11;
+ }
+ :return_value = :async_temporary_2;
+ break #L5;
+ }
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method throwDynamic() → dynamic {
+ throw "dynamic";
+}
+static method callDynamic() → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ dynamic :exception0;
+ dynamic :stack_trace0;
+ FutureOr<core::int>:async_temporary_0;
+ FutureOr<core::int>:async_temporary_1;
+ FutureOr<core::int>:async_temporary_2;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L6:
+ {
+ try {
+ final FutureOr<core::int>#t13 = self::throwDynamic() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::int>;
+ if(#t13 is asy::Future<core::int>) {
+ [yield] let dynamic #t14 = asy::_awaitHelper(#t13, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t13;
+ }
+ :return_value = :async_temporary_0;
+ break #L6;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtDynamic = true;
+ final core::int #t15 = 0;
+ if(#t15 is asy::Future<core::int>) {
+ [yield] let dynamic #t16 = asy::_awaitHelper(#t15, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_2 = #t15;
+ }
+ :return_value = :async_temporary_2;
+ break #L6;
+ }
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method throwFutureNum() → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L7:
+ {
+ throw "Future<num>";
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method callFutureNum() → asy::Future<core::num> /* originally async */ {
+ final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
+ core::bool* :is_sync = false;
+ FutureOr<core::num>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ dynamic :exception0;
+ dynamic :stack_trace0;
+ FutureOr<core::num>:async_temporary_0;
+ FutureOr<core::num>:async_temporary_1;
+ FutureOr<core::num>:async_temporary_2;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L8:
+ {
+ try {
+ final asy::Future<core::int> #t17 = self::throwFutureNum();
+ if(#t17 is asy::Future<core::num>) {
+ [yield] let dynamic #t18 = asy::_awaitHelper(#t17, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t17;
+ }
+ :return_value = :async_temporary_0;
+ break #L8;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureNum = true;
+ final core::int #t19 = 0;
+ if(#t19 is asy::Future<core::num>) {
+ [yield] let dynamic #t20 = asy::_awaitHelper(#t19, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_2 = #t19;
+ }
+ :return_value = :async_temporary_2;
+ break #L8;
+ }
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method main() → void /* originally async */ {
+ final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+ core::bool* :is_sync = false;
+ FutureOr<dynamic>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L9:
+ {
+ [yield] let dynamic #t21 = asy::_awaitHelper(self::callFutureOrInt(), :async_op_then, :async_op_error, :async_op) in null;
+ _in::unsafeCast<core::int>(:result);
+ if(!self::caughtFutureOrInt)
+ throw "Uncaught async return";
+ [yield] let dynamic #t22 = asy::_awaitHelper(self::callInt(), :async_op_then, :async_op_error, :async_op) in null;
+ _in::unsafeCast<core::int>(:result);
+ if(!self::caughtInt)
+ throw "Uncaught async return";
+ [yield] let dynamic #t23 = asy::_awaitHelper(self::callFutureInt(), :async_op_then, :async_op_error, :async_op) in null;
+ _in::unsafeCast<core::int>(:result);
+ if(!self::caughtFutureInt)
+ throw "Uncaught async return";
+ [yield] let dynamic #t24 = asy::_awaitHelper(self::callDynamic(), :async_op_then, :async_op_error, :async_op) in null;
+ _in::unsafeCast<core::int>(:result);
+ if(!self::caughtDynamic)
+ throw "Uncaught async return";
+ [yield] let dynamic #t25 = asy::_awaitHelper(self::callFutureNum(), :async_op_then, :async_op_error, :async_op) in null;
+ _in::unsafeCast<core::num>(:result);
+ if(!self::caughtFutureNum)
+ throw "Uncaught async return";
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect b/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect
index 70d918b..dab461b 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.strong.expect
@@ -103,7 +103,7 @@
static method returnAsync4() → FutureOr<core::int?> async {}
static method returnAsync5() → dynamic async {}
static method returnAsync6() → asy::Future<core::int?> async {
- return null;
+ return let final Null #t6 = null in #t6 is asy::Future<core::int?> ?{FutureOr<core::int?>} await #t6 : #t6;
}
static method returnAsync7() → asy::Future<core::int?> async {}
static method yieldSync() → core::Iterable<dynamic> sync* {}
@@ -133,7 +133,7 @@
default:
{}
}
- return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:54:6: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
+ return let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:54:6: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
- 'Enum' is from 'pkg/front_end/testcases/nnbd/return_null.dart'.
Enum caseReturn2(Enum e) /* error */ {
^" in null;
@@ -141,38 +141,38 @@
static method localFunctions() → dynamic {
function returnImplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:63:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:63:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String returnImplicit() /* error */ {
^" in null;
}
function returnExplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
+ return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
function returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
- return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
+ return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
- return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:72:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:72:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String returnMixed(bool b) /* error */ {
^" in null;
}
function returnAsync1() → asy::Future<dynamic> async {}
function returnAsync2() → FutureOr<dynamic> async {}
function returnAsync3() → FutureOr<core::int> async {
- return let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:83:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
+ return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:83:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
FutureOr<int> returnAsync3() async {} // error
^" in null;
}
function returnAsync4() → FutureOr<core::int?> async {}
function returnAsync5() → asy::Future<Null> async {}
function returnAsync6() → asy::Future<core::int?> async {
- return null;
+ return let final Null #t13 = null in #t13 is asy::Future<core::int?> ?{FutureOr<core::int?>} await #t13 : #t13;
}
function returnAsync7() → asy::Future<core::int?> async {}
function yieldSync() → core::Iterable<dynamic> sync* {}
@@ -202,7 +202,7 @@
default:
{}
}
- return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:108:3: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
+ return let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:108:3: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
- 'Enum' is from 'pkg/front_end/testcases/nnbd/return_null.dart'.
Enum caseReturn2(Enum e) /* error */ {
^" in null;
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 2b1a3dc..af2d2ae 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
@@ -55,6 +55,7 @@
import self as self;
import "dart:core" as core;
import "dart:async" as asy;
+import "dart:_internal" as _in;
import "dart:async";
@@ -226,11 +227,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::int?>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L6:
{
- :return_value = null;
+ final Null #t8 = null;
+ if(#t8 is asy::Future<core::int?>) {
+ [yield] let dynamic #t9 = asy::_awaitHelper(#t8, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Null>(:result);
+ }
+ else {
+ :async_temporary_0 = #t8;
+ }
+ :return_value = :async_temporary_0;
break #L6;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -332,7 +343,7 @@
default:
{}
}
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:54:6: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
+ return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:54:6: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
- 'Enum' is from 'pkg/front_end/testcases/nnbd/return_null.dart'.
Enum caseReturn2(Enum e) /* error */ {
^" in null;
@@ -340,24 +351,24 @@
static method localFunctions() → dynamic {
function returnImplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:63:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:63:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String returnImplicit() /* error */ {
^" in null;
}
function returnExplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
+ return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
return null; // error
- ^" in let Null #t11 = null in #t11.==(null) ?{core::String} #t11 as{TypeError,ForNonNullableByDefault} core::String : #t11{core::String};
+ ^" in let Null #t13 = null in #t13.==(null) ?{core::String} #t13 as{TypeError,ForNonNullableByDefault} core::String : #t13{core::String};
}
function returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
- return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
+ return let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
return null; // error
- ^" in let Null #t13 = null in #t13.==(null) ?{core::String} #t13 as{TypeError,ForNonNullableByDefault} core::String : #t13{core::String};
+ ^" in let Null #t15 = null in #t15.==(null) ?{core::String} #t15 as{TypeError,ForNonNullableByDefault} core::String : #t15{core::String};
}
- return let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:72:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:72:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String returnMixed(bool b) /* error */ {
^" in null;
}
@@ -421,7 +432,7 @@
try {
#L15:
{
- :return_value = let final<BottomType> #t15 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:83:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
+ :return_value = let final<BottomType> #t17 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:83:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
FutureOr<int> returnAsync3() async {} // error
^" in null;
break #L15;
@@ -494,11 +505,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::int?>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L18:
{
- :return_value = null;
+ final Null #t18 = null;
+ if(#t18 is asy::Future<core::int?>) {
+ [yield] let dynamic #t19 = asy::_awaitHelper(#t18, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Null>(:result);
+ }
+ else {
+ :async_temporary_0 = #t18;
+ }
+ :return_value = :async_temporary_0;
break #L18;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -600,7 +621,7 @@
default:
{}
}
- return let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:108:3: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
+ return let final<BottomType> #t20 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:108:3: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
- 'Enum' is from 'pkg/front_end/testcases/nnbd/return_null.dart'.
Enum caseReturn2(Enum e) /* error */ {
^" in null;
@@ -642,7 +663,7 @@
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: 394, effectively constant: 12
+Extra constant evaluation: evaluated: 422, effectively constant: 12
Constructor coverage from constants:
diff --git a/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect b/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect
index 0513741..aef28a4 100644
--- a/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/return_null.dart.weak.expect
@@ -104,7 +104,7 @@
static method returnAsync4() → FutureOr<core::int?> async {}
static method returnAsync5() → dynamic async {}
static method returnAsync6() → asy::Future<core::int?> async {
- return null;
+ return let final Null #t6 = null in #t6 is asy::Future<core::int?> ?{FutureOr<core::int?>} await #t6 : #t6;
}
static method returnAsync7() → asy::Future<core::int?> async {}
static method yieldSync() → core::Iterable<dynamic> sync* {}
@@ -137,7 +137,7 @@
default:
{}
}
- return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:54:6: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
+ return let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:54:6: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
- 'Enum' is from 'pkg/front_end/testcases/nnbd/return_null.dart'.
Enum caseReturn2(Enum e) /* error */ {
^" in null;
@@ -145,38 +145,38 @@
static method localFunctions() → dynamic {
function returnImplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:63:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:63:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String returnImplicit() /* error */ {
^" in null;
}
function returnExplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
+ return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
function returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
- return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
+ return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
return null; // error
^" in null as{TypeError,ForNonNullableByDefault} core::String;
}
- return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:72:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:72:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String returnMixed(bool b) /* error */ {
^" in null;
}
function returnAsync1() → asy::Future<dynamic> async {}
function returnAsync2() → FutureOr<dynamic> async {}
function returnAsync3() → FutureOr<core::int> async {
- return let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:83:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
+ return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:83:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
FutureOr<int> returnAsync3() async {} // error
^" in null;
}
function returnAsync4() → FutureOr<core::int?> async {}
function returnAsync5() → asy::Future<Null> async {}
function returnAsync6() → asy::Future<core::int?> async {
- return null;
+ return let final Null #t13 = null in #t13 is asy::Future<core::int?> ?{FutureOr<core::int?>} await #t13 : #t13;
}
function returnAsync7() → asy::Future<core::int?> async {}
function yieldSync() → core::Iterable<dynamic> sync* {}
@@ -209,7 +209,7 @@
default:
{}
}
- return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:108:3: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
+ return let final<BottomType> #t14 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:108:3: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
- 'Enum' is from 'pkg/front_end/testcases/nnbd/return_null.dart'.
Enum caseReturn2(Enum e) /* error */ {
^" in null;
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 3643cf7..dba40e5 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
@@ -227,11 +227,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::int?>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L6:
{
- :return_value = null;
+ final Null #t6 = null;
+ if(#t6 is asy::Future<core::int?>) {
+ [yield] let dynamic #t7 = asy::_awaitHelper(#t6, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Null>(:result);
+ }
+ else {
+ :async_temporary_0 = #t6;
+ }
+ :return_value = :async_temporary_0;
break #L6;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -336,7 +346,7 @@
default:
{}
}
- return let final<BottomType> #t6 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:54:6: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
+ return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:54:6: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
- 'Enum' is from 'pkg/front_end/testcases/nnbd/return_null.dart'.
Enum caseReturn2(Enum e) /* error */ {
^" in null;
@@ -344,24 +354,24 @@
static method localFunctions() → dynamic {
function returnImplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t7 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:63:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:63:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String returnImplicit() /* error */ {
^" in null;
}
function returnExplicit() → core::String {
core::print("foo");
- return let final<BottomType> #t8 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
+ return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:69:12: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
return null; // error
^" in null;
}
function returnMixed(core::bool b) → core::String {
if(b) {
core::print("foo");
- return let final<BottomType> #t9 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
+ return let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:75:14: Error: The value 'null' can't be returned from a function with return type 'String' because 'String' is not nullable.
return null; // error
^" in null;
}
- return let final<BottomType> #t10 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:72:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
+ return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:72:3: Error: A non-null value must be returned since the return type 'String' doesn't allow null.
String returnMixed(bool b) /* error */ {
^" in null;
}
@@ -425,7 +435,7 @@
try {
#L16:
{
- :return_value = let final<BottomType> #t11 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:83:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
+ :return_value = let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:83:3: Error: A non-null value must be returned since the return type 'int' doesn't allow null.
FutureOr<int> returnAsync3() async {} // error
^" in null;
break #L16;
@@ -498,11 +508,21 @@
(core::Object, core::StackTrace) → dynamic :async_op_error;
core::int :await_jump_var = 0;
dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ FutureOr<core::int?>:async_temporary_0;
function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
try {
#L19:
{
- :return_value = null;
+ final Null #t14 = null;
+ if(#t14 is asy::Future<core::int?>) {
+ [yield] let dynamic #t15 = asy::_awaitHelper(#t14, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<Null>(:result);
+ }
+ else {
+ :async_temporary_0 = #t14;
+ }
+ :return_value = :async_temporary_0;
break #L19;
}
asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
@@ -607,7 +627,7 @@
default:
{}
}
- return let final<BottomType> #t12 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:108:3: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
+ return let final<BottomType> #t16 = invalid-expression "pkg/front_end/testcases/nnbd/return_null.dart:108:3: Error: A non-null value must be returned since the return type 'Enum' doesn't allow null.
- 'Enum' is from 'pkg/front_end/testcases/nnbd/return_null.dart'.
Enum caseReturn2(Enum e) /* error */ {
^" in null;
diff --git a/pkg/front_end/testcases/nnbd_mixed/return_from_async.dart b/pkg/front_end/testcases/nnbd_mixed/return_from_async.dart
new file mode 100644
index 0000000..5b167d0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/return_from_async.dart
@@ -0,0 +1,92 @@
+// 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 file.
+
+import 'dart:async';
+import 'return_from_async_lib.dart';
+
+abstract class Class {
+ FutureOr<int> throwFutureOrInt();
+
+ int throwInt();
+
+ Future<int> throwFutureInt();
+
+ dynamic throwDynamic();
+
+ Future<num> throwFutureNum();
+}
+
+bool caughtFutureOrInt = false;
+
+Future<int> callFutureOrInt(Class c) async {
+ try {
+ return c.throwFutureOrInt();
+ } catch (e) {
+ print('Caught "$e"');
+ caughtFutureOrInt = true;
+ return 0;
+ }
+}
+
+bool caughtInt = false;
+
+Future<int> callInt(Class c) async {
+ try {
+ return c.throwInt();
+ } catch (e) {
+ print('Caught "$e"');
+ caughtInt = true;
+ return 0;
+ }
+}
+
+bool caughtFutureInt = false;
+
+Future<int> callFutureInt(Class c) async {
+ try {
+ return c.throwFutureInt();
+ } catch (e) {
+ print('Caught "$e"');
+ caughtFutureInt = true;
+ return 0;
+ }
+}
+
+bool caughtDynamic = false;
+
+Future<int> callDynamic(Class c) async {
+ try {
+ return c.throwDynamic();
+ } catch (e) {
+ print('Caught "$e"');
+ caughtDynamic = true;
+ return 0;
+ }
+}
+
+bool caughtFutureNum = false;
+
+Future<num> callFutureNum(Class c) async {
+ try {
+ return c.throwFutureNum();
+ } catch (e) {
+ print('Caught "$e"');
+ caughtFutureNum = true;
+ return 0;
+ }
+}
+
+void main() async {
+ Class c = new Subclass();
+ await callFutureOrInt(c);
+ if (!caughtFutureOrInt) throw 'Uncaught async return';
+ await callInt(c);
+ if (!caughtInt) throw 'Uncaught async return';
+ await callFutureInt(c);
+ if (!caughtFutureInt) throw 'Uncaught async return';
+ await callDynamic(c);
+ if (!caughtDynamic) throw 'Uncaught async return';
+ await callFutureNum(c);
+ if (!caughtFutureNum) throw 'Uncaught async return';
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/return_from_async.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/return_from_async.dart.textual_outline.expect
new file mode 100644
index 0000000..66339b5
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/return_from_async.dart.textual_outline.expect
@@ -0,0 +1,22 @@
+import 'dart:async';
+import 'return_from_async_lib.dart';
+
+abstract class Class {
+ FutureOr<int> throwFutureOrInt();
+ int throwInt();
+ Future<int> throwFutureInt();
+ dynamic throwDynamic();
+ Future<num> throwFutureNum();
+}
+
+bool caughtFutureOrInt = false;
+Future<int> callFutureOrInt(Class c) async {}
+bool caughtInt = false;
+Future<int> callInt(Class c) async {}
+bool caughtFutureInt = false;
+Future<int> callFutureInt(Class c) async {}
+bool caughtDynamic = false;
+Future<int> callDynamic(Class c) async {}
+bool caughtFutureNum = false;
+Future<num> callFutureNum(Class c) async {}
+void main() async {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/return_from_async.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/return_from_async.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..3c8dcd7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/return_from_async.dart.textual_outline_modelled.expect
@@ -0,0 +1,23 @@
+import 'dart:async';
+import 'return_from_async_lib.dart';
+
+Future<int> callDynamic(Class c) async {}
+Future<int> callFutureInt(Class c) async {}
+Future<int> callFutureOrInt(Class c) async {}
+Future<int> callInt(Class c) async {}
+Future<num> callFutureNum(Class c) async {}
+
+abstract class Class {
+ Future<int> throwFutureInt();
+ Future<num> throwFutureNum();
+ FutureOr<int> throwFutureOrInt();
+ dynamic throwDynamic();
+ int throwInt();
+}
+
+bool caughtDynamic = false;
+bool caughtFutureInt = false;
+bool caughtFutureNum = false;
+bool caughtFutureOrInt = false;
+bool caughtInt = false;
+void main() async {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/return_from_async.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/return_from_async.dart.weak.expect
new file mode 100644
index 0000000..0a614de
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/return_from_async.dart.weak.expect
@@ -0,0 +1,122 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "return_from_async_lib.dart" as ret;
+
+import "dart:async";
+import "org-dartlang-testcase:///return_from_async_lib.dart";
+
+abstract class Class extends core::Object {
+ synthetic constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ abstract method throwFutureOrInt() → FutureOr<core::int>;
+ abstract method throwInt() → core::int;
+ abstract method throwFutureInt() → asy::Future<core::int>;
+ abstract method throwDynamic() → dynamic;
+ abstract method throwFutureNum() → asy::Future<core::num>;
+}
+static field core::bool caughtFutureOrInt = false;
+static field core::bool caughtInt = false;
+static field core::bool caughtFutureInt = false;
+static field core::bool caughtDynamic = false;
+static field core::bool caughtFutureNum = false;
+static method callFutureOrInt(self::Class c) → asy::Future<core::int> async {
+ try {
+ return let final FutureOr<core::int>#t1 = c.{self::Class::throwFutureOrInt}() in #t1 is asy::Future<core::int> ?{FutureOr<core::int>} await #t1 : #t1;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureOrInt = true;
+ return let final core::int #t2 = 0 in #t2 is asy::Future<core::int> ?{FutureOr<core::int>} await #t2 : #t2;
+ }
+}
+static method callInt(self::Class c) → asy::Future<core::int> async {
+ try {
+ return let final core::int #t3 = c.{self::Class::throwInt}() in #t3 is asy::Future<core::int> ?{FutureOr<core::int>} await #t3 : #t3;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtInt = true;
+ return let final core::int #t4 = 0 in #t4 is asy::Future<core::int> ?{FutureOr<core::int>} await #t4 : #t4;
+ }
+}
+static method callFutureInt(self::Class c) → asy::Future<core::int> async {
+ try {
+ return let final asy::Future<core::int> #t5 = c.{self::Class::throwFutureInt}() in #t5 is asy::Future<core::int> ?{FutureOr<core::int>} await #t5 : #t5;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureInt = true;
+ return let final core::int #t6 = 0 in #t6 is asy::Future<core::int> ?{FutureOr<core::int>} await #t6 : #t6;
+ }
+}
+static method callDynamic(self::Class c) → asy::Future<core::int> async {
+ try {
+ return let final dynamic #t7 = c.{self::Class::throwDynamic}() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::int> in #t7 is asy::Future<core::int> ?{FutureOr<core::int>} await #t7 : #t7;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtDynamic = true;
+ return let final core::int #t8 = 0 in #t8 is asy::Future<core::int> ?{FutureOr<core::int>} await #t8 : #t8;
+ }
+}
+static method callFutureNum(self::Class c) → asy::Future<core::num> async {
+ try {
+ return let final asy::Future<core::num> #t9 = c.{self::Class::throwFutureNum}() in #t9 is asy::Future<core::num> ?{FutureOr<core::num>} await #t9 : #t9;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureNum = true;
+ return let final core::int #t10 = 0 in #t10 is asy::Future<core::num> ?{FutureOr<core::num>} await #t10 : #t10;
+ }
+}
+static method main() → void async {
+ self::Class c = new ret::Subclass::•();
+ await self::callFutureOrInt(c);
+ if(!self::caughtFutureOrInt)
+ throw "Uncaught async return";
+ await self::callInt(c);
+ if(!self::caughtInt)
+ throw "Uncaught async return";
+ await self::callFutureInt(c);
+ if(!self::caughtFutureInt)
+ throw "Uncaught async return";
+ await self::callDynamic(c);
+ if(!self::caughtDynamic)
+ throw "Uncaught async return";
+ await self::callFutureNum(c);
+ if(!self::caughtFutureNum)
+ throw "Uncaught async return";
+}
+
+library /*isNonNullableByDefault*/;
+import self as ret;
+import "dart:core" as core;
+import "return_from_async.dart" as self;
+import "dart:async" as asy;
+
+import "dart:async";
+import "org-dartlang-testcase:///return_from_async.dart";
+
+class Subclass extends core::Object implements self::Class {
+ synthetic constructor •() → ret::Subclass
+ : super core::Object::•()
+ ;
+ method throwFutureOrInt() → FutureOr<core::int> async {
+ throw "FutureOr<int>";
+ }
+ method throwInt() → core::int {
+ throw "int";
+ }
+ method throwFutureInt() → asy::Future<core::int> async {
+ throw "Future<int>";
+ }
+ method throwDynamic() → dynamic {
+ throw "dynamic";
+ }
+ method throwFutureNum() → asy::Future<core::num> async {
+ throw "Future<num>";
+ }
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/return_from_async.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/return_from_async.dart.weak.transformed.expect
new file mode 100644
index 0000000..1924b7e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/return_from_async.dart.weak.transformed.expect
@@ -0,0 +1,461 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "dart:async" as asy;
+import "dart:_internal" as _in;
+import "return_from_async_lib.dart" as ret;
+
+import "dart:async";
+import "org-dartlang-testcase:///return_from_async_lib.dart";
+
+abstract class Class extends core::Object {
+ synthetic constructor •() → self::Class
+ : super core::Object::•()
+ ;
+ abstract method throwFutureOrInt() → FutureOr<core::int>;
+ abstract method throwInt() → core::int;
+ abstract method throwFutureInt() → asy::Future<core::int>;
+ abstract method throwDynamic() → dynamic;
+ abstract method throwFutureNum() → asy::Future<core::num>;
+}
+static field core::bool caughtFutureOrInt = false;
+static field core::bool caughtInt = false;
+static field core::bool caughtFutureInt = false;
+static field core::bool caughtDynamic = false;
+static field core::bool caughtFutureNum = false;
+static method callFutureOrInt(self::Class c) → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ dynamic :exception0;
+ dynamic :stack_trace0;
+ FutureOr<core::int>:async_temporary_0;
+ FutureOr<core::int>:async_temporary_1;
+ FutureOr<core::int>:async_temporary_2;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L1:
+ {
+ try {
+ final FutureOr<core::int>#t1 = c.{self::Class::throwFutureOrInt}();
+ if(#t1 is asy::Future<core::int>) {
+ [yield] let dynamic #t2 = asy::_awaitHelper(#t1, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t1;
+ }
+ :return_value = :async_temporary_0;
+ break #L1;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureOrInt = true;
+ final core::int #t3 = 0;
+ if(#t3 is asy::Future<core::int>) {
+ [yield] let dynamic #t4 = asy::_awaitHelper(#t3, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_2 = #t3;
+ }
+ :return_value = :async_temporary_2;
+ break #L1;
+ }
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method callInt(self::Class c) → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ dynamic :exception0;
+ dynamic :stack_trace0;
+ FutureOr<core::int>:async_temporary_0;
+ FutureOr<core::int>:async_temporary_1;
+ FutureOr<core::int>:async_temporary_2;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L2:
+ {
+ try {
+ final core::int #t5 = c.{self::Class::throwInt}();
+ if(#t5 is asy::Future<core::int>) {
+ [yield] let dynamic #t6 = asy::_awaitHelper(#t5, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t5;
+ }
+ :return_value = :async_temporary_0;
+ break #L2;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtInt = true;
+ final core::int #t7 = 0;
+ if(#t7 is asy::Future<core::int>) {
+ [yield] let dynamic #t8 = asy::_awaitHelper(#t7, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_2 = #t7;
+ }
+ :return_value = :async_temporary_2;
+ break #L2;
+ }
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method callFutureInt(self::Class c) → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ dynamic :exception0;
+ dynamic :stack_trace0;
+ FutureOr<core::int>:async_temporary_0;
+ FutureOr<core::int>:async_temporary_1;
+ FutureOr<core::int>:async_temporary_2;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L3:
+ {
+ try {
+ final asy::Future<core::int> #t9 = c.{self::Class::throwFutureInt}();
+ if(#t9 is asy::Future<core::int>) {
+ [yield] let dynamic #t10 = asy::_awaitHelper(#t9, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t9;
+ }
+ :return_value = :async_temporary_0;
+ break #L3;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureInt = true;
+ final core::int #t11 = 0;
+ if(#t11 is asy::Future<core::int>) {
+ [yield] let dynamic #t12 = asy::_awaitHelper(#t11, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_2 = #t11;
+ }
+ :return_value = :async_temporary_2;
+ break #L3;
+ }
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method callDynamic(self::Class c) → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ dynamic :exception0;
+ dynamic :stack_trace0;
+ FutureOr<core::int>:async_temporary_0;
+ FutureOr<core::int>:async_temporary_1;
+ FutureOr<core::int>:async_temporary_2;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L4:
+ {
+ try {
+ final FutureOr<core::int>#t13 = c.{self::Class::throwDynamic}() as{TypeError,ForDynamic,ForNonNullableByDefault} FutureOr<core::int>;
+ if(#t13 is asy::Future<core::int>) {
+ [yield] let dynamic #t14 = asy::_awaitHelper(#t13, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_0 = #t13;
+ }
+ :return_value = :async_temporary_0;
+ break #L4;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtDynamic = true;
+ final core::int #t15 = 0;
+ if(#t15 is asy::Future<core::int>) {
+ [yield] let dynamic #t16 = asy::_awaitHelper(#t15, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_2 = #t15;
+ }
+ :return_value = :async_temporary_2;
+ break #L4;
+ }
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method callFutureNum(self::Class c) → asy::Future<core::num> /* originally async */ {
+ final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
+ core::bool* :is_sync = false;
+ FutureOr<core::num>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ dynamic :saved_try_context_var1;
+ dynamic :exception0;
+ dynamic :stack_trace0;
+ FutureOr<core::num>:async_temporary_0;
+ FutureOr<core::num>:async_temporary_1;
+ FutureOr<core::num>:async_temporary_2;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L5:
+ {
+ try {
+ final asy::Future<core::num> #t17 = c.{self::Class::throwFutureNum}();
+ if(#t17 is asy::Future<core::num>) {
+ [yield] let dynamic #t18 = asy::_awaitHelper(#t17, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_0 = _in::unsafeCast<core::num>(:result);
+ }
+ else {
+ :async_temporary_0 = #t17;
+ }
+ :return_value = :async_temporary_0;
+ break #L5;
+ }
+ on core::Object catch(final core::Object e) {
+ core::print("Caught \"${e}\"");
+ self::caughtFutureNum = true;
+ final core::int #t19 = 0;
+ if(#t19 is asy::Future<core::num>) {
+ [yield] let dynamic #t20 = asy::_awaitHelper(#t19, :async_op_then, :async_op_error, :async_op) in null;
+ :async_temporary_2 = _in::unsafeCast<core::int>(:result);
+ }
+ else {
+ :async_temporary_2 = #t19;
+ }
+ :return_value = :async_temporary_2;
+ break #L5;
+ }
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+static method main() → void /* originally async */ {
+ final asy::_Future<dynamic> :async_future = new asy::_Future::•<dynamic>();
+ core::bool* :is_sync = false;
+ FutureOr<dynamic>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ dynamic :saved_try_context_var0;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L6:
+ {
+ self::Class c = new ret::Subclass::•();
+ [yield] let dynamic #t21 = asy::_awaitHelper(self::callFutureOrInt(c), :async_op_then, :async_op_error, :async_op) in null;
+ _in::unsafeCast<core::int>(:result);
+ if(!self::caughtFutureOrInt)
+ throw "Uncaught async return";
+ [yield] let dynamic #t22 = asy::_awaitHelper(self::callInt(c), :async_op_then, :async_op_error, :async_op) in null;
+ _in::unsafeCast<core::int>(:result);
+ if(!self::caughtInt)
+ throw "Uncaught async return";
+ [yield] let dynamic #t23 = asy::_awaitHelper(self::callFutureInt(c), :async_op_then, :async_op_error, :async_op) in null;
+ _in::unsafeCast<core::int>(:result);
+ if(!self::caughtFutureInt)
+ throw "Uncaught async return";
+ [yield] let dynamic #t24 = asy::_awaitHelper(self::callDynamic(c), :async_op_then, :async_op_error, :async_op) in null;
+ _in::unsafeCast<core::int>(:result);
+ if(!self::caughtDynamic)
+ throw "Uncaught async return";
+ [yield] let dynamic #t25 = asy::_awaitHelper(self::callFutureNum(c), :async_op_then, :async_op_error, :async_op) in null;
+ _in::unsafeCast<core::num>(:result);
+ if(!self::caughtFutureNum)
+ throw "Uncaught async return";
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+}
+
+library /*isNonNullableByDefault*/;
+import self as ret;
+import "dart:core" as core;
+import "return_from_async.dart" as self;
+import "dart:async" as asy;
+
+import "dart:async";
+import "org-dartlang-testcase:///return_from_async.dart";
+
+class Subclass extends core::Object implements self::Class {
+ synthetic constructor •() → ret::Subclass
+ : super core::Object::•()
+ ;
+ method throwFutureOrInt() → FutureOr<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L7:
+ {
+ throw "FutureOr<int>";
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+ }
+ method throwInt() → core::int {
+ throw "int";
+ }
+ method throwFutureInt() → asy::Future<core::int> /* originally async */ {
+ final asy::_Future<core::int> :async_future = new asy::_Future::•<core::int>();
+ core::bool* :is_sync = false;
+ FutureOr<core::int>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L8:
+ {
+ throw "Future<int>";
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+ }
+ method throwDynamic() → dynamic {
+ throw "dynamic";
+ }
+ method throwFutureNum() → asy::Future<core::num> /* originally async */ {
+ final asy::_Future<core::num> :async_future = new asy::_Future::•<core::num>();
+ core::bool* :is_sync = false;
+ FutureOr<core::num>? :return_value;
+ (dynamic) → dynamic :async_op_then;
+ (core::Object, core::StackTrace) → dynamic :async_op_error;
+ core::int :await_jump_var = 0;
+ dynamic :await_ctx_var;
+ function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding
+ try {
+ #L9:
+ {
+ throw "Future<num>";
+ }
+ asy::_completeOnAsyncReturn(:async_future, :return_value, :is_sync);
+ return;
+ }
+ on dynamic catch(dynamic exception, core::StackTrace stack_trace) {
+ asy::_completeOnAsyncError(:async_future, exception, stack_trace, :is_sync);
+ }
+ :async_op_then = asy::_asyncThenWrapperHelper(:async_op);
+ :async_op_error = asy::_asyncErrorWrapperHelper(:async_op);
+ :async_op.call();
+ :is_sync = true;
+ return :async_future;
+ }
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/return_from_async_lib.dart b/pkg/front_end/testcases/nnbd_mixed/return_from_async_lib.dart
new file mode 100644
index 0000000..0e4cbb7
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/return_from_async_lib.dart
@@ -0,0 +1,28 @@
+// 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 file.
+
+import 'dart:async';
+import 'return_from_async.dart';
+
+class Subclass implements Class {
+ FutureOr<int> throwFutureOrInt() async {
+ throw 'FutureOr<int>';
+ }
+
+ int throwInt() {
+ throw 'int';
+ }
+
+ Future<int> throwFutureInt() async {
+ throw 'Future<int>';
+ }
+
+ dynamic throwDynamic() {
+ throw 'dynamic';
+ }
+
+ Future<num> throwFutureNum() async {
+ throw 'Future<num>';
+ }
+}
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 2e35c64..bbb5c64 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -171,7 +171,6 @@
nnbd/covariant_late_field: TypeCheckError
nnbd/getter_vs_setter_type: TypeCheckError
nnbd/issue41180: RuntimeError # Strong mode runtime checking fails due to mixed strong mode.
-nnbd/issue42546: TypeCheckError
nnbd/issue42603: TypeCheckError
nnbd/no_support_for_old_null_aware_index_access_syntax: RuntimeError # Expected.
nnbd/nullable_object_access: TypeCheckError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index a59dfcd..c21c124 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -171,7 +171,6 @@
nnbd/covariant_late_field: TypeCheckError
nnbd/getter_vs_setter_type: TypeCheckError
nnbd/issue41180: RuntimeError
-nnbd/issue42546: TypeCheckError
nnbd/issue42603: TypeCheckError
nnbd/no_support_for_old_null_aware_index_access_syntax: RuntimeError # Expected.
nnbd/nullable_object_access: TypeCheckError
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index 56c47dc..731df3e 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -58,7 +58,6 @@
late_lowering/covariant_late_field: TypeCheckError
nnbd/covariant_late_field: TypeCheckError
nnbd/getter_vs_setter_type: TypeCheckError
-nnbd/issue42546: TypeCheckError
nnbd/issue42603: TypeCheckError
nnbd/no_support_for_old_null_aware_index_access_syntax: RuntimeError # Expected.
nnbd/nullable_object_access: TypeCheckError
diff --git a/pkg/front_end/tool/_fasta/command_line.dart b/pkg/front_end/tool/_fasta/command_line.dart
index 4eb7083..09c977b 100644
--- a/pkg/front_end/tool/_fasta/command_line.dart
+++ b/pkg/front_end/tool/_fasta/command_line.dart
@@ -195,6 +195,7 @@
Flags.nnbdAgnosticMode: const BoolValue(false),
Flags.target: const StringValue(),
Flags.verbose: const BoolValue(false),
+ Flags.verbosity: const StringValue(),
Flags.verify: const BoolValue(false),
Flags.verifySkipPlatform: const BoolValue(false),
Flags.warnOnReachabilityCheck: const BoolValue(false),
@@ -308,6 +309,8 @@
final String invocationModes = options[Flags.invocationModes] ?? '';
+ final String verbosity = options[Flags.verbosity] ?? Verbosity.defaultValue;
+
if (nnbdStrongMode && nnbdWeakMode) {
return throw new CommandLineProblem.deprecated(
"Can't specify both '${Flags.nnbdStrongMode}' and "
@@ -359,7 +362,8 @@
..additionalDills = linkDependencies
..emitDeps = !noDeps
..warnOnReachabilityCheck = warnOnReachabilityCheck
- ..invocationModes = InvocationMode.parseArguments(invocationModes);
+ ..invocationModes = InvocationMode.parseArguments(invocationModes)
+ ..verbosity = Verbosity.parseArgument(verbosity);
if (programName == "compile_platform") {
if (arguments.length != 5) {
diff --git a/pkg/nnbd_migration/lib/src/preview/preview_site.dart b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
index c02b3c1..bd690a9 100644
--- a/pkg/nnbd_migration/lib/src/preview/preview_site.dart
+++ b/pkg/nnbd_migration/lib/src/preview/preview_site.dart
@@ -220,22 +220,26 @@
if (line.length > lineStart + 1 &&
line.codeUnitAt(lineStart) == $slash &&
line.codeUnitAt(lineStart + 1) == $slash) {
- // Comment.
+ // [line] is a comment.
+
if (index == length) {
// [code] consists _only_ of one comment line.
return '$code$newline$newline// @dart=2.9$newline';
}
var previousLineIndex = index;
+ String newlinesAfterDlvc;
while (true) {
previousLineIndex = index;
line = getLine();
lineStart = line.indexOf(_nonWhitespaceChar);
if (lineStart < 0) {
- // Line of whitespace; end of block comment.
+ // Line of zero-or-more whitespace; end of block comment.
+ newlinesAfterDlvc = newline;
break;
}
if (line.length <= lineStart + 1) {
// Only one character; not a comment; end of block comment.
+ newlinesAfterDlvc = '$newline$newline';
break;
}
if (line.codeUnitAt(lineStart) == $slash &&
@@ -248,13 +252,14 @@
continue;
} else {
// Non-blank, non-comment line.
+ newlinesAfterDlvc = '$newline$newline';
break;
}
}
// [previousLineIndex] points to the start of [line], which is the first
// non-comment line following the first comment.
return '${code.substring(0, previousLineIndex)}$newline'
- '// @dart=2.9$newline$newline'
+ '// @dart=2.9$newlinesAfterDlvc'
'${code.substring(previousLineIndex)}';
} else {
// [code] does not start with a block comment.
diff --git a/pkg/nnbd_migration/test/preview/preview_site_test.dart b/pkg/nnbd_migration/test/preview/preview_site_test.dart
index d351962..550cd92 100644
--- a/pkg/nnbd_migration/test/preview/preview_site_test.dart
+++ b/pkg/nnbd_migration/test/preview/preview_site_test.dart
@@ -156,14 +156,20 @@
void test_optOutOfNullSafety_commentThenCode() {
expect(
IncrementalPlan.optCodeOutOfNullSafety('// comment\n\nvoid main() {}'),
- equals('// comment\n\n// @dart=2.9\n\n\nvoid main() {}'));
+ equals('// comment\n\n// @dart=2.9\n\nvoid main() {}'));
+ }
+
+ void test_optOutOfNullSafety_commentThenSemicolon() {
+ expect(
+ IncrementalPlan.optCodeOutOfNullSafety('// comment\n;\nvoid main() {}'),
+ equals('// comment\n\n// @dart=2.9\n\n;\nvoid main() {}'));
}
void test_optOutOfNullSafety_commentThenCode_windows() {
expect(
IncrementalPlan.optCodeOutOfNullSafety(
'// comment\r\n\r\nvoid main() {}'),
- equals('// comment\r\n\r\n// @dart=2.9\r\n\r\n\r\nvoid main() {}'));
+ equals('// comment\r\n\r\n// @dart=2.9\r\n\r\nvoid main() {}'));
}
void test_optOutOfNullSafety_commentThenDirective() {
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 5f226e7..2a57c7b 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -95,7 +95,8 @@
List<String> experimentalFlags,
Uri packagesUri,
List<String> errors,
- String invocationModes) {
+ String invocationModes,
+ String verbosityLevel) {
final expFlags = <String>[];
if (experimentalFlags != null) {
for (String flag in experimentalFlags) {
@@ -103,6 +104,7 @@
}
}
+ Verbosity verbosity = Verbosity.parseArgument(verbosityLevel);
return new CompilerOptions()
..fileSystem = fileSystem
..target = new VmTarget(new TargetFlags(
@@ -139,13 +141,16 @@
case Severity.ignored:
throw "Unexpected severity: ${message.severity}";
}
- if (printToStdErr) {
- printDiagnosticMessage(message, stderr.writeln);
- } else if (printToStdOut) {
- printDiagnosticMessage(message, stdout.writeln);
+ if (Verbosity.shouldPrint(verbosity, message)) {
+ if (printToStdErr) {
+ printDiagnosticMessage(message, stderr.writeln);
+ } else if (printToStdOut) {
+ printDiagnosticMessage(message, stdout.writeln);
+ }
}
}
- ..invocationModes = InvocationMode.parseArguments(invocationModes);
+ ..invocationModes = InvocationMode.parseArguments(invocationModes)
+ ..verbosity = verbosity;
}
abstract class Compiler {
@@ -158,6 +163,7 @@
final List<String> experimentalFlags;
final String packageConfig;
final String invocationModes;
+ final String verbosityLevel;
// Code coverage and hot reload are only supported by incremental compiler,
// which is used if vm-service is enabled.
@@ -176,7 +182,8 @@
this.supportCodeCoverage: false,
this.supportHotReload: false,
this.packageConfig: null,
- this.invocationModes: ''}) {
+ this.invocationModes: '',
+ this.verbosityLevel: Verbosity.defaultValue}) {
Uri packagesUri = null;
if (packageConfig != null) {
packagesUri = Uri.parse(packageConfig);
@@ -200,7 +207,8 @@
experimentalFlags,
packagesUri,
errors,
- invocationModes);
+ invocationModes,
+ verbosityLevel);
}
Future<CompilerResult> compile(Uri script) {
@@ -291,7 +299,8 @@
int nullSafety: kNullSafetyOptionUnspecified,
List<String> experimentalFlags: null,
String packageConfig: null,
- String invocationModes: ''})
+ String invocationModes: '',
+ String verbosityLevel: Verbosity.defaultValue})
: super(isolateId, fileSystem, platformKernelPath,
suppressWarnings: suppressWarnings,
enableAsserts: enableAsserts,
@@ -300,7 +309,8 @@
supportHotReload: true,
supportCodeCoverage: true,
packageConfig: packageConfig,
- invocationModes: invocationModes);
+ invocationModes: invocationModes,
+ verbosityLevel: verbosityLevel);
factory IncrementalCompilerWrapper.forExpressionCompilationOnly(
Component component,
@@ -379,14 +389,16 @@
int nullSafety: kNullSafetyOptionUnspecified,
List<String> experimentalFlags: null,
String packageConfig: null,
- String invocationModes: ''})
+ String invocationModes: '',
+ String verbosityLevel: Verbosity.defaultValue})
: super(isolateId, fileSystem, platformKernelPath,
suppressWarnings: suppressWarnings,
enableAsserts: enableAsserts,
nullSafety: nullSafety,
experimentalFlags: experimentalFlags,
packageConfig: packageConfig,
- invocationModes: invocationModes);
+ invocationModes: invocationModes,
+ verbosityLevel: verbosityLevel);
@override
Future<CompilerResult> compileInternal(Uri script) async {
@@ -423,7 +435,8 @@
String packageConfig: null,
String multirootFilepaths,
String multirootScheme,
- String invocationModes: ''}) async {
+ String invocationModes: '',
+ String verbosityLevel: Verbosity.defaultValue}) async {
IncrementalCompilerWrapper compiler = lookupIncrementalCompiler(isolateId);
if (compiler != null) {
updateSources(compiler, sourceFiles);
@@ -453,7 +466,8 @@
nullSafety: nullSafety,
experimentalFlags: experimentalFlags,
packageConfig: packageConfig,
- invocationModes: invocationModes);
+ invocationModes: invocationModes,
+ verbosityLevel: verbosityLevel);
}
isolateCompilers[isolateId] = compiler;
}
@@ -755,6 +769,8 @@
final String multirootFilepaths = request[13];
final String multirootScheme = request[14];
final String workingDirectory = request[15];
+ // TODO(johnniwinther,bkonyi): Pass verbosity from command line arguments.
+ final String verbosityLevel = Verbosity.defaultValue;
Uri platformKernelPath = null;
List<int> platformKernel = null;
@@ -823,7 +839,8 @@
experimentalFlags,
packagesUri,
errors,
- invocationModes);
+ invocationModes,
+ verbosityLevel);
// script should only be null for kUpdateSourcesTag.
assert(script != null);
@@ -850,7 +867,8 @@
packageConfig: packageConfig,
multirootFilepaths: multirootFilepaths,
multirootScheme: multirootScheme,
- invocationModes: invocationModes);
+ invocationModes: invocationModes,
+ verbosityLevel: verbosityLevel);
} else {
FileSystem fileSystem = _buildFileSystem(
sourceFiles, platformKernel, multirootFilepaths, multirootScheme);
@@ -862,7 +880,8 @@
nullSafety: nullSafety,
experimentalFlags: experimentalFlags,
packageConfig: packageConfig,
- invocationModes: invocationModes);
+ invocationModes: invocationModes,
+ verbosityLevel: verbosityLevel);
}
CompilationResult result;
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index a1fc45e..e0368f7 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -33,6 +33,7 @@
ProcessedOptions,
Severity,
StandardFileSystem,
+ Verbosity,
getMessageUri,
kernelForProgram,
parseExperimentalArguments,
@@ -131,6 +132,10 @@
args.addOption('invocation-modes',
help: 'Provides information to the front end about how it is invoked.',
defaultsTo: '');
+ args.addOption('verbosity',
+ help: 'Sets the verbosity level used for filtering messages during '
+ 'compilation.',
+ defaultsTo: Verbosity.defaultValue);
}
/// Create ArgParser and populate it with options consumed by [runCompiler].
@@ -215,7 +220,8 @@
mainUri = await convertToPackageUri(fileSystem, mainUri, packagesUri);
}
- final errorPrinter = new ErrorPrinter();
+ final verbosity = Verbosity.parseArgument(options['verbosity']);
+ final errorPrinter = new ErrorPrinter(verbosity);
final errorDetector = new ErrorDetector(previousErrorHandler: errorPrinter);
final CompilerOptions compilerOptions = new CompilerOptions()
@@ -232,7 +238,8 @@
}
..embedSourceText = embedSources
..invocationModes =
- InvocationMode.parseArguments(options['invocation-modes']);
+ InvocationMode.parseArguments(options['invocation-modes'])
+ ..verbosity = verbosity;
if (nullSafety == null &&
compilerOptions.isExperimentEnabled(ExperimentalFlag.nonNullable)) {
@@ -489,10 +496,11 @@
}
class ErrorPrinter {
+ final Verbosity verbosity;
final DiagnosticMessageHandler previousErrorHandler;
final compilationMessages = <Uri, List<DiagnosticMessage>>{};
- ErrorPrinter({this.previousErrorHandler});
+ ErrorPrinter(this.verbosity, {this.previousErrorHandler});
void call(DiagnosticMessage message) {
final sourceUri = getMessageUri(message);
@@ -516,7 +524,9 @@
});
for (final Uri sourceUri in sortedUris) {
for (final DiagnosticMessage message in compilationMessages[sourceUri]) {
- printDiagnosticMessage(message, print);
+ if (Verbosity.shouldPrint(verbosity, message)) {
+ printDiagnosticMessage(message, print);
+ }
}
}
}
diff --git a/pkg/vm_service/test/async_single_step_out_test.dart b/pkg/vm_service/test/async_single_step_out_test.dart
index a0a3d83..7e5f200 100644
--- a/pkg/vm_service/test/async_single_step_out_test.dart
+++ b/pkg/vm_service/test/async_single_step_out_test.dart
@@ -44,6 +44,10 @@
stepInto, // exit helper via a single step.
hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_B), // await helper
+ stepInto,
+
+ hasStoppedAtBreakpoint,
stoppedAtLine(20), // return null (weird dispatching)
stepInto, // exit helper via a single step.
diff --git a/runtime/observatory/tests/service/async_single_step_out_test.dart b/runtime/observatory/tests/service/async_single_step_out_test.dart
index cfeac6c..3c6de1b 100644
--- a/runtime/observatory/tests/service/async_single_step_out_test.dart
+++ b/runtime/observatory/tests/service/async_single_step_out_test.dart
@@ -44,6 +44,10 @@
stepInto, // exit helper via a single step.
hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_B), // await helper
+ stepInto,
+
+ hasStoppedAtBreakpoint,
stoppedAtLine(20), // return null (weird dispatching)
stepInto, // exit helper via a single step.
diff --git a/runtime/tests/vm/dart/causal_stacks/utils.dart b/runtime/tests/vm/dart/causal_stacks/utils.dart
index 73ffe1d..fdebc07 100644
--- a/runtime/tests/vm/dart/causal_stacks/utils.dart
+++ b/runtime/tests/vm/dart/causal_stacks/utils.dart
@@ -720,20 +720,22 @@
final mixedYieldsExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
r'^<asynchronous suspension>$',
- r'^#1 mixedYields2 \(.*/utils.dart:66(:3)?\)$',
+ r'^#1 mixedYields3 \(.*/utils.dart:70(:3)?\)$',
r'^<asynchronous suspension>$',
- r'^#2 mixedYields \(.*/utils.dart:61(:3)?\)$',
+ r'^#2 mixedYields2 \(.*/utils.dart:66(:3)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#3 mixedYields \(.*/utils.dart:61(:3)?\)$',
r'^<asynchronous suspension>$',
];
await doTestAwait(
mixedYields,
mixedYieldsExpected +
const <String>[
- r'^#3 doTestAwait ',
+ r'^#4 doTestAwait ',
r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
+ r'^#5 doTestsLazy ',
r'^<asynchronous suspension>$',
- r'^#5 main ',
+ r'^#6 main ',
r'^<asynchronous suspension>$',
],
debugInfoFilename);
@@ -741,7 +743,7 @@
mixedYields,
mixedYieldsExpected +
const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
+ r'^#4 doTestAwaitThen.<anonymous closure> ',
r'^<asynchronous suspension>$',
],
debugInfoFilename);
@@ -782,20 +784,22 @@
final nonAsyncNoStackExpected = const <String>[
r'^#0 throwAsync \(.*/utils.dart:21(:3)?\)$',
r'^<asynchronous suspension>$',
- r'^#1 nonAsyncNoStack1 \(.*/utils.dart:95(:36)?\)$',
+ r'^#1 nonAsyncNoStack2 \(.*/utils.dart:97(:36)?\)$',
r'^<asynchronous suspension>$',
- r'^#2 nonAsyncNoStack \(.*/utils.dart:93(:35)?\)$',
+ r'^#2 nonAsyncNoStack1 \(.*/utils.dart:95(:36)?\)$',
+ r'^<asynchronous suspension>$',
+ r'^#3 nonAsyncNoStack \(.*/utils.dart:93(:35)?\)$',
r'^<asynchronous suspension>$',
];
await doTestAwait(
nonAsyncNoStack,
nonAsyncNoStackExpected +
const <String>[
- r'^#3 doTestAwait ',
+ r'^#4 doTestAwait ',
r'^<asynchronous suspension>$',
- r'^#4 doTestsLazy ',
+ r'^#5 doTestsLazy ',
r'^<asynchronous suspension>$',
- r'^#5 main ',
+ r'^#6 main ',
r'^<asynchronous suspension>$',
],
debugInfoFilename);
@@ -803,7 +807,7 @@
nonAsyncNoStack,
nonAsyncNoStackExpected +
const <String>[
- r'^#3 doTestAwaitThen.<anonymous closure> ',
+ r'^#4 doTestAwaitThen.<anonymous closure> ',
r'^<asynchronous suspension>$',
],
debugInfoFilename);
diff --git a/sdk/lib/_http/http_parser.dart b/sdk/lib/_http/http_parser.dart
index 23e4a2b..93b6518 100644
--- a/sdk/lib/_http/http_parser.dart
+++ b/sdk/lib/_http/http_parser.dart
@@ -684,11 +684,16 @@
} else {
String headerField = new String.fromCharCodes(_headerField);
String headerValue = new String.fromCharCodes(_headerValue);
+ const errorIfBothText = "Both Content-Length and Transfer-Encoding "
+ "are specified, at most one is allowed";
if (headerField == HttpHeaders.contentLengthHeader) {
// Content Length header should not have more than one occurance
// or coexist with Transfer Encoding header.
- if (_contentLength || _transferEncoding) {
- _statusCode = HttpStatus.badRequest;
+ if (_contentLength) {
+ throw HttpException("The Content-Length header occurred "
+ "more than once, at most one is allowed.");
+ } else if (_transferEncoding) {
+ throw HttpException(errorIfBothText);
}
_contentLength = true;
} else if (headerField == HttpHeaders.transferEncodingHeader) {
@@ -697,7 +702,7 @@
_chunked = true;
}
if (_contentLength) {
- _statusCode = HttpStatus.badRequest;
+ throw HttpException(errorIfBothText);
}
}
var headers = _headers!;
diff --git a/tests/language/async/explicit_await_test.dart b/tests/language/async/explicit_await_test.dart
new file mode 100644
index 0000000..545e5c5
--- /dev/null
+++ b/tests/language/async/explicit_await_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+bool caughtInMethod1 = false;
+bool caughtInMethod2 = false;
+bool caughtInMain = false;
+
+Future<Object> f() {
+ return new Future<Future<Object>>.value(new Future<Object>.delayed(
+ const Duration(seconds: 1), () => throw 'foo'));
+}
+
+Future<Object> method1() async {
+ try {
+ return await f();
+ } catch (e) {
+ print('caught in method1: $e');
+ caughtInMethod1 = true;
+ }
+ return new Object();
+}
+
+Future<Object> method2() async {
+ try {
+ return method1();
+ } catch (e) {
+ print('caught in method2: $e');
+ caughtInMethod2 = true;
+ }
+ return new Object();
+}
+
+void main() async {
+ try {
+ print(await method2());
+ print('Done');
+ } catch (e) {
+ print('caught in main: $e');
+ caughtInMain = true;
+ }
+ Expect.isTrue(caughtInMethod1, "Exception should be caught in 'method1'.");
+ Expect.isFalse(
+ caughtInMethod2, "Exception should not be caught in 'method2'.");
+ Expect.isFalse(caughtInMain, "Exception should not be caught in 'main'.");
+}
diff --git a/tests/language/async/implicit_await_test.dart b/tests/language/async/implicit_await_test.dart
new file mode 100644
index 0000000..9c79259
--- /dev/null
+++ b/tests/language/async/implicit_await_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+
+bool caughtInF = false;
+bool caughtInMain = false;
+
+class A {}
+
+class AAndFutureOfA implements A, Future<A> {
+ noSuchMethod(Invocation i) => throw 0;
+}
+
+Future<A> f(A a) async {
+ try {
+ // Statically looks like no `await` is needed, but dynamically it is needed.
+ // So we should check dynamically whether to await.
+ return a;
+ } catch (e) {
+ caughtInF = true;
+ }
+ return new A();
+}
+
+void main() async {
+ try {
+ print(await f(AAndFutureOfA()));
+ print('Done');
+ } catch (e) {
+ caughtInMain = true;
+ }
+ Expect.isTrue(caughtInF, "Exception should be caught in 'f'.");
+ Expect.isFalse(caughtInMain, "Exception should not be caught in 'main'.");
+}
diff --git a/tests/standalone/io/http_parser_test.dart b/tests/standalone/io/http_parser_test.dart
index fa7499c..022a9b9 100644
--- a/tests/standalone/io/http_parser_test.dart
+++ b/tests/standalone/io/http_parser_test.dart
@@ -461,36 +461,6 @@
_testParseRequest(request, "POST", "/test",
expectedTransferLength: -1, expectedBytesReceived: 10, chunked: true);
- // Test mixing chunked encoding and content length (content length
- // is ignored).
- request = """
-POST /test HTTP/1.1\r
-Content-Length: 7\r
-Transfer-Encoding: chunked\r
-\r
-5\r
-01234\r
-5\r
-56789\r
-0\r\n\r\n""";
- _testParseRequest(request, "POST", "/test",
- expectedTransferLength: -1, expectedBytesReceived: 10, chunked: true);
-
- // Test mixing chunked encoding and content length (content length
- // is ignored).
- request = """
-POST /test HTTP/1.1\r
-Transfer-Encoding: chunked\r
-Content-Length: 3\r
-\r
-5\r
-01234\r
-5\r
-56789\r
-0\r\n\r\n""";
- _testParseRequest(request, "POST", "/test",
- expectedTransferLength: -1, expectedBytesReceived: 10, chunked: true);
-
// Test upper and lower case hex digits in chunked encoding.
request = """
POST /test HTTP/1.1\r
@@ -772,6 +742,32 @@
request = "GET / HTTP/1.1\r\nKeep-Alive: False\r\nbadheader\r\n\r\n";
_testParseInvalidRequest(request);
+
+ // Content-Length and "Transfer-Encoding: chunked" are specified (error
+ // per RFC-7320).
+ request = """
+POST /test HTTP/1.1\r
+Content-Length: 7\r
+Transfer-Encoding: chunked\r
+\r
+5\r
+01234\r
+5\r
+56789\r
+0\r\n\r\n""";
+ _testParseInvalidRequest(request);
+
+ request = """
+POST /test HTTP/1.1\r
+Transfer-Encoding: chunked\r
+Content-Length: 7\r
+\r
+5\r
+01234\r
+5\r
+56789\r
+0\r\n\r\n""";
+ _testParseInvalidRequest(request);
}
static void testParseInvalidResponse() {
diff --git a/tools/VERSION b/tools/VERSION
index 927bbe8..4aae745 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 254
+PRERELEASE 255
PRERELEASE_PATCH 0
\ No newline at end of file