Version 2.15.1

* Cherry-pick e12a81d776d02f88002ac2cdebc1fddd1dc14a50 to stable
* Cherry-pick 1777f769abc9ea7f2a7e2c70c3e1635a838bc199 to stable
* Cherry-pick d2da75a5e01b5ccec1ce4013d9d37657bc86b312 to stable
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 68af803..8b1f6cf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,15 @@
-## 2.15.0
+## 2.15.1 - 2021-12-14
+
+This is a patch release that fixes:
+
+- an AOT compilation failure in some Flutter apps (issue [#47878][]).
+- `dart pub publish` for servers with a path in the URL (pr
+  [dart-lang/pub#3244][]).
+
+[#47878]: https://github.com/dart-lang/sdk/issues/47878
+[dart-lang/pub#3244]: https://github.com/dart-lang/pub/pull/3244
+
+## 2.15.0 - 2021-12-08
 
 ### Language
 
diff --git a/DEPS b/DEPS
index cb395cc..7a961aa 100644
--- a/DEPS
+++ b/DEPS
@@ -139,7 +139,7 @@
   "pool_rev": "7abe634002a1ba8a0928eded086062f1307ccfae",
   "process_rev": "56ece43b53b64c63ae51ec184b76bd5360c28d0b",
   "protobuf_rev": "c1eb6cb51af39ccbaa1a8e19349546586a5c8e31",
-  "pub_rev": "96404e0749864c9fbf8b12e1d424e8078809e00a",
+  "pub_rev": "b9edfa5e288ea3d1a57d1db054ef844ae7b27d99",
   "pub_semver_rev": "a43ad72fb6b7869607581b5fedcb186d1e74276a",
   "root_certificates_rev": "692f6d6488af68e0121317a9c2c9eb393eb0ee50",
   "rust_revision": "b7856f695d65a8ebc846754f97d15814bcb1c244",
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 86800bb..38e5cfc 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -11888,7 +11888,9 @@
       v.visitTypeParameterType(this, arg);
 
   @override
-  void visitChildren(Visitor v) {}
+  void visitChildren(Visitor v) {
+    promotedBound?.accept(v);
+  }
 
   @override
   bool operator ==(Object other) => equals(other, null);
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 1868a4d..00efc64 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -985,6 +985,7 @@
     if (parent is Class) {
       shaker.addClassUsedInType(parent);
     }
+    node.visitChildren(this);
   }
 }
 
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_47878.dart b/pkg/vm/testcases/transformations/type_flow/transformer/regress_47878.dart
new file mode 100644
index 0000000..866f945
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_47878.dart
@@ -0,0 +1,27 @@
+// 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.
+
+// Regression test for https://github.com/dart-lang/sdk/issues/47878
+
+abstract class Disposable {}
+
+class A {}
+
+class Data<T> {
+  T? value;
+}
+
+class DataStream<T> {
+  DataStream({newValue, Data<T>? stream}) {
+    var lastValue = stream!.value;
+
+    if (lastValue != null &&
+        lastValue is Disposable &&
+        lastValue != newValue) {}
+  }
+}
+
+void main() {
+  DataStream<A>();
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/regress_47878.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/regress_47878.dart.expect
new file mode 100644
index 0000000..d52c496
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/regress_47878.dart.expect
@@ -0,0 +1,26 @@
+library #lib /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+abstract class Disposable extends core::Object {
+}
+abstract class A extends core::Object {
+}
+abstract class Data<T extends core::Object? = dynamic> extends core::Object {
+}
+class DataStream<T extends core::Object? = dynamic> extends core::Object {
+  constructor •() → self::DataStream<self::DataStream::T%>
+    : super core::Object::•() {
+    self::DataStream::T? lastValue = block {
+      #C1!;
+    } =>throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
+    if(!(throw "Attempt to execute code removed by Dart AOT compiler (TFA)") && false && !([@vm.inferred-type.metadata=dart.core::bool (skip check) (receiver not int)] lastValue{self::DataStream::T & self::Disposable /* '!' & '!' = '!' */} =={core::Object::==}{(core::Object) → core::bool} #C1)) {
+    }
+  }
+}
+static method main() → void {
+  new self::DataStream::•<self::A>();
+}
+constants  {
+  #C1 = null
+}
diff --git a/tools/VERSION b/tools/VERSION
index b85398b..6ac463f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -26,6 +26,6 @@
 CHANNEL stable
 MAJOR 2
 MINOR 15
-PATCH 0
+PATCH 1
 PRERELEASE 0
 PRERELEASE_PATCH 0
\ No newline at end of file