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