From 70293476acadcb432317a8856628e05548ce6d82 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Thu, 12 Dec 2024 16:55:28 +0100
Subject: [PATCH 01/11] Enable "jump to def" feature on prelude variants

---
 src/librustdoc/html/highlight.rs | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 48a537ad5e7ad..62cf2b63f7fd6 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -337,7 +337,7 @@ enum Class {
     Ident(Span),
     Lifetime,
     PreludeTy(Span),
-    PreludeVal,
+    PreludeVal(Span),
     QuestionMark,
     Decoration(&'static str),
 }
@@ -385,7 +385,7 @@ impl Class {
             Class::Ident(_) => "",
             Class::Lifetime => "lifetime",
             Class::PreludeTy(_) => "prelude-ty",
-            Class::PreludeVal => "prelude-val",
+            Class::PreludeVal(_) => "prelude-val",
             Class::QuestionMark => "question-mark",
             Class::Decoration(kind) => kind,
         }
@@ -395,7 +395,11 @@ impl Class {
     /// a "span" (a tuple representing `(lo, hi)` equivalent of `Span`).
     fn get_span(self) -> Option<Span> {
         match self {
-            Self::Ident(sp) | Self::Self_(sp) | Self::Macro(sp) | Self::PreludeTy(sp) => Some(sp),
+            Self::Ident(sp)
+            | Self::Self_(sp)
+            | Self::Macro(sp)
+            | Self::PreludeTy(sp)
+            | Self::PreludeVal(sp) => Some(sp),
             Self::Comment
             | Self::DocComment
             | Self::Attribute
@@ -406,7 +410,6 @@ impl Class {
             | Self::Number
             | Self::Bool
             | Self::Lifetime
-            | Self::PreludeVal
             | Self::QuestionMark
             | Self::Decoration(_) => None,
         }
@@ -851,7 +854,9 @@ impl<'src> Classifier<'src> {
             TokenKind::Ident => match get_real_ident_class(text, false) {
                 None => match text {
                     "Option" | "Result" => Class::PreludeTy(self.new_span(before, text)),
-                    "Some" | "None" | "Ok" | "Err" => Class::PreludeVal,
+                    "Some" | "None" | "Ok" | "Err" => {
+                        Class::PreludeVal(self.new_span(before, text))
+                    }
                     // "union" is a weak keyword and is only considered as a keyword when declaring
                     // a union type.
                     "union" if self.check_if_is_union_keyword() => Class::KeyWord,

From f6525a621ae815a981aff1c9d2e05ef631e62bd5 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Thu, 12 Dec 2024 16:55:53 +0100
Subject: [PATCH 02/11] Enable "jump to def" feature on patterns

---
 src/librustdoc/html/render/span_map.rs | 27 +++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 81d79a6be9683..e9250cf7edd10 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -4,7 +4,7 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{ExprKind, HirId, Item, ItemKind, Mod, Node};
+use rustc_hir::{ExprKind, HirId, Item, ItemKind, Mod, Node, Pat, PatKind, QPath};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::hygiene::MacroKind;
@@ -189,6 +189,27 @@ impl SpanMapVisitor<'_> {
             self.matches.insert(span, link);
         }
     }
+
+    fn handle_pat(&mut self, p: &Pat<'_>) {
+        match p.kind {
+            PatKind::Binding(_, _, _, Some(p)) => self.handle_pat(p),
+            PatKind::Struct(qpath, _, _)
+            | PatKind::TupleStruct(qpath, _, _)
+            | PatKind::Path(qpath) => match qpath {
+                QPath::TypeRelative(_, path) if matches!(path.res, Res::Err) => {
+                    self.handle_call(path.hir_id, Some(p.hir_id), qpath.span());
+                }
+                QPath::Resolved(_, path) => self.handle_path(path),
+                _ => {}
+            },
+            PatKind::Or(pats) => {
+                for pat in pats {
+                    self.handle_pat(pat);
+                }
+            }
+            _ => {}
+        }
+    }
 }
 
 impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
@@ -206,6 +227,10 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
         intravisit::walk_path(self, path);
     }
 
+    fn visit_pat(&mut self, p: &Pat<'tcx>) {
+        self.handle_pat(p);
+    }
+
     fn visit_mod(&mut self, m: &'tcx Mod<'tcx>, span: Span, id: HirId) {
         // To make the difference between "mod foo {}" and "mod foo;". In case we "import" another
         // file, we want to link to it. Otherwise no need to create a link.

From 140640a8cf7650f0c574f444c300e4c7cbf92cf3 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Thu, 12 Dec 2024 17:08:36 +0100
Subject: [PATCH 03/11] Add regression test for patterns support in "jump to
 def" feature

---
 tests/rustdoc/jump-to-def-pats.rs | 52 +++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 tests/rustdoc/jump-to-def-pats.rs

diff --git a/tests/rustdoc/jump-to-def-pats.rs b/tests/rustdoc/jump-to-def-pats.rs
new file mode 100644
index 0000000000000..147902b44cf5c
--- /dev/null
+++ b/tests/rustdoc/jump-to-def-pats.rs
@@ -0,0 +1,52 @@
+// This test ensures that patterns also get a link generated.
+
+//@ compile-flags: -Zunstable-options --generate-link-to-definition
+
+#![crate_name = "foo"]
+
+//@ has 'src/foo/jump-to-def-pats.rs.html'
+
+use std::fmt;
+
+pub enum MyEnum<T, E> {
+    Ok(T),
+    Err(E),
+    Some(T),
+    None,
+}
+
+pub enum X {
+    A,
+}
+
+pub fn foo() -> Result<(), ()> {
+    // FIXME: would be nice to be able to check both the class and the href at the same time so
+    // we could check the text as well...
+    //@ has - '//a[@class="prelude-val"]/@href' '{{channel}}/core/result/enum.Result.html#variant.Ok'
+    //@ has - '//a[@href="{{channel}}/core/result/enum.Result.html#variant.Ok"]' 'Ok'
+    Ok(())
+}
+
+impl<T, E> fmt::Display for MyEnum<T, E> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            //@ has - '//a[@href="#12"]' 'Self::Ok'
+            Self::Ok(_) => f.write_str("MyEnum::Ok"),
+            //@ has - '//a[@href="#13"]' 'MyEnum::Err'
+            MyEnum::Err(_) => f.write_str("MyEnum::Err"),
+            //@ has - '//a[@href="#14"]' 'Self::Some'
+            Self::Some(_) => f.write_str("MyEnum::Some"),
+            //@ has - '//a[@href="#15"]' 'Self::None'
+            Self::None => f.write_str("MyEnum::None"),
+        }
+    }
+}
+
+impl X {
+    fn p(&self) -> &str {
+        match self {
+            //@ has - '//a[@href="#19"]' 'Self::A'
+            Self::A => "X::A",
+        }
+    }
+}

From 12a12c9a8399bd7f4eacb42d76a7480df5623989 Mon Sep 17 00:00:00 2001
From: Guillaume Gomez <guillaume1.gomez@gmail.com>
Date: Thu, 12 Dec 2024 17:09:38 +0100
Subject: [PATCH 04/11] Rename `handle_call` into `infer_id`

---
 src/librustdoc/html/render/span_map.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index e9250cf7edd10..2570596a49ca8 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -170,7 +170,7 @@ impl SpanMapVisitor<'_> {
         true
     }
 
-    fn handle_call(&mut self, hir_id: HirId, expr_hir_id: Option<HirId>, span: Span) {
+    fn infer_id(&mut self, hir_id: HirId, expr_hir_id: Option<HirId>, span: Span) {
         let hir = self.tcx.hir();
         let body_id = hir.enclosing_body_owner(hir_id);
         // FIXME: this is showing error messages for parts of the code that are not
@@ -197,7 +197,7 @@ impl SpanMapVisitor<'_> {
             | PatKind::TupleStruct(qpath, _, _)
             | PatKind::Path(qpath) => match qpath {
                 QPath::TypeRelative(_, path) if matches!(path.res, Res::Err) => {
-                    self.handle_call(path.hir_id, Some(p.hir_id), qpath.span());
+                    self.infer_id(path.hir_id, Some(p.hir_id), qpath.span());
                 }
                 QPath::Resolved(_, path) => self.handle_path(path),
                 _ => {}
@@ -253,9 +253,9 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> {
     fn visit_expr(&mut self, expr: &'tcx rustc_hir::Expr<'tcx>) {
         match expr.kind {
             ExprKind::MethodCall(segment, ..) => {
-                self.handle_call(segment.hir_id, Some(expr.hir_id), segment.ident.span)
+                self.infer_id(segment.hir_id, Some(expr.hir_id), segment.ident.span)
             }
-            ExprKind::Call(call, ..) => self.handle_call(call.hir_id, None, call.span),
+            ExprKind::Call(call, ..) => self.infer_id(call.hir_id, None, call.span),
             _ => {
                 if self.handle_macro(expr.span) {
                     // We don't want to go deeper into the macro.

From 377dbc96a6d5b7d22b75d4bd98fd00d9e1bb194e Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Tue, 14 Jan 2025 01:50:53 +0000
Subject: [PATCH 05/11] Leak check in impossible_predicates to avoid
 monomorphizing impossible instances

---
 .../rustc_trait_selection/src/traits/mod.rs   | 15 +++++--
 .../impossible-method-modulo-binders-2.rs     | 39 ++++++++++++++++++
 .../impossible-method-modulo-binders.rs       | 40 +++++++++++++++++++
 3 files changed, 91 insertions(+), 3 deletions(-)
 create mode 100644 tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs
 create mode 100644 tests/ui/traits/trait-upcasting/impossible-method-modulo-binders.rs

diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 1dcd0d0dfb830..da16a74209965 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -714,9 +714,18 @@ pub fn impossible_predicates<'tcx>(tcx: TyCtxt<'tcx>, predicates: Vec<ty::Clause
     }
     let errors = ocx.select_all_or_error();
 
-    let result = !errors.is_empty();
-    debug!("impossible_predicates = {:?}", result);
-    result
+    if !errors.is_empty() {
+        return true;
+    }
+
+    // Leak check for any higher-ranked trait mismatches.
+    // We only need to do this in the old solver, since the new solver already
+    // leak-checks.
+    if !infcx.next_trait_solver() && infcx.leak_check(ty::UniverseIndex::ROOT, None).is_err() {
+        return true;
+    }
+
+    false
 }
 
 fn instantiate_and_check_impossible_predicates<'tcx>(
diff --git a/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs b/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs
new file mode 100644
index 0000000000000..bc43360553194
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs
@@ -0,0 +1,39 @@
+//@ build-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+#![allow(coherence_leak_check)]
+
+type A = fn(&'static ());
+type B = fn(&());
+
+trait Bound<P: WithAssoc>: From<GetAssoc<P>> {
+}
+impl Bound<B> for String {}
+
+trait Trt<T> {
+    fn __(&self, x: T) where T: Bound<A> {
+        T::from(());
+    }
+}
+
+impl<T, S> Trt<T> for S {}
+
+type GetAssoc<T> = <T as WithAssoc>::Ty;
+
+trait WithAssoc {
+    type Ty;
+}
+
+impl WithAssoc for B {
+    type Ty = String;
+}
+
+impl WithAssoc for A {
+    type Ty = ();
+}
+
+fn main() {
+    let x: &'static dyn Trt<String> = &();
+}
diff --git a/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders.rs b/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders.rs
new file mode 100644
index 0000000000000..63ad1c0a06082
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders.rs
@@ -0,0 +1,40 @@
+//@ build-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+trait Foo {}
+impl Foo for fn(&'static ()) {}
+
+trait Bar {
+    type Assoc: Default;
+}
+impl<T: Foo> Bar for T {
+    type Assoc = usize;
+}
+impl Bar for fn(&()) {
+    type Assoc = ();
+}
+
+fn needs_foo<T: Foo>() -> usize {
+    needs_bar::<T>()
+}
+
+fn needs_bar<T: Bar>() -> <T as Bar>::Assoc {
+    Default::default()
+}
+
+trait Evil<T> {
+    fn bad(&self)
+    where
+        T: Foo,
+    {
+        needs_foo::<T>();
+    }
+}
+
+impl Evil<fn(&())> for () {}
+
+fn main() {
+    let x: &dyn Evil<fn(&())> = &();
+}

From 2c4aee92fa65e74f23ad7853937db8d2c4bfa6c8 Mon Sep 17 00:00:00 2001
From: Aditya Kumar <git@adityais.dev>
Date: Sun, 29 Dec 2024 07:01:54 +0000
Subject: [PATCH 06/11] Made `Path::name` only have item name rather than full
 name

---
 src/librustdoc/json/conversions.rs   | 2 +-
 src/rustdoc-json-types/lib.rs        | 2 +-
 tests/rustdoc-json/return_private.rs | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 7f072aa7e2fc4..093f8eff8398f 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -620,7 +620,7 @@ impl FromClean<clean::Type> for Type {
 impl FromClean<clean::Path> for Path {
     fn from_clean(path: clean::Path, renderer: &JsonRenderer<'_>) -> Path {
         Path {
-            name: path.whole_name(),
+            name: path.last_opt().map_or(String::from(""), |s| String::from(s.as_str())),
             id: renderer.id_from_item_default(path.def_id().into()),
             args: path.segments.last().map(|args| Box::new(args.clone().args.into_json(renderer))),
         }
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 84b33e3d86068..5a99977ded5eb 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -30,7 +30,7 @@ pub type FxHashMap<K, V> = HashMap<K, V>; // re-export for use in src/librustdoc
 /// This integer is incremented with every breaking change to the API,
 /// and is returned along with the JSON blob as [`Crate::format_version`].
 /// Consuming code should assert that this value matches the format version(s) that it supports.
-pub const FORMAT_VERSION: u32 = 37;
+pub const FORMAT_VERSION: u32 = 38;
 
 /// The root of the emitted JSON blob.
 ///
diff --git a/tests/rustdoc-json/return_private.rs b/tests/rustdoc-json/return_private.rs
index 0b341e2bda7d2..c238a536e0d8d 100644
--- a/tests/rustdoc-json/return_private.rs
+++ b/tests/rustdoc-json/return_private.rs
@@ -6,7 +6,7 @@ mod secret {
 }
 
 //@ has "$.index[*][?(@.name=='get_secret')].inner.function"
-//@ is "$.index[*][?(@.name=='get_secret')].inner.function.sig.output.resolved_path.name" \"secret::Secret\"
+//@ is "$.index[*][?(@.name=='get_secret')].inner.function.sig.output.resolved_path.name" \"Secret\"
 pub fn get_secret() -> secret::Secret {
     secret::Secret
 }

From 94ffced66747a94554e0e0fa420eb21abdced095 Mon Sep 17 00:00:00 2001
From: lcnr <rust@lcnr.de>
Date: Tue, 14 Jan 2025 10:06:22 +0100
Subject: [PATCH 07/11] add note to test

---
 .../trait-upcasting/impossible-method-modulo-binders-2.rs       | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs b/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs
index bc43360553194..c03b5145aa73b 100644
--- a/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs
+++ b/tests/ui/traits/trait-upcasting/impossible-method-modulo-binders-2.rs
@@ -2,7 +2,7 @@
 //@ revisions: current next
 //@ ignore-compare-mode-next-solver (explicit revisions)
 //@[next] compile-flags: -Znext-solver
-
+// Regression test for #135462.
 #![allow(coherence_leak_check)]
 
 type A = fn(&'static ());

From 3a66b97b9bd4992c4743a8e4d2be55df127b3a25 Mon Sep 17 00:00:00 2001
From: Kleis Auke Wolthuizen <github@kleisauke.nl>
Date: Tue, 14 Jan 2025 10:49:32 +0100
Subject: [PATCH 08/11] Remove remnant of asmjs

See: https://github.com/rust-lang/rust/issues/131467#issuecomment-2529314603.
---
 src/ci/docker/scripts/emscripten.sh | 24 ------------------------
 1 file changed, 24 deletions(-)
 delete mode 100644 src/ci/docker/scripts/emscripten.sh

diff --git a/src/ci/docker/scripts/emscripten.sh b/src/ci/docker/scripts/emscripten.sh
deleted file mode 100644
index 8b2b39ee1629e..0000000000000
--- a/src/ci/docker/scripts/emscripten.sh
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/sh
-set -ex
-
-hide_output() {
-  set +x
-  on_err="
-echo ERROR: An error was encountered with the build.
-cat /tmp/build.log
-exit 1
-"
-  trap "$on_err" ERR
-  bash -c "while true; do sleep 30; echo \$(date) - building ...; done" &
-  PING_LOOP_PID=$!
-  "$@" &> /tmp/build.log
-  trap - ERR
-  kill $PING_LOOP_PID
-  rm -f /tmp/build.log
-  set -x
-}
-
-git clone https://github.com/emscripten-core/emsdk.git /emsdk-portable
-cd /emsdk-portable
-hide_output ./emsdk install 3.1.68
-./emsdk activate 3.1.68

From 99657aa3389885d40e7aa0f1729186a72a4be8b5 Mon Sep 17 00:00:00 2001
From: lcnr <rust@lcnr.de>
Date: Tue, 14 Jan 2025 11:58:42 +0100
Subject: [PATCH 09/11] mir borrowck: cleanup late-bound region handling

---
 compiler/rustc_borrowck/src/renumber.rs       |  1 -
 .../rustc_borrowck/src/universal_regions.rs   | 65 ++++++++-----------
 .../binder/nested-closures-regions.stderr     |  4 +-
 .../escape-argument-callee.stderr             |  2 +-
 ...er-to-static-comparing-against-free.stderr |  2 +-
 ...ail-to-approximate-longer-no-bounds.stderr |  4 +-
 ...-to-approximate-longer-wrong-bounds.stderr |  4 +-
 7 files changed, 34 insertions(+), 48 deletions(-)

diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs
index d83d6ade2032c..e355d2b415b03 100644
--- a/compiler/rustc_borrowck/src/renumber.rs
+++ b/compiler/rustc_borrowck/src/renumber.rs
@@ -34,7 +34,6 @@ pub(crate) enum RegionCtxt {
     Location(Location),
     TyContext(TyContext),
     Free(Symbol),
-    Bound(Symbol),
     LateBound(Symbol),
     Existential(Option<Symbol>),
     Placeholder(Symbol),
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 3dc4569c57b9a..26af86c0cdd49 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -467,15 +467,13 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                 self.infcx.tcx.local_parent(self.mir_def),
                 |r| {
                     debug!(?r);
-                    if !indices.indices.contains_key(&r) {
-                        let region_vid = {
-                            let name = r.get_name_or_anon();
-                            self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
-                        };
-
-                        debug!(?region_vid);
-                        indices.insert_late_bound_region(r, region_vid.as_var());
-                    }
+                    let region_vid = {
+                        let name = r.get_name_or_anon();
+                        self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
+                    };
+
+                    debug!(?region_vid);
+                    indices.insert_late_bound_region(r, region_vid.as_var());
                 },
             );
 
@@ -484,21 +482,17 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
             self.infcx.num_region_vars()
         };
 
-        // "Liberate" the late-bound regions. These correspond to
-        // "local" free regions.
+        // Converse of above, if this is a function/closure then the late-bound regions declared
+        // on its signature are local.
+        //
+        // We manually loop over `bound_inputs_and_output` instead of using
+        // `for_each_late_bound_region_in_item` as we may need to add the otherwise
+        // implicit `ClosureEnv` region.
         let bound_inputs_and_output = self.compute_inputs_and_output(&indices, defining_ty);
-
-        let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars(
-            FR,
-            self.mir_def,
-            bound_inputs_and_output,
-            &mut indices,
-        );
-        // Converse of above, if this is a function/closure then the late-bound regions declared on its
-        // signature are local.
-        for_each_late_bound_region_in_item(self.infcx.tcx, self.mir_def, |r| {
-            debug!(?r);
-            if !indices.indices.contains_key(&r) {
+        for (idx, bound_var) in bound_inputs_and_output.bound_vars().iter().enumerate() {
+            if let ty::BoundVariableKind::Region(kind) = bound_var {
+                let kind = ty::LateParamRegionKind::from_bound(ty::BoundVar::from_usize(idx), kind);
+                let r = ty::Region::new_late_param(self.infcx.tcx, self.mir_def.to_def_id(), kind);
                 let region_vid = {
                     let name = r.get_name_or_anon();
                     self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
@@ -507,7 +501,12 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                 debug!(?region_vid);
                 indices.insert_late_bound_region(r, region_vid.as_var());
             }
-        });
+        }
+        let inputs_and_output = self.infcx.replace_bound_regions_with_nll_infer_vars(
+            self.mir_def,
+            bound_inputs_and_output,
+            &indices,
+        );
 
         let (unnormalized_output_ty, mut unnormalized_input_tys) =
             inputs_and_output.split_last().unwrap();
@@ -832,10 +831,9 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
     #[instrument(level = "debug", skip(self, indices))]
     fn replace_bound_regions_with_nll_infer_vars<T>(
         &self,
-        origin: NllRegionVariableOrigin,
         all_outlive_scope: LocalDefId,
         value: ty::Binder<'tcx, T>,
-        indices: &mut UniversalRegionIndices<'tcx>,
+        indices: &UniversalRegionIndices<'tcx>,
     ) -> T
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
@@ -845,18 +843,7 @@ impl<'tcx> BorrowckInferCtxt<'tcx> {
             let kind = ty::LateParamRegionKind::from_bound(br.var, br.kind);
             let liberated_region =
                 ty::Region::new_late_param(self.tcx, all_outlive_scope.to_def_id(), kind);
-            let region_vid = {
-                let name = match br.kind.get_name() {
-                    Some(name) => name,
-                    _ => sym::anon,
-                };
-
-                self.next_nll_region_var(origin, || RegionCtxt::Bound(name))
-            };
-
-            indices.insert_late_bound_region(liberated_region, region_vid.as_var());
-            debug!(?liberated_region, ?region_vid);
-            region_vid
+            ty::Region::new_var(self.tcx, indices.to_region_vid(liberated_region))
         });
         value
     }
@@ -870,7 +857,7 @@ impl<'tcx> UniversalRegionIndices<'tcx> {
     /// well. These are used for error reporting.
     fn insert_late_bound_region(&mut self, r: ty::Region<'tcx>, vid: ty::RegionVid) {
         debug!("insert_late_bound_region({:?}, {:?})", r, vid);
-        self.indices.insert(r, vid);
+        assert_eq!(self.indices.insert(r, vid), None);
     }
 
     /// Converts `r` into a local inference variable: `r` can either
diff --git a/tests/ui/closures/binder/nested-closures-regions.stderr b/tests/ui/closures/binder/nested-closures-regions.stderr
index a30339ac67b1c..909cbcaa808a5 100644
--- a/tests/ui/closures/binder/nested-closures-regions.stderr
+++ b/tests/ui/closures/binder/nested-closures-regions.stderr
@@ -9,7 +9,7 @@ LL |     for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
                extern "rust-call" fn((&(),)),
                (),
            ]
-   = note: late-bound region is '?4
+   = note: late-bound region is '?3
    = note: late-bound region is '?2
    = note: number of external vids: 3
    = note: where '?1: '?2
@@ -26,7 +26,7 @@ LL |     for<'a> || -> () { for<'c> |_: &'a ()| -> () {}; };
                extern "rust-call" fn(()),
                (),
            ]
-   = note: late-bound region is '?2
+   = note: late-bound region is '?1
 
 note: no external requirements
   --> $DIR/nested-closures-regions.rs:7:1
diff --git a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr
index a7a59dccf2234..a445534c8d801 100644
--- a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -17,7 +17,7 @@ LL |         let mut closure = expect_sig(|p, y| *p = y);
    |                                       -  -  ^^^^^^ assignment requires that `'1` must outlive `'2`
    |                                       |  |
    |                                       |  has type `&'1 i32`
-   |                                       has type `&'?2 mut &'2 i32`
+   |                                       has type `&'?1 mut &'2 i32`
 
 note: no external requirements
   --> $DIR/escape-argument-callee.rs:20:1
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index 0094d7a50d369..621c1ea083b25 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -20,7 +20,7 @@ LL |     foo(cell, |cell_a, cell_x| {
 LL |         cell_a.set(cell_x.get()); // forces 'x: 'a, error in closure
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ `cell_x` escapes the closure body here
    |
-   = note: requirement occurs because of the type `Cell<&'?8 u32>`, which makes the generic argument `&'?8 u32` invariant
+   = note: requirement occurs because of the type `Cell<&'?9 u32>`, which makes the generic argument `&'?9 u32` invariant
    = note: the struct `Cell<T>` is invariant over the parameter `T`
    = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
 
diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
index 4558ff50674f8..f48ed2823ddb1 100644
--- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
@@ -16,9 +16,9 @@ error: lifetime may not live long enough
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:37:9
    |
 LL |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-   |                                                ---------  - has type `&'?7 Cell<&'1 u32>`
+   |                                                ---------  - has type `&'?6 Cell<&'1 u32>`
    |                                                |
-   |                                                has type `&'?5 Cell<&'2 &'?1 u32>`
+   |                                                has type `&'?4 Cell<&'2 &'?1 u32>`
 LL |         // Only works if 'x: 'y:
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
index 83173ae80c00d..a090e94593fe6 100644
--- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
@@ -16,9 +16,9 @@ error: lifetime may not live long enough
   --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:41:9
    |
 LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-   |                                                ----------  ---------- has type `&'?8 Cell<&'2 &'?2 u32>`
+   |                                                ----------  ---------- has type `&'?7 Cell<&'2 &'?2 u32>`
    |                                                |
-   |                                                has type `&'?6 Cell<&'1 &'?1 u32>`
+   |                                                has type `&'?5 Cell<&'1 &'?1 u32>`
 LL |         // Only works if 'x: 'y:
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`

From faafa5c3107344adc5e57dd6d6dc74e019bd7daf Mon Sep 17 00:00:00 2001
From: Michael Goulet <michael@errs.io>
Date: Tue, 14 Jan 2025 16:32:17 +0000
Subject: [PATCH 10/11] Fix legacy symbol mangling of closures

---
 compiler/rustc_symbol_mangling/src/legacy.rs    | 8 ++++----
 tests/codegen-units/item-collection/closures.rs | 6 ++++++
 2 files changed, 10 insertions(+), 4 deletions(-)

diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 58c0a05df1f2c..879f3fac21fb4 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -19,15 +19,15 @@ pub(super) fn mangle<'tcx>(
     let def_id = instance.def_id();
 
     // We want to compute the "type" of this item. Unfortunately, some
-    // kinds of items (e.g., closures) don't have an entry in the
-    // item-type array. So walk back up the find the closest parent
-    // that DOES have an entry.
+    // kinds of items (e.g., synthetic static allocations from const eval)
+    // don't have a proper implementation for the `type_of` query. So walk
+    // back up the find the closest parent that DOES have a type.
     let mut ty_def_id = def_id;
     let instance_ty;
     loop {
         let key = tcx.def_key(ty_def_id);
         match key.disambiguated_data.data {
-            DefPathData::TypeNs(_) | DefPathData::ValueNs(_) => {
+            DefPathData::TypeNs(_) | DefPathData::ValueNs(_) | DefPathData::Closure => {
                 instance_ty = tcx.type_of(ty_def_id).instantiate_identity();
                 debug!(?instance_ty);
                 break;
diff --git a/tests/codegen-units/item-collection/closures.rs b/tests/codegen-units/item-collection/closures.rs
index 5fc8023092533..864f98817a874 100644
--- a/tests/codegen-units/item-collection/closures.rs
+++ b/tests/codegen-units/item-collection/closures.rs
@@ -10,3 +10,9 @@ pub async fn async_fn() {}
 pub fn closure() {
     let _ = || {};
 }
+
+//~ MONO_ITEM fn A::{constant#0}::{closure#0} @@
+trait A where
+    [(); (|| {}, 1).1]: Sized,
+{
+}

From c141f506bcf9eb3423f319ec7f047cf6a132af4b Mon Sep 17 00:00:00 2001
From: Yotam Ofek <yotam.ofek@gmail.com>
Date: Tue, 14 Jan 2025 17:24:34 +0000
Subject: [PATCH 11/11] =?UTF-8?q?Add=20missing=20closing=20backtick=20in?=
 =?UTF-8?q?=20commit=20hook=20message=20=F0=9F=90=B8?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/bootstrap/src/core/build_steps/format.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/bootstrap/src/core/build_steps/format.rs b/src/bootstrap/src/core/build_steps/format.rs
index 40c908c3fa996..c7eafadee2df3 100644
--- a/src/bootstrap/src/core/build_steps/format.rs
+++ b/src/bootstrap/src/core/build_steps/format.rs
@@ -116,7 +116,7 @@ fn print_paths(verb: &str, adjective: Option<&str>, paths: &[String]) {
         println!("fmt: {verb} {len} {adjective}files");
     }
     if len > 1000 && !CiEnv::is_ci() {
-        println!("hint: if this number seems too high, try running `git fetch origin master");
+        println!("hint: if this number seems too high, try running `git fetch origin master`");
     }
 }