Version 2.11.0-204.0.dev

Merge commit 'af5cde47b57475553ceaa21cb053a913c7482fdc' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 291fc7c..01c6f7a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,8 +23,14 @@
 
 #### Linter
 
-Updated the Linter to `0.1.120`, which includes:
+Updated the Linter to `0.1.121`, which includes:
 
+# 0.1.121
+
+* Performance improvements to `always_use_package_imports`, 
+  `avoid_renaming_method_parameters`, `prefer_relative_imports` and
+  `public_member_api_docs`.
+* (internal): updates to analyzer `0.40.4` APIs
 * New lint: `cast_nullable_to_non_nullable`.
 * New lint: `null_check_on_nullable_type_parameter`.
 * New lint: `tighten_type_of_initializing_formals`.
diff --git a/DEPS b/DEPS
index eaa25b8..b0e03ea 100644
--- a/DEPS
+++ b/DEPS
@@ -113,7 +113,7 @@
   "intl_tag": "0.16.1",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_rev": "8f189db8f0c299187a0e8fa959dba7e9b0254be5",
-  "linter_tag": "0.1.120",
+  "linter_tag": "0.1.121",
   "logging_rev": "1590ba0b648a51e7eb3895c612e4b72f72623b6f",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
   "markdown_rev": "dbeafd47759e7dd0a167602153bb9c49fb5e5fe7",
diff --git a/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
index 27eceab..2cb1bde 100644
--- a/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
+++ b/pkg/analyzer/lib/src/dart/element/least_upper_bound.dart
@@ -667,10 +667,19 @@
       return _functionType(T1, T2);
     }
 
-    // UP(T Function<...>(...), T2) = Object
-    // UP(T1, T Function<...>(...)) = Object
-    if (T1 is FunctionType || T2 is FunctionType) {
-      return _typeSystem.objectNone;
+    // UP(T Function<...>(...), T2) = UP(Object, T2)
+    if (T1 is FunctionType) {
+      return getLeastUpperBound(_typeSystem.objectNone, T2);
+    }
+
+    // UP(T1, T Function<...>(...)) = UP(T1, Object)
+    if (T2 is FunctionType) {
+      return getLeastUpperBound(T1, _typeSystem.objectNone);
+    }
+
+    var futureOrResult = _futureOr(T1, T2);
+    if (futureOrResult != null) {
+      return futureOrResult;
     }
 
     // UP(T1, T2) = T2 if T1 <: T2
@@ -802,6 +811,56 @@
     );
   }
 
+  DartType _futureOr(DartType T1, DartType T2) {
+    var T1_futureOr = T1 is InterfaceType && T1.isDartAsyncFutureOr
+        ? T1.typeArguments[0]
+        : null;
+
+    var T1_future = T1 is InterfaceType && T1.isDartAsyncFuture
+        ? T1.typeArguments[0]
+        : null;
+
+    var T2_futureOr = T2 is InterfaceType && T2.isDartAsyncFutureOr
+        ? T2.typeArguments[0]
+        : null;
+
+    var T2_future = T2 is InterfaceType && T2.isDartAsyncFuture
+        ? T2.typeArguments[0]
+        : null;
+
+    // UP(FutureOr<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
+    if (T1_futureOr != null && T2_futureOr != null) {
+      var T3 = getLeastUpperBound(T1_futureOr, T2_futureOr);
+      return _typeSystem.typeProvider.futureOrType2(T3);
+    }
+
+    // UP(Future<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
+    if (T1_future != null && T2_futureOr != null) {
+      var T3 = getLeastUpperBound(T1_future, T2_futureOr);
+      return _typeSystem.typeProvider.futureOrType2(T3);
+    }
+
+    // UP(FutureOr<T1>, Future<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
+    if (T1_futureOr != null && T2_future != null) {
+      var T3 = getLeastUpperBound(T1_futureOr, T2_future);
+      return _typeSystem.typeProvider.futureOrType2(T3);
+    }
+
+    // UP(T1, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
+    if (T2_futureOr != null) {
+      var T3 = getLeastUpperBound(T1, T2_futureOr);
+      return _typeSystem.typeProvider.futureOrType2(T3);
+    }
+
+    // UP(FutureOr<T1>, T2) = FutureOr<T3> where T3 = UP(T1, T2)
+    if (T1_futureOr != null) {
+      var T3 = getLeastUpperBound(T1_futureOr, T2);
+      return _typeSystem.typeProvider.futureOrType2(T3);
+    }
+
+    return null;
+  }
+
   DartType _parameterType(ParameterElement a, ParameterElement b) {
     return _typeSystem.getGreatestLowerBound(a.type, b.type);
   }
diff --git a/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart b/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
index cda9e13..3372610 100644
--- a/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
+++ b/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
@@ -2000,6 +2000,20 @@
       );
     }
   }
+
+  test_unrelated() {
+    var T1 = functionTypeNone(returnType: intNone);
+
+    _checkLeastUpperBound(T1, intNone, objectNone);
+    _checkLeastUpperBound(T1, intQuestion, objectQuestion);
+    _checkLeastUpperBound(T1, intStar, objectStar);
+
+    _checkLeastUpperBound(
+      T1,
+      futureOrNone(functionQuestion),
+      objectQuestion,
+    );
+  }
 }
 
 @reflectiveTest
@@ -2594,6 +2608,50 @@
     );
   }
 
+  /// UP(Future<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
+  /// UP(FutureOr<T1>, Future<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
+  test_futureOr_future() {
+    void check(DartType T1, DartType T2, DartType expected) {
+      _checkLeastUpperBound(
+        futureNone(T1),
+        futureOrNone(T2),
+        futureOrNone(expected),
+      );
+    }
+
+    check(intNone, doubleNone, numNone);
+    check(intNone, stringNone, objectNone);
+  }
+
+  /// UP(FutureOr<T1>, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
+  test_futureOr_futureOr() {
+    void check(DartType T1, DartType T2, DartType expected) {
+      _checkLeastUpperBound(
+        futureOrNone(T1),
+        futureOrNone(T2),
+        futureOrNone(expected),
+      );
+    }
+
+    check(intNone, doubleNone, numNone);
+    check(intNone, stringNone, objectNone);
+  }
+
+  /// UP(T1, FutureOr<T2>) = FutureOr<T3> where T3 = UP(T1, T2)
+  /// UP(FutureOr<T1>, T2) = FutureOr<T3> where T3 = UP(T1, T2)
+  test_futureOr_other() {
+    void check(DartType T1, DartType T2, DartType expected) {
+      _checkLeastUpperBound(
+        futureOrNone(T1),
+        T2,
+        futureOrNone(expected),
+      );
+    }
+
+    check(intNone, doubleNone, numNone);
+    check(intNone, stringNone, objectNone);
+  }
+
   test_identical() {
     void check(DartType type) {
       _checkLeastUpperBound(type, type, type);
diff --git a/tools/VERSION b/tools/VERSION
index 3888401..7077211 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 11
 PATCH 0
-PRERELEASE 203
+PRERELEASE 204
 PRERELEASE_PATCH 0
\ No newline at end of file