about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs4
-rw-r--r--compiler/rustc_hir/src/hir.rs16
-rw-r--r--compiler/rustc_hir/src/intravisit.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs26
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs19
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs5
-rw-r--r--library/core/src/cmp.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/doc.rs47
-rw-r--r--src/bootstrap/src/utils/helpers.rs6
-rw-r--r--src/bootstrap/src/utils/helpers/tests.rs19
-rw-r--r--src/librustdoc/html/markdown/footnotes.rs2
-rw-r--r--src/librustdoc/html/render/sorted_template.rs2
-rw-r--r--src/librustdoc/html/static/js/search.js4
-rw-r--r--src/tools/rust-installer/install-template.sh2
-rw-r--r--src/tools/tidy/src/deps.rs2
-rw-r--r--src/tools/tidy/src/ext_tool_checks.rs2
-rw-r--r--tests/crashes/132766.rs9
-rw-r--r--tests/ui/impl-trait/captured-invalid-lifetime.rs19
-rw-r--r--tests/ui/impl-trait/captured-invalid-lifetime.stderr11
-rw-r--r--tests/ui/stats/input-stats.stderr12
26 files changed, 129 insertions, 109 deletions
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 8438a421226..46e91636cfb 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1845,11 +1845,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             GenericParamKind::Lifetime => {
                 // AST resolution emitted an error on those parameters, so we lower them using
                 // `ParamName::Error`.
+                let ident = self.lower_ident(param.ident);
                 let param_name =
                     if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
-                        ParamName::Error
+                        ParamName::Error(ident)
                     } else {
-                        let ident = self.lower_ident(param.ident);
                         ParamName::Plain(ident)
                     };
                 let kind =
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 5ea3bcef9ba..7a3cde4bc2f 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -52,6 +52,13 @@ pub enum ParamName {
     /// Some user-given name like `T` or `'x`.
     Plain(Ident),
 
+    /// Indicates an illegal name was given and an error has been
+    /// reported (so we should squelch other derived errors).
+    ///
+    /// Occurs when, e.g., `'_` is used in the wrong place, or a
+    /// lifetime name is duplicated.
+    Error(Ident),
+
     /// Synthetic name generated when user elided a lifetime in an impl header.
     ///
     /// E.g., the lifetimes in cases like these:
@@ -67,18 +74,13 @@ pub enum ParamName {
     /// where `'f` is something like `Fresh(0)`. The indices are
     /// unique per impl, but not necessarily continuous.
     Fresh,
-
-    /// Indicates an illegal name was given and an error has been
-    /// reported (so we should squelch other derived errors). Occurs
-    /// when, e.g., `'_` is used in the wrong place.
-    Error,
 }
 
 impl ParamName {
     pub fn ident(&self) -> Ident {
         match *self {
-            ParamName::Plain(ident) => ident,
-            ParamName::Fresh | ParamName::Error => Ident::with_dummy_span(kw::UnderscoreLifetime),
+            ParamName::Plain(ident) | ParamName::Error(ident) => ident,
+            ParamName::Fresh => Ident::with_dummy_span(kw::UnderscoreLifetime),
         }
     }
 }
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index 387a195cb29..a73cf367c0e 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -928,8 +928,8 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(
 ) -> V::Result {
     try_visit!(visitor.visit_id(param.hir_id));
     match param.name {
-        ParamName::Plain(ident) => try_visit!(visitor.visit_ident(ident)),
-        ParamName::Error | ParamName::Fresh => {}
+        ParamName::Plain(ident) | ParamName::Error(ident) => try_visit!(visitor.visit_ident(ident)),
+        ParamName::Fresh => {}
     }
     match param.kind {
         GenericParamKind::Lifetime { .. } => {}
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 3cddc9642ba..efffb24c81d 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -2007,7 +2007,10 @@ fn check_variances_for_type_defn<'tcx>(
         }
 
         match hir_param.name {
-            hir::ParamName::Error => {}
+            hir::ParamName::Error(_) => {
+                // Don't report a bivariance error for a lifetime that isn't
+                // even valid to name.
+            }
             _ => {
                 let has_explicit_bounds = explicitly_bounded_params.contains(&parameter);
                 report_bivariance(tcx, hir_param, has_explicit_bounds, item);
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 9d364775445..e2a26ddacab 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::{self as hir, HirId, LangItem};
 use rustc_hir_analysis::autoderef::Autoderef;
 use rustc_infer::infer;
-use rustc_infer::traits::{self, Obligation, ObligationCause, ObligationCauseCode};
+use rustc_infer::traits::{Obligation, ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::adjustment::{
     Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability,
 };
@@ -512,7 +512,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.register_bound(
                     ty,
                     self.tcx.require_lang_item(hir::LangItem::Tuple, Some(sp)),
-                    traits::ObligationCause::new(sp, self.body_id, ObligationCauseCode::RustCall),
+                    self.cause(sp, ObligationCauseCode::RustCall),
                 );
                 self.require_type_is_sized(ty, sp, ObligationCauseCode::RustCall);
             } else {
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index f9e4a592d92..60e3c0166b9 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -580,11 +580,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         let mut selcx = traits::SelectionContext::new(self);
 
         // Create an obligation for `Source: CoerceUnsized<Target>`.
-        let cause =
-            ObligationCause::new(self.cause.span, self.body_id, ObligationCauseCode::Coercion {
-                source,
-                target,
-            });
+        let cause = self.cause(self.cause.span, ObligationCauseCode::Coercion { source, target });
 
         // Use a FIFO queue for this custom fulfillment procedure.
         //
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index a7d12cae7b5..8ba9a4bab57 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -22,7 +22,6 @@ use rustc_hir::{ExprKind, HirId, QPath};
 use rustc_hir_analysis::hir_ty_lowering::{FeedConstTy, HirTyLowerer as _};
 use rustc_infer::infer;
 use rustc_infer::infer::{DefineOpaqueTypes, InferOk};
-use rustc_infer::traits::ObligationCause;
 use rustc_infer::traits::query::NoSolution;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
@@ -1174,9 +1173,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         for err in errors {
             let cause = &mut err.obligation.cause;
             if let ObligationCauseCode::OpaqueReturnType(None) = cause.code() {
-                let new_cause = ObligationCause::new(
+                let new_cause = self.cause(
                     cause.span,
-                    cause.body_id,
                     ObligationCauseCode::OpaqueReturnType(Some((return_expr_ty, hir_id))),
                 );
                 *cause = new_cause;
@@ -3856,7 +3854,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                     // Enums are anyway always sized. But just to safeguard against future
                     // language extensions, let's double-check.
-                    self.require_type_is_sized(field_ty, expr.span, ObligationCauseCode::Misc);
+                    self.require_type_is_sized(
+                        field_ty,
+                        expr.span,
+                        ObligationCauseCode::FieldSized {
+                            adt_kind: AdtKind::Enum,
+                            span: self.tcx.def_span(field.did),
+                            last: false,
+                        },
+                    );
 
                     if field.vis.is_accessible_from(sub_def_scope, self.tcx) {
                         self.tcx.check_stability(field.did, Some(expr.hir_id), expr.span, None);
@@ -3884,11 +3890,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         let field_ty = self.field_ty(expr.span, field, args);
 
                         if self.tcx.features().offset_of_slice() {
-                            self.require_type_has_static_alignment(
-                                field_ty,
-                                expr.span,
-                                ObligationCauseCode::Misc,
-                            );
+                            self.require_type_has_static_alignment(field_ty, expr.span);
                         } else {
                             self.require_type_is_sized(
                                 field_ty,
@@ -3917,11 +3919,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     {
                         if let Some(&field_ty) = tys.get(index) {
                             if self.tcx.features().offset_of_slice() {
-                                self.require_type_has_static_alignment(
-                                    field_ty,
-                                    expr.span,
-                                    ObligationCauseCode::Misc,
-                                );
+                                self.require_type_has_static_alignment(field_ty, expr.span);
                             } else {
                                 self.require_type_is_sized(
                                     field_ty,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 364499378b0..b77071523a6 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -384,7 +384,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         code: traits::ObligationCauseCode<'tcx>,
         def_id: DefId,
     ) {
-        self.register_bound(ty, def_id, traits::ObligationCause::new(span, self.body_id, code));
+        self.register_bound(ty, def_id, self.cause(span, code));
     }
 
     pub(crate) fn require_type_is_sized(
@@ -410,12 +410,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub(crate) fn require_type_has_static_alignment(
-        &self,
-        ty: Ty<'tcx>,
-        span: Span,
-        code: traits::ObligationCauseCode<'tcx>,
-    ) {
+    pub(crate) fn require_type_has_static_alignment(&self, ty: Ty<'tcx>, span: Span) {
         if !ty.references_error() {
             let tail = self.tcx.struct_tail_raw(
                 ty,
@@ -434,7 +429,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             } else {
                 // We can't be sure, let's required full `Sized`.
                 let lang_item = self.tcx.require_lang_item(LangItem::Sized, None);
-                self.require_type_meets(ty, span, code, lang_item);
+                self.require_type_meets(ty, span, ObligationCauseCode::Misc, lang_item);
             }
         }
     }
@@ -572,7 +567,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         code: traits::ObligationCauseCode<'tcx>,
     ) {
         // WF obligations never themselves fail, so no real need to give a detailed cause:
-        let cause = traits::ObligationCause::new(span, self.body_id, code);
+        let cause = self.cause(span, code);
         self.register_predicate(traits::Obligation::new(
             self.tcx,
             cause,
@@ -1426,9 +1421,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let bounds = self.instantiate_bounds(span, def_id, args);
 
         for obligation in traits::predicates_for_generics(
-            |idx, predicate_span| {
-                traits::ObligationCause::new(span, self.body_id, code(idx, predicate_span))
-            },
+            |idx, predicate_span| self.cause(span, code(idx, predicate_span)),
             param_env,
             bounds,
         ) {
@@ -1561,7 +1554,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         query_result: &Canonical<'tcx, QueryResponse<'tcx, Ty<'tcx>>>,
     ) -> InferResult<'tcx, Ty<'tcx>> {
         self.instantiate_query_response_and_region_obligations(
-            &traits::ObligationCause::misc(span, self.body_id),
+            &self.misc(span),
             self.param_env,
             original_values,
             query_result,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index fffea8f640b..d02e669e790 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -207,7 +207,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.register_wf_obligation(
                 fn_input_ty.into(),
                 arg_expr.span,
-                ObligationCauseCode::Misc,
+                ObligationCauseCode::WellFormed(None),
             );
         }
 
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index ef431c852e9..0c93c9817b4 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -601,7 +601,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                     self.call_expr.hir_id,
                     idx,
                 );
-                traits::ObligationCause::new(self.span, self.body_id, code)
+                self.cause(self.span, code)
             },
             self.param_env,
             method_predicates,
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index ace114f1ffa..116765325a9 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -1739,8 +1739,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         &self,
         trait_ref: ty::TraitRef<'tcx>,
     ) -> traits::SelectionResult<'tcx, traits::Selection<'tcx>> {
-        let cause = traits::ObligationCause::misc(self.span, self.body_id);
-        let obligation = traits::Obligation::new(self.tcx, cause, self.param_env, trait_ref);
+        let obligation =
+            traits::Obligation::new(self.tcx, self.misc(self.span), self.param_env, trait_ref);
         traits::SelectionContext::new(self).select(&obligation)
     }
 
@@ -1841,7 +1841,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                                 self.scope_expr_id,
                                 idx,
                             );
-                            ObligationCause::new(self.span, self.body_id, code)
+                            self.cause(self.span, code)
                         },
                         self.param_env,
                         impl_bounds,
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 1de88d52767..0b008fd10b5 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -105,8 +105,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return false;
         };
         let trait_ref = ty::TraitRef::new(self.tcx, into_iterator_trait, [ty]);
-        let cause = ObligationCause::new(span, self.body_id, ObligationCauseCode::Misc);
-        let obligation = Obligation::new(self.tcx, cause, self.param_env, trait_ref);
+        let obligation = Obligation::new(self.tcx, self.misc(span), self.param_env, trait_ref);
         if !self.predicate_must_hold_modulo_regions(&obligation) {
             return false;
         }
@@ -3489,7 +3488,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let pred = ty::TraitRef::new(self.tcx, unpin_trait, [*rcvr_ty]);
                 let unpin = self.predicate_must_hold_considering_regions(&Obligation::new(
                     self.tcx,
-                    ObligationCause::misc(rcvr.span, self.body_id),
+                    self.misc(rcvr.span),
                     self.param_env,
                     pred,
                 ));
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 5a3b9365cd2..97974d195fe 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -796,7 +796,7 @@ impl<T: Clone> Clone for Reverse<T> {
 /// }
 ///
 /// impl Ord for Character {
-///     fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+///     fn cmp(&self, other: &Self) -> Ordering {
 ///         self.experience
 ///             .cmp(&other.experience)
 ///             .then(self.health.cmp(&other.health))
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index 8a9321f8e79..68bb483be54 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -18,19 +18,10 @@ use crate::core::builder::{
     self, Alias, Builder, Compiler, Kind, RunConfig, ShouldRun, Step, crate_description,
 };
 use crate::core::config::{Config, TargetSelection};
-use crate::utils::helpers::{symlink_dir, t, up_to_date};
-
-macro_rules! submodule_helper {
-    ($path:expr, submodule) => {
-        $path
-    };
-    ($path:expr, submodule = $submodule:literal) => {
-        $submodule
-    };
-}
+use crate::helpers::{is_path_in_submodule, symlink_dir, t, up_to_date};
 
 macro_rules! book {
-    ($($name:ident, $path:expr, $book_name:expr, $lang:expr $(, submodule $(= $submodule:literal)? )? ;)+) => {
+    ($($name:ident, $path:expr, $book_name:expr, $lang:expr ;)+) => {
         $(
             #[derive(Debug, Clone, Hash, PartialEq, Eq)]
         pub struct $name {
@@ -53,10 +44,10 @@ macro_rules! book {
             }
 
             fn run(self, builder: &Builder<'_>) {
-                $(
-                    let path = submodule_helper!( $path, submodule $( = $submodule )? );
-                    builder.require_submodule(path, None);
-                )?
+                if is_path_in_submodule(&builder, $path) {
+                    builder.require_submodule($path, None);
+                }
+
                 builder.ensure(RustbookSrc {
                     target: self.target,
                     name: $book_name.to_owned(),
@@ -77,12 +68,12 @@ macro_rules! book {
 // FIXME: Make checking for a submodule automatic somehow (maybe by having a list of all submodules
 // and checking against it?).
 book!(
-    CargoBook, "src/tools/cargo/src/doc", "cargo", &[], submodule = "src/tools/cargo";
+    CargoBook, "src/tools/cargo/src/doc", "cargo", &[];
     ClippyBook, "src/tools/clippy/book", "clippy", &[];
-    EditionGuide, "src/doc/edition-guide", "edition-guide", &[], submodule;
-    EmbeddedBook, "src/doc/embedded-book", "embedded-book", &[], submodule;
-    Nomicon, "src/doc/nomicon", "nomicon", &[], submodule;
-    RustByExample, "src/doc/rust-by-example", "rust-by-example", &["ja", "zh"], submodule;
+    EditionGuide, "src/doc/edition-guide", "edition-guide", &[];
+    EmbeddedBook, "src/doc/embedded-book", "embedded-book", &[];
+    Nomicon, "src/doc/nomicon", "nomicon", &[];
+    RustByExample, "src/doc/rust-by-example", "rust-by-example", &["ja", "zh"];
     RustdocBook, "src/doc/rustdoc", "rustdoc", &[];
     StyleGuide, "src/doc/style-guide", "style-guide", &[];
 );
@@ -910,7 +901,6 @@ macro_rules! tool_doc {
         $(rustc_tool = $rustc_tool:literal, )?
         $(is_library = $is_library:expr,)?
         $(crates = $crates:expr)?
-        $(, submodule $(= $submodule:literal)? )?
        ) => {
         #[derive(Debug, Clone, Hash, PartialEq, Eq)]
         pub struct $tool {
@@ -938,14 +928,12 @@ macro_rules! tool_doc {
             /// we do not merge it with the other documentation from std, test and
             /// proc_macros. This is largely just a wrapper around `cargo doc`.
             fn run(self, builder: &Builder<'_>) {
-                let source_type = SourceType::InTree;
-                $(
-                    let _ = source_type; // silence the "unused variable" warning
-                    let source_type = SourceType::Submodule;
+                let mut source_type = SourceType::InTree;
 
-                    let path = submodule_helper!( $path, submodule $( = $submodule )? );
-                    builder.require_submodule(path, None);
-                )?
+                if is_path_in_submodule(&builder, $path) {
+                    source_type = SourceType::Submodule;
+                    builder.require_submodule($path, None);
+                }
 
                 let stage = builder.top_stage;
                 let target = self.target;
@@ -1054,8 +1042,7 @@ tool_doc!(
         "crates-io",
         "mdman",
         "rustfix",
-    ],
-    submodule = "src/tools/cargo"
+    ]
 );
 tool_doc!(Tidy, "src/tools/tidy", rustc_tool = false, crates = ["tidy"]);
 tool_doc!(
diff --git a/src/bootstrap/src/utils/helpers.rs b/src/bootstrap/src/utils/helpers.rs
index 923cc2dfc28..985d733a41f 100644
--- a/src/bootstrap/src/utils/helpers.rs
+++ b/src/bootstrap/src/utils/helpers.rs
@@ -60,6 +60,12 @@ pub fn is_dylib(path: &Path) -> bool {
     })
 }
 
+/// Returns `true` if the given path is part of a submodule.
+pub fn is_path_in_submodule(builder: &Builder<'_>, path: &str) -> bool {
+    let submodule_paths = build_helper::util::parse_gitmodules(&builder.src);
+    submodule_paths.iter().any(|submodule_path| path.starts_with(submodule_path))
+}
+
 fn is_aix_shared_archive(path: &Path) -> bool {
     let file = match fs::File::open(path) {
         Ok(file) => file,
diff --git a/src/bootstrap/src/utils/helpers/tests.rs b/src/bootstrap/src/utils/helpers/tests.rs
index f6fe6f47aa4..7bd2a47c63c 100644
--- a/src/bootstrap/src/utils/helpers/tests.rs
+++ b/src/bootstrap/src/utils/helpers/tests.rs
@@ -3,8 +3,8 @@ use std::io::Write;
 use std::path::PathBuf;
 
 use crate::utils::helpers::{
-    check_cfg_arg, extract_beta_rev, hex_encode, make, program_out_of_date, set_file_times,
-    symlink_dir,
+    check_cfg_arg, extract_beta_rev, hex_encode, is_path_in_submodule, make, program_out_of_date,
+    set_file_times, symlink_dir,
 };
 use crate::{Config, Flags};
 
@@ -115,3 +115,18 @@ fn test_set_file_times_sanity_check() {
     assert_eq!(found_metadata.accessed().unwrap(), unix_epoch);
     assert_eq!(found_metadata.modified().unwrap(), unix_epoch)
 }
+
+#[test]
+fn test_is_path_in_submodule() {
+    let config = Config::parse_inner(Flags::parse(&["build".into(), "--dry-run".into()]), |&_| {
+        Ok(Default::default())
+    });
+
+    let build = crate::Build::new(config.clone());
+    let builder = crate::core::builder::Builder::new(&build);
+    assert!(!is_path_in_submodule(&builder, "invalid/path"));
+    assert!(is_path_in_submodule(&builder, "src/tools/cargo"));
+    assert!(is_path_in_submodule(&builder, "src/llvm-project"));
+    // Make sure subdirs are handled properly
+    assert!(is_path_in_submodule(&builder, "src/tools/cargo/random-subdir"));
+}
diff --git a/src/librustdoc/html/markdown/footnotes.rs b/src/librustdoc/html/markdown/footnotes.rs
index 519778e4d3b..ded0585ddcc 100644
--- a/src/librustdoc/html/markdown/footnotes.rs
+++ b/src/librustdoc/html/markdown/footnotes.rs
@@ -91,7 +91,7 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for Footnotes<'a, I> {
                 Some(e) => return Some(e),
                 None => {
                     if !self.footnotes.is_empty() {
-                        // After all the markdown is emmited, emit an <hr> then all the footnotes
+                        // After all the markdown is emitted, emit an <hr> then all the footnotes
                         // in a list.
                         let defs: Vec<_> = self.footnotes.drain(..).map(|(_, x)| x).collect();
                         self.existing_footnotes.fetch_add(defs.len(), Ordering::Relaxed);
diff --git a/src/librustdoc/html/render/sorted_template.rs b/src/librustdoc/html/render/sorted_template.rs
index dc894840f92..a7b954ab70b 100644
--- a/src/librustdoc/html/render/sorted_template.rs
+++ b/src/librustdoc/html/render/sorted_template.rs
@@ -27,7 +27,7 @@ struct Offset {
 }
 
 impl<F> SortedTemplate<F> {
-    /// Generate this template from arbitary text.
+    /// Generate this template from arbitrary text.
     /// Will insert wherever the substring `delimiter` can be found.
     /// Errors if it does not appear exactly once.
     pub(crate) fn from_template(template: &str, delimiter: &str) -> Result<Self, Error> {
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index 04eeee37fe8..5fd5eb14478 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -2848,7 +2848,7 @@ class DocSearch {
          *     - Limit checks that Ty matches Vec<Ty>,
          *       but not Vec<ParamEnvAnd<WithInfcx<ConstTy<Interner<Ty=Ty>>>>>
          *
-         * @return {[FunctionType]|null} - Returns highlighed results if a match, null otherwise.
+         * @return {[FunctionType]|null} - Returns highlighted results if a match, null otherwise.
          */
         function unifyFunctionTypes(
             fnTypesIn,
@@ -3148,7 +3148,7 @@ class DocSearch {
          *     - Limit checks that Ty matches Vec<Ty>,
          *       but not Vec<ParamEnvAnd<WithInfcx<ConstTy<Interner<Ty=Ty>>>>>
          *
-         * @return {[FunctionType]|null} - Returns highlighed results if a match, null otherwise.
+         * @return {[FunctionType]|null} - Returns highlighted results if a match, null otherwise.
          */
         function unifyGenericTypes(
             fnTypesIn,
diff --git a/src/tools/rust-installer/install-template.sh b/src/tools/rust-installer/install-template.sh
index b477c3eac35..f7f408be882 100644
--- a/src/tools/rust-installer/install-template.sh
+++ b/src/tools/rust-installer/install-template.sh
@@ -584,7 +584,7 @@ install_components() {
             # HACK: Try to support overriding --docdir.  Paths with the form
             # "share/doc/$product/" can be redirected to a single --docdir
             # path. If the following detects that --docdir has been specified
-            # then it will replace everything preceeding the "$product" path
+            # then it will replace everything preceding the "$product" path
             # component. The problem here is that the combined rust installer
             # contains two "products": rust and cargo; so the contents of those
             # directories will both be dumped into the same directory; and the
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 1794d0fbca7..d00d5a9b4da 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -214,7 +214,7 @@ const EXCEPTIONS_BOOTSTRAP: ExceptionList = &[
 ];
 
 const EXCEPTIONS_UEFI_QEMU_TEST: ExceptionList = &[
-    ("r-efi", "MIT OR Apache-2.0 OR LGPL-2.1-or-later"), // LGPL is not acceptible, but we use it under MIT OR Apache-2.0
+    ("r-efi", "MIT OR Apache-2.0 OR LGPL-2.1-or-later"), // LGPL is not acceptable, but we use it under MIT OR Apache-2.0
 ];
 
 /// Placeholder for non-standard license file.
diff --git a/src/tools/tidy/src/ext_tool_checks.rs b/src/tools/tidy/src/ext_tool_checks.rs
index e8370a0af02..6269d91c7ec 100644
--- a/src/tools/tidy/src/ext_tool_checks.rs
+++ b/src/tools/tidy/src/ext_tool_checks.rs
@@ -1,6 +1,6 @@
 //! Optional checks for file types other than Rust source
 //!
-//! Handles python tool version managment via a virtual environment in
+//! Handles python tool version management via a virtual environment in
 //! `build/venv`.
 //!
 //! # Functional outline
diff --git a/tests/crashes/132766.rs b/tests/crashes/132766.rs
deleted file mode 100644
index 5f5117d77a5..00000000000
--- a/tests/crashes/132766.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ known-bug: #132766
-
-trait Trait {}
-impl<'a> Trait for () {
-    fn pass2<'a>() -> impl Trait2 {}
-}
-
-trait Trait2 {}
-impl Trait2 for () {}
diff --git a/tests/ui/impl-trait/captured-invalid-lifetime.rs b/tests/ui/impl-trait/captured-invalid-lifetime.rs
new file mode 100644
index 00000000000..57cd2e85dd0
--- /dev/null
+++ b/tests/ui/impl-trait/captured-invalid-lifetime.rs
@@ -0,0 +1,19 @@
+// This uses edition 2024 for new lifetime capture rules.
+//@ edition: 2024
+
+// The problem here is that the presence of the opaque which captures all lifetimes in scope
+// means that the duplicated `'a` (which I'll call the dupe) is considered to be *early-bound*
+// since it shows up in the output but not the inputs. This is paired with the fact that we
+// were previously setting the name of the dupe to `'_` in the generic param definition, which
+// means that the identity args for the function were `['a#0, '_#1]` even though the lifetime
+// for the dupe should've been `'a#1`. This difference in symbol meant that NLL couldn't
+// actually match the lifetime against the identity lifetimes, leading to an ICE.
+
+struct Foo<'a>(&'a ());
+
+impl<'a> Foo<'a> {
+    fn pass<'a>() -> impl Sized {}
+    //~^ ERROR lifetime name `'a` shadows a lifetime name that is already in scope
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/captured-invalid-lifetime.stderr b/tests/ui/impl-trait/captured-invalid-lifetime.stderr
new file mode 100644
index 00000000000..c1315e34241
--- /dev/null
+++ b/tests/ui/impl-trait/captured-invalid-lifetime.stderr
@@ -0,0 +1,11 @@
+error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
+  --> $DIR/captured-invalid-lifetime.rs:15:13
+   |
+LL | impl<'a> Foo<'a> {
+   |      -- first declared here
+LL |     fn pass<'a>() -> impl Sized {}
+   |             ^^ lifetime `'a` already in scope
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0496`.
diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr
index 7183073d665..9b1568fa116 100644
--- a/tests/ui/stats/input-stats.stderr
+++ b/tests/ui/stats/input-stats.stderr
@@ -146,13 +146,13 @@ hir-stats Variant                  144 ( 1.6%)             2            72
 hir-stats GenericBound             256 ( 2.9%)             4            64
 hir-stats - Trait                    256 ( 2.9%)             4
 hir-stats Block                    288 ( 3.2%)             6            48
-hir-stats GenericParam             360 ( 4.0%)             5            72
 hir-stats Pat                      360 ( 4.0%)             5            72
 hir-stats - Struct                    72 ( 0.8%)             1
 hir-stats - Wild                      72 ( 0.8%)             1
 hir-stats - Binding                  216 ( 2.4%)             3
-hir-stats Generics                 560 ( 6.3%)            10            56
-hir-stats Ty                       720 ( 8.1%)            15            48
+hir-stats GenericParam             400 ( 4.5%)             5            80
+hir-stats Generics                 560 ( 6.2%)            10            56
+hir-stats Ty                       720 ( 8.0%)            15            48
 hir-stats - Ptr                       48 ( 0.5%)             1
 hir-stats - Ref                       48 ( 0.5%)             1
 hir-stats - Path                     624 ( 7.0%)            13
@@ -171,8 +171,8 @@ hir-stats - Impl                      88 ( 1.0%)             1
 hir-stats - Trait                     88 ( 1.0%)             1
 hir-stats - Fn                       176 ( 2.0%)             2
 hir-stats - Use                      352 ( 3.9%)             4
-hir-stats Path                   1_240 (13.9%)            31            40
-hir-stats PathSegment            1_920 (21.5%)            40            48
+hir-stats Path                   1_240 (13.8%)            31            40
+hir-stats PathSegment            1_920 (21.4%)            40            48
 hir-stats ----------------------------------------------------------------
-hir-stats Total                  8_936                   180
+hir-stats Total                  8_976                   180
 hir-stats