Version 2.12.0-248.0.dev
Merge commit 'c9e24eee9f51f6bff041b92d09f35aec5a39f0d9' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 56ef139..88848f7 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -296,6 +296,33 @@
}
@override
+ bool referencesAny(Set<TypeParameterElement> parameters) {
+ if (typeFormals.any((element) {
+ var elementImpl = element as TypeParameterElementImpl;
+ assert(!parameters.contains(elementImpl));
+
+ var bound = elementImpl.bound as TypeImpl;
+ if (bound != null && bound.referencesAny(parameters)) {
+ return true;
+ }
+
+ var defaultType = elementImpl.defaultType as TypeImpl;
+ return defaultType.referencesAny(parameters);
+ })) {
+ return true;
+ }
+
+ if (this.parameters.any((element) {
+ var type = element.type as TypeImpl;
+ return type.referencesAny(parameters);
+ })) {
+ return true;
+ }
+
+ return (returnType as TypeImpl).referencesAny(parameters);
+ }
+
+ @override
TypeImpl withNullability(NullabilitySuffix nullabilitySuffix) {
if (this.nullabilitySuffix == nullabilitySuffix) return this;
return FunctionTypeImpl(
@@ -1312,6 +1339,14 @@
}
@override
+ bool referencesAny(Set<TypeParameterElement> parameters) {
+ return typeArguments.any((argument) {
+ var argumentImpl = argument as TypeImpl;
+ return argumentImpl.referencesAny(parameters);
+ });
+ }
+
+ @override
InterfaceTypeImpl withNullability(NullabilitySuffix nullabilitySuffix) {
if (this.nullabilitySuffix == nullabilitySuffix) return this;
@@ -1712,6 +1747,11 @@
return builder.toString();
}
+ /// Returns true if this type references any of the [parameters].
+ bool referencesAny(Set<TypeParameterElement> parameters) {
+ return false;
+ }
+
@override
DartType resolveToBound(DartType objectType) => this;
@@ -1853,6 +1893,11 @@
}
@override
+ bool referencesAny(Set<TypeParameterElement> parameters) {
+ return parameters.contains(element);
+ }
+
+ @override
DartType resolveToBound(DartType objectType) {
if (promotedBound != null) {
return promotedBound;
diff --git a/pkg/analyzer/test/src/dart/element/test_all.dart b/pkg/analyzer/test/src/dart/element/test_all.dart
index 6efd3dd..bac0ac6 100644
--- a/pkg/analyzer/test/src/dart/element/test_all.dart
+++ b/pkg/analyzer/test/src/dart/element/test_all.dart
@@ -25,6 +25,7 @@
import 'type_bounded_test.dart' as type_bounded;
import 'type_constraint_gatherer_test.dart' as type_constraint_gatherer;
import 'type_parameter_element_test.dart' as type_parameter_element;
+import 'type_references_any_test.dart' as type_references_any;
import 'type_visitor_test.dart' as type_visitor;
import 'upper_lower_bound_test.dart' as upper_bound;
@@ -52,6 +53,7 @@
type_bounded.main();
type_constraint_gatherer.main();
type_parameter_element.main();
+ type_references_any.main();
type_visitor.main();
upper_bound.main();
}, name: 'element');
diff --git a/pkg/analyzer/test/src/dart/element/type_references_any_test.dart b/pkg/analyzer/test/src/dart/element/type_references_any_test.dart
new file mode 100644
index 0000000..60b8192
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/element/type_references_any_test.dart
@@ -0,0 +1,73 @@
+// 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:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../../generated/type_system_test.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(TypeReferencesAnyTest);
+ });
+}
+
+@reflectiveTest
+class TypeReferencesAnyTest extends AbstractTypeSystemNullSafetyTest {
+ TypeParameterElement T;
+ TypeParameterType T_none;
+
+ @override
+ void setUp() {
+ super.setUp();
+
+ T = typeParameter('T');
+ T_none = typeParameterTypeNone(T);
+ }
+
+ test_false() {
+ _checkFalse(dynamicNone);
+ _checkFalse(intNone);
+ _checkFalse(neverNone);
+ _checkFalse(voidNone);
+ _checkFalse(listNone(intNone));
+ }
+
+ test_true() {
+ _checkTrue(T_none);
+ _checkTrue(listNone(T_none));
+ _checkTrue(mapNone(T_none, intNone));
+ _checkTrue(mapNone(intNone, T_none));
+
+ _checkTrue(functionTypeNone(returnType: T_none));
+
+ _checkTrue(
+ functionTypeNone(returnType: voidNone, parameters: [
+ requiredParameter(type: T_none),
+ ]),
+ );
+
+ _checkTrue(
+ functionTypeNone(
+ typeFormals: [
+ typeParameter('U', bound: T_none),
+ ],
+ returnType: voidNone,
+ ),
+ );
+ }
+
+ void _checkFalse(DartType type) {
+ var actual = (type as TypeImpl).referencesAny({T});
+ expect(actual, isFalse);
+ }
+
+ void _checkTrue(DartType type) {
+ var actual = (type as TypeImpl).referencesAny({T});
+ expect(actual, isTrue);
+ }
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/verifier.dart b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
index a5b190f..ddfef29 100644
--- a/pkg/front_end/lib/src/fasta/kernel/verifier.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/verifier.dart
@@ -113,9 +113,9 @@
TreeNode get localContext {
TreeNode result = getSameLibraryLastSeenTreeNode(withLocation: true);
if (result == null &&
- currentClassOrMember != null &&
- _isInSameLibrary(currentLibrary, currentClassOrMember)) {
- result = currentClassOrMember;
+ currentClassOrExtensionOrMember != null &&
+ _isInSameLibrary(currentLibrary, currentClassOrExtensionOrMember)) {
+ result = currentClassOrExtensionOrMember;
}
return result;
}
@@ -174,7 +174,7 @@
@override
problem(TreeNode node, String details, {TreeNode context, TreeNode origin}) {
- node ??= (context ?? currentClassOrMember);
+ node ??= (context ?? currentClassOrExtensionOrMember);
int offset = node?.fileOffset ?? -1;
Uri file = node?.location?.file ?? fileUri;
Uri uri = file == null ? null : file;
@@ -243,6 +243,14 @@
}
@override
+ void visitExtension(Extension node) {
+ enterTreeNode(node);
+ fileUri = checkLocation(node, node.name, node.fileUri);
+ super.visitExtension(node);
+ exitTreeNode(node);
+ }
+
+ @override
void visitField(Field node) {
enterTreeNode(node);
fileUri = checkLocation(node, node.name.text, node.fileUri);
diff --git a/pkg/front_end/test/extensions/data/part/main.dart b/pkg/front_end/test/extensions/data/part/main.dart
new file mode 100644
index 0000000..b014688
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/part/main.dart
@@ -0,0 +1,14 @@
+// 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.
+
+/*library: scope=[
+ Extension,
+ _extension#0]*/
+
+part 'part.dart';
+
+main() {
+ 0.intMethod();
+ ''.stringMethod();
+}
diff --git a/pkg/front_end/test/extensions/data/part/part.dart b/pkg/front_end/test/extensions/data/part/part.dart
new file mode 100644
index 0000000..468a7a7
--- /dev/null
+++ b/pkg/front_end/test/extensions/data/part/part.dart
@@ -0,0 +1,55 @@
+// 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.
+
+part of 'main.dart';
+
+/*class: Extension:
+ builder-name=Extension,
+ builder-onType=int,
+ extension-members=[
+ intMethod=Extension|intMethod,
+ tearoff intMethod=Extension|get#intMethod],
+ extension-name=Extension,
+ extension-onType=int!
+*/
+extension Extension on int {
+ /*member: Extension|intMethod:
+ builder-name=intMethod,
+ builder-params=[#this],
+ member-name=Extension|intMethod,
+ member-params=[#this]
+ */
+ /*member: Extension|get#intMethod:
+ builder-name=intMethod,
+ builder-params=[#this],
+ member-name=Extension|get#intMethod,
+ member-params=[#this]
+ */
+ intMethod() {}
+}
+
+/*class: _extension#0:
+ builder-name=_extension#0,
+ builder-onType=String,
+ extension-members=[
+ stringMethod=_extension#0|stringMethod,
+ tearoff stringMethod=_extension#0|get#stringMethod],
+ extension-name=_extension#0,
+ extension-onType=String!
+*/
+extension on String {
+ /*member: _extension#0|stringMethod:
+ builder-name=stringMethod,
+ builder-params=[#this],
+ member-name=_extension#0|stringMethod,
+ member-params=[#this]
+ */
+ /*member: _extension#0|get#stringMethod:
+ builder-name=stringMethod,
+ builder-params=[#this],
+ member-name=_extension#0|get#stringMethod,
+ member-params=[#this]
+ */
+ stringMethod() {}
+}
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 4f81bdd..65796ed 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -1468,6 +1468,11 @@
}
@override
+ Location _getLocationInEnclosingFile(int offset) {
+ return _getLocationInComponent(enclosingComponent, fileUri, offset);
+ }
+
+ @override
String toString() {
return "Extension(${toStringInternal()})";
}
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index 6bfbf06..e40ab133 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -80,9 +80,12 @@
Class currentClass;
+ Extension currentExtension;
+
TreeNode currentParent;
- TreeNode get currentClassOrMember => currentMember ?? currentClass;
+ TreeNode get currentClassOrExtensionOrMember =>
+ currentMember ?? currentClass ?? currentExtension;
static void check(Component component, {bool isOutline, bool afterConst}) {
component.accept(
@@ -111,7 +114,7 @@
}
problem(TreeNode node, String details, {TreeNode context}) {
- context ??= currentClassOrMember;
+ context ??= currentClassOrExtensionOrMember;
throw new VerificationError(context, node, details);
}
@@ -242,11 +245,13 @@
}
visitExtension(Extension node) {
+ currentExtension = node;
declareTypeParameters(node.typeParameters);
final TreeNode oldParent = enterParent(node);
node.visitChildren(this);
exitParent(oldParent);
undeclareTypeParameters(node.typeParameters);
+ currentExtension = null;
}
void checkTypedef(Typedef node) {
diff --git a/pkg/modular_test/lib/src/loader.dart b/pkg/modular_test/lib/src/loader.dart
index 65d5558..9050017 100644
--- a/pkg/modular_test/lib/src/loader.dart
+++ b/pkg/modular_test/lib/src/loader.dart
@@ -20,11 +20,12 @@
/// The format is described in `test_specification_parser.dart`.
import 'dart:io';
import 'dart:convert';
+import 'dart:typed_data';
import 'suite.dart';
import 'test_specification_parser.dart';
import 'find_sdk_root.dart';
-import 'package:package_config/packages_file.dart' as package_config;
+import 'package:package_config/src/packages_file.dart' as packages_file;
/// Returns the [ModularTest] associated with a folder under [uri].
///
@@ -38,7 +39,7 @@
var testUri = folder.uri; // normalized in case the trailing '/' was missing.
Uri root = await findRoot();
Map<String, Uri> defaultPackages =
- package_config.parse(_defaultPackagesInput, root);
+ _parseDotPackagesBytesToLibMap(_defaultPackagesInput, root);
Module sdkModule = await _createSdkModule(root);
Map<String, Module> modules = {'sdk': sdkModule};
String specString;
@@ -76,7 +77,7 @@
modules[moduleName] = module;
} else if (fileName == '.packages') {
List<int> packagesBytes = await entry.readAsBytes();
- packages = package_config.parse(packagesBytes, entryUri);
+ packages = _parseDotPackagesBytesToLibMap(packagesBytes, entryUri);
} else if (fileName == 'modules.yaml') {
specString = await entry.readAsString();
}
@@ -313,3 +314,15 @@
}
}
}
+
+/// Parse [bytes] representing a `.packages` file into the map of package names
+/// to URIs of their `lib` locations.
+Map<String, Uri> _parseDotPackagesBytesToLibMap(Uint8List bytes, Uri baseUri) {
+ var map = <String, Uri>{};
+ var packageConfig =
+ packages_file.parse(bytes, baseUri, (error) => throw error);
+ for (var package in packageConfig.packages) {
+ map[package.name] = package.packageUriRoot;
+ }
+ return map;
+}
diff --git a/tests/language/least_upper_bound/least_upper_bound_greatest_closure_1_test.dart b/tests/language/least_upper_bound/least_upper_bound_greatest_closure_1_test.dart
new file mode 100644
index 0000000..41f83dd
--- /dev/null
+++ b/tests/language/least_upper_bound/least_upper_bound_greatest_closure_1_test.dart
@@ -0,0 +1,826 @@
+// 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 '../static_type_helper.dart';
+
+class C1<X> {}
+
+class C2 extends C1<C2> {}
+
+var condition = true;
+
+void main() {
+ void f0<X1 extends int>(X1 x1, String t2) {
+ // UP(X1 extends int /*B1*/, String /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : ((throw 0) as int);
+ z1.expectStaticType<Exactly<int>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<Object>>();
+
+ // UP(String /*T2*/, X1 extends int /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? ((throw 0) as int) : x1;
+ z4.expectStaticType<Exactly<int>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<Object>>();
+ }
+
+ void g0<X1>(X1 x1, String t2) {
+ if (x1 is int) {
+ // UP(X1 & int /*B1*/, String /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : (null as Object?);
+ z1.expectStaticType<Exactly<Object?>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<Object>>();
+
+ // UP(String /*T2*/, X1 & int /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? null as Object? : x1;
+ z4.expectStaticType<Exactly<Object?>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<Object>>();
+ }
+ }
+
+ void f1<X1 extends C1<X1>>(X1 x1, C1<C2> t2) {
+ // UP(X1 extends C1<X1> /*B1*/, C1<C2> /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : ((throw 0) as C1<X1>);
+ z1.expectStaticType<Exactly<C1<X1>>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<C1<Object?>>>();
+
+ // UP(C1<C2> /*T2*/, X1 extends C1<X1> /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? ((throw 0) as C1<X1>) : x1;
+ z4.expectStaticType<Exactly<C1<X1>>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<C1<Object?>>>();
+ }
+
+ void g1<X1>(X1 x1, C1<C2> t2) {
+ if (x1 is C1<X1>) {
+ // UP(X1 & C1<X1> /*B1*/, C1<C2> /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : (null as Object?);
+ z1.expectStaticType<Exactly<Object?>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<C1<Object?>>>();
+
+ // UP(C1<C2> /*T2*/, X1 & C1<X1> /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? null as Object? : x1;
+ z4.expectStaticType<Exactly<Object?>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<C1<Object?>>>();
+ }
+ }
+
+ void f2<X1 extends C1<X1>>(X1 x1, C1<C2>? t2) {
+ // UP(X1 extends C1<X1> /*B1*/, C1<C2>? /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : ((throw 0) as C1<X1>);
+ z1.expectStaticType<Exactly<C1<X1>>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<C1<Object?>?>>();
+
+ // UP(C1<C2>? /*T2*/, X1 extends C1<X1> /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? ((throw 0) as C1<X1>) : x1;
+ z4.expectStaticType<Exactly<C1<X1>>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<C1<Object?>?>>();
+ }
+
+ void g2<X1>(X1 x1, C1<C2>? t2) {
+ if (x1 is C1<X1>) {
+ // UP(X1 & C1<X1> /*B1*/, C1<C2>? /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : (null as Object?);
+ z1.expectStaticType<Exactly<Object?>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<C1<Object?>?>>();
+
+ // UP(C1<C2>? /*T2*/, X1 & C1<X1> /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? null as Object? : x1;
+ z4.expectStaticType<Exactly<Object?>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<C1<Object?>?>>();
+ }
+ }
+
+ void f3<X1 extends C1<X1>?>(X1 x1, C1<C2> t2) {
+ // UP(X1 extends C1<X1>? /*B1*/, C1<C2> /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : ((throw 0) as C1<X1>?);
+ z1.expectStaticType<Exactly<C1<Object?>?>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<C1<Object?>?>>();
+
+ // UP(C1<C2> /*T2*/, X1 extends C1<X1>? /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? ((throw 0) as C1<X1>?) : x1;
+ z4.expectStaticType<Exactly<C1<Object?>?>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<C1<Object?>?>>();
+ }
+
+ void g3<X1>(X1 x1, C1<C2> t2) {
+ if (x1 is C1<X1>?) {
+ // UP(X1 & C1<X1>? /*B1*/, C1<C2> /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : (null as Object?);
+ z1.expectStaticType<Exactly<Object?>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<C1<Object?>?>>();
+
+ // UP(C1<C2> /*T2*/, X1 & C1<X1>? /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? null as Object? : x1;
+ z4.expectStaticType<Exactly<Object?>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<C1<Object?>?>>();
+ }
+ }
+
+ void f4<X1 extends C1<X1>?>(X1 x1, C1<C2>? t2) {
+ // UP(X1 extends C1<X1>? /*B1*/, C1<C2>? /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : ((throw 0) as C1<X1>?);
+ z1.expectStaticType<Exactly<C1<Object?>?>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<C1<Object?>?>>();
+
+ // UP(C1<C2>? /*T2*/, X1 extends C1<X1>? /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? ((throw 0) as C1<X1>?) : x1;
+ z4.expectStaticType<Exactly<C1<Object?>?>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<C1<Object?>?>>();
+ }
+
+ void g4<X1>(X1 x1, C1<C2>? t2) {
+ if (x1 is C1<X1>?) {
+ // UP(X1 & C1<X1>? /*B1*/, C1<C2>? /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : (null as Object?);
+ z1.expectStaticType<Exactly<Object?>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<C1<Object?>?>>();
+
+ // UP(C1<C2>? /*T2*/, X1 & C1<X1>? /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? null as Object? : x1;
+ z4.expectStaticType<Exactly<Object?>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<C1<Object?>?>>();
+ }
+ }
+
+ void f5<X1 extends Iterable<Iterable<X1>?>>(
+ X1 x1, Iterable<List<Object?>?> t2) {
+ // UP(X1 extends Iterable<Iterable<X1>?> /*B1*/,
+ // Iterable<List<Object?>?> /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : ((throw 0) as Iterable<Iterable<X1>?>);
+ z1.expectStaticType<Exactly<Iterable<Iterable<X1>?>>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<Iterable<Iterable<Object?>?>>>();
+
+ // UP(Iterable<List<Object?>?> /*T2*/,
+ // X1 extends Iterable<Iterable<X1>?> /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? ((throw 0) as Iterable<Iterable<X1>?>) : x1;
+ z4.expectStaticType<Exactly<Iterable<Iterable<X1>?>>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<Iterable<Iterable<Object?>?>>>();
+ }
+
+ void g5<X1>(X1 x1, Iterable<List<Object?>?> t2) {
+ if (x1 is Iterable<Iterable<X1>?>) {
+ // UP(X1 & Iterable<Iterable<X1>?> /*B1*/,
+ // Iterable<List<Object?>?> /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : (null as Object?);
+ z1.expectStaticType<Exactly<Object?>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<Iterable<Iterable<Object?>?>>>();
+
+ // UP(Iterable<List<Object?>?> /*T2*/,
+ // X1 & Iterable<Iterable<X1>?> /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? null as Object? : x1;
+ z4.expectStaticType<Exactly<Object?>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<Iterable<Iterable<Object?>?>>>();
+ }
+ }
+
+ void g6<X1>(X1 x1, FutureOr<Object> t2) {
+ if (x1 is FutureOr<X1>) {
+ // UP(X1 & FutureOr<X1> /*B1*/, FutureOr<Object> /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : (null as Object?);
+ z1.expectStaticType<Exactly<Object?>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<FutureOr<Object>?>>();
+
+ // UP(FutureOr<Object> /*T2*/, X1 & FutureOr<X1> /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? null as Object? : x1;
+ z4.expectStaticType<Exactly<Object?>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<FutureOr<Object>?>>();
+ }
+ }
+
+ void g7<X1>(X1 x1, FutureOr<Object> t2) {
+ if (x1 is FutureOr<X1?>) {
+ // UP(X1 & FutureOr<X1?> /*B1*/, FutureOr<Object> /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : (null as Object?);
+ z1.expectStaticType<Exactly<Object?>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<FutureOr<Object>?>>();
+
+ // UP(FutureOr<Object> /*T2*/, X1 & FutureOr<X1?> /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? null as Object? : x1;
+ z4.expectStaticType<Exactly<Object?>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<FutureOr<Object>?>>();
+ }
+ }
+
+ void f8<X1 extends void Function(X1)>(X1 x1, void Function(Null) t2) {
+ // UP(X1 extends void Function(X1) /*B1*/, void Function(Null) /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : ((throw 0) as void Function(X1));
+ z1.expectStaticType<Exactly<void Function(X1)>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<void Function(Never)>>();
+
+ // UP(void Function(Null) /*T2*/, X1 extends void Function(X1) /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? ((throw 0) as void Function(X1)) : x1;
+ z4.expectStaticType<Exactly<void Function(X1)>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<void Function(Never)>>();
+ }
+
+ void g8<X1>(X1 x1, void Function(Null) t2) {
+ if (x1 is void Function(X1)) {
+ // UP(X1 & void Function(X1) /*B1*/, void Function(Null) /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : (null as Object?);
+ z1.expectStaticType<Exactly<Object?>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<void Function(Never)>>();
+
+ // UP(void Function(Null) /*T2*/, X1 & void Function(X1) /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? null as Object? : x1;
+ z4.expectStaticType<Exactly<Object?>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<void Function(Never)>>();
+ }
+ }
+
+ void f9<X1 extends void Function([X1])>(X1 x1, void Function([Null]) t2) {
+ // UP(X1 extends void Function([X1]) /*B1*/, void Function([Null]) /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : ((throw 0) as void Function([X1]));
+ z1.expectStaticType<Exactly<void Function([X1])>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<void Function([Never])>>();
+
+ // UP(void Function([Null]) /*T2*/, X1 extends void Function([X1]) /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? ((throw 0) as void Function([X1])) : x1;
+ z4.expectStaticType<Exactly<void Function([X1])>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<void Function([Never])>>();
+ }
+
+ void g9<X1>(X1 x1, void Function([Null]) t2) {
+ if (x1 is void Function([X1])) {
+ // UP(X1 & void Function([X1]) /*B1*/, void Function([Null]) /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : (null as Object?);
+ z1.expectStaticType<Exactly<Object?>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<void Function([Never])>>();
+
+ // UP(void Function([Null]) /*T2*/, X1 & void Function([X1]) /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? null as Object? : x1;
+ z4.expectStaticType<Exactly<Object?>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<void Function([Never])>>();
+ }
+ }
+
+ void f10<X1 extends void Function({X1 p})>(
+ X1 x1, void Function({Null p}) t2) {
+ // UP(X1 extends void Function({X1 p}) /*B1*/,
+ // void Function({Null p}) /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : ((throw 0) as void Function({X1 p}));
+ z1.expectStaticType<Exactly<void Function({X1 p})>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<void Function({Never p})>>();
+
+ // UP(void Function({Null p}) /*T2*/,
+ // X1 extends void Function({X1 p}) /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? ((throw 0) as void Function({X1 p})) : x1;
+ z4.expectStaticType<Exactly<void Function({X1 p})>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<void Function({Never p})>>();
+ }
+
+ void g10<X1>(X1 x1, void Function({Null p}) t2) {
+ if (x1 is void Function({X1 p})) {
+ // UP(X1 & void Function({X1 p}) /*B1*/, void Function({Null p}) /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : (null as Object?);
+ z1.expectStaticType<Exactly<Object?>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<void Function({Never p})>>();
+
+ // UP(void Function({Null p}) /*T2*/, X1 & void Function({X1 p}) /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? null as Object? : x1;
+ z4.expectStaticType<Exactly<Object?>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<void Function({Never p})>>();
+ }
+ }
+
+ void f11<X1 extends void Function({required X1 p})>(
+ X1 x1, void Function({X1 p}) t2) {
+ // UP(X1 extends void Function({required X1 p}) /*B1*/,
+ // void Function({X1 p}) /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : ((throw 0) as void Function({required X1 p}));
+ z1.expectStaticType<Exactly<void Function({required X1 p})>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<void Function({required Never p})>>();
+
+ // UP(void Function({X1 p}) /*T2*/,
+ // X1 extends void Function({required X1 p}) /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? ((throw 0) as void Function({required X1 p})) : x1;
+ z4.expectStaticType<Exactly<void Function({required X1 p})>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<void Function({required Never p})>>();
+ }
+
+ void g11<X1>(X1 x1, void Function({X1 p}) t2) {
+ if (x1 is void Function({required X1 p})) {
+ // UP(X1 & void Function({required X1 p}) /*B1*/,
+ // void Function({X1 p}) /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : (null as Object?);
+ z1.expectStaticType<Exactly<Object?>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<void Function({required Never p})>>();
+
+ // UP(void Function({X1 p}) /*T2*/,
+ // X1 & void Function({required X1 p}) /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? null as Object? : x1;
+ z4.expectStaticType<Exactly<Object?>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<void Function({required Never p})>>();
+ }
+ }
+
+ void f12<X1 extends void Function(FutureOr<X1>)>(
+ X1 x1, void Function(FutureOr<Null>) t2) {
+ // UP(X1 extends void Function(FutureOr<X1>) /*B1*/,
+ // void Function(FutureOr<Null>) /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : ((throw 0) as void Function(FutureOr<X1>));
+ z1.expectStaticType<Exactly<void Function(FutureOr<X1>)>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<void Function(FutureOr<Never>)>>();
+
+ // UP(void Function(FutureOr<Null>) /*T2*/,
+ // X1 extends void Function(FutureOr<X1>) /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? ((throw 0) as void Function(FutureOr<X1>)) : x1;
+ z4.expectStaticType<Exactly<void Function(FutureOr<X1>)>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<void Function(FutureOr<Never>)>>();
+ }
+
+ void g12<X1>(X1 x1, void Function(FutureOr<Null>) t2) {
+ if (x1 is void Function(FutureOr<X1>)) {
+ // UP(X1 & void Function(FutureOr<X1>) /*B1*/,
+ // void Function(FutureOr<Null>) /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : (null as Object?);
+ z1.expectStaticType<Exactly<Object?>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<void Function(FutureOr<Never>)>>();
+
+ // UP(void Function(FutureOr<Null>) /*T2*/,
+ // X1 & void Function(FutureOr<X1>) /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? null as Object? : x1;
+ z4.expectStaticType<Exactly<Object?>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<void Function(FutureOr<Never>)>>();
+ }
+ }
+}
diff --git a/tests/language/least_upper_bound/least_upper_bound_greatest_closure_2_test.dart b/tests/language/least_upper_bound/least_upper_bound_greatest_closure_2_test.dart
new file mode 100644
index 0000000..d0b888a
--- /dev/null
+++ b/tests/language/least_upper_bound/least_upper_bound_greatest_closure_2_test.dart
@@ -0,0 +1,78 @@
+// 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 '../static_type_helper.dart';
+
+class C1<X> {}
+
+class C2 extends C1<C2> {}
+
+var condition = true;
+
+void main() {
+ void f6<X1 extends FutureOr<X1>>(X1 x1, FutureOr<Object> t2) {
+ // UP(X1 extends FutureOr<X1> /*B1*/, FutureOr<Object> /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : ((throw 0) as FutureOr<X1>);
+ z1.expectStaticType<Exactly<FutureOr<X1>>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<FutureOr<Object?>>>();
+
+ // UP(FutureOr<Object> /*T2*/, X1 extends FutureOr<X1> /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? ((throw 0) as FutureOr<X1>) : x1;
+ z4.expectStaticType<Exactly<FutureOr<X1>>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<FutureOr<Object?>>>();
+ }
+
+ void f7<X1 extends FutureOr<X1?>>(X1 x1, FutureOr<Object> t2) {
+ // UP(X1 extends FutureOr<X1?> /*B1*/, FutureOr<Object> /*T2*/) =
+ // T2 if X1 <: T2
+ // otherwise X1 if T2 <: X1
+ // otherwise UP(B1a, T2)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z1 = condition ? x1 : ((throw 0) as FutureOr<X1?>);
+ z1.expectStaticType<Exactly<FutureOr<X1?>>>();
+
+ var z2 = condition ? x1 : throw 0;
+ z2.expectStaticType<Exactly<X1>>();
+
+ var z3 = condition ? x1 : t2;
+ z3.expectStaticType<Exactly<FutureOr<Object?>>>();
+
+ // UP(FutureOr<Object> /*T2*/, X1 extends FutureOr<X1?> /*B1*/) =
+ // X1 if T2 <: X1
+ // otherwise T2 if X1 <: T2
+ // otherwise UP(T2, B1a)
+ // where B1a is the greatest closure of B1 with respect to X1
+
+ var z4 = condition ? ((throw 0) as FutureOr<X1?>) : x1;
+ z4.expectStaticType<Exactly<FutureOr<X1?>>>();
+
+ var z5 = condition ? throw 0 : x1;
+ z5.expectStaticType<Exactly<X1>>();
+
+ var z6 = condition ? t2 : x1;
+ z6.expectStaticType<Exactly<FutureOr<Object?>>>();
+ }
+}
diff --git a/tools/VERSION b/tools/VERSION
index b5a8ca3..6e464de 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 12
PATCH 0
-PRERELEASE 247
+PRERELEASE 248
PRERELEASE_PATCH 0
\ No newline at end of file