about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_borrowck/src/region_infer/opaque_types.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/inherited.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs10
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs4
-rw-r--r--compiler/rustc_parse/locales/en-US.ftl3
-rw-r--r--compiler/rustc_parse/src/errors.rs17
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs41
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs4
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs12
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt.rs35
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs99
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs2
-rw-r--r--library/core/src/convert/num.rs26
-rw-r--r--library/core/src/ptr/mod.rs4
-rw-r--r--src/bootstrap/format.rs8
-rw-r--r--src/bootstrap/native.rs2
-rwxr-xr-xsrc/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh10
-rw-r--r--src/librustdoc/clean/mod.rs108
-rw-r--r--src/librustdoc/html/render/context.rs28
-rw-r--r--src/librustdoc/html/render/span_map.rs6
-rw-r--r--src/librustdoc/html/static/js/main.js39
-rw-r--r--src/librustdoc/html/static/js/storage.js47
-rw-r--r--src/librustdoc/html/templates/page.html39
-rw-r--r--src/librustdoc/visit_ast.rs29
-rw-r--r--src/tools/tidy/src/pal.rs3
-rw-r--r--tests/run-make-fulldeps/rustdoc-themes/foo.rs2
-rw-r--r--tests/rustdoc-gui/scrape-examples-button-focus.goml10
-rw-r--r--tests/rustdoc/anonymous-reexport.rs8
-rw-r--r--tests/rustdoc/issue-108679-reexport-of-reexport.rs29
-rw-r--r--tests/rustdoc/issue-108931-anonymous-reexport.rs21
-rw-r--r--tests/ui/parser/integer-literal-start-ident.rs2
-rw-r--r--tests/ui/parser/integer-literal-start-ident.stderr10
-rw-r--r--tests/ui/parser/issues/issue-104088.rs6
-rw-r--r--tests/ui/parser/issues/issue-104088.stderr18
-rw-r--r--tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.rs16
-rw-r--r--tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.stderr22
-rw-r--r--triagebot.toml5
46 files changed, 502 insertions, 276 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
index ec4b2e9d3e4..748c8b9e442 100644
--- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
+++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs
@@ -325,7 +325,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
         if errors.is_empty() {
             definition_ty
         } else {
-            let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+            let reported = infcx.err_ctxt().report_fulfillment_errors(&errors);
             self.tcx.ty_error(reported)
         }
     }
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index 656baa784d7..61c4d28bdfa 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -769,7 +769,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
 
                         let errors = ocx.select_all_or_error();
                         if !errors.is_empty() {
-                            infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+                            infcx.err_ctxt().report_fulfillment_errors(&errors);
                         }
                     }
 
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index be0ae4ce2ef..14dc9d89180 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -444,7 +444,7 @@ fn check_opaque_meets_bounds<'tcx>(
     // version.
     let errors = ocx.select_all_or_error();
     if !errors.is_empty() {
-        infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+        infcx.err_ctxt().report_fulfillment_errors(&errors);
     }
     match origin {
         // Checked when type checking the function containing them.
@@ -1545,6 +1545,6 @@ pub(super) fn check_generator_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     let errors = fulfillment_cx.select_all_or_error(&infcx);
     debug!(?errors);
     if !errors.is_empty() {
-        infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+        infcx.err_ctxt().report_fulfillment_errors(&errors);
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 5adc7a87323..5e2781925e6 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -320,7 +320,7 @@ fn compare_method_predicate_entailment<'tcx>(
                 });
             }
             CheckImpliedWfMode::Skip => {
-                let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+                let reported = infcx.err_ctxt().report_fulfillment_errors(&errors);
                 return Err(reported);
             }
         }
@@ -720,7 +720,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
     // RPITs.
     let errors = ocx.select_all_or_error();
     if !errors.is_empty() {
-        let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+        let reported = infcx.err_ctxt().report_fulfillment_errors(&errors);
         return Err(reported);
     }
 
@@ -1731,7 +1731,7 @@ pub(super) fn compare_impl_const_raw(
     // version.
     let errors = ocx.select_all_or_error();
     if !errors.is_empty() {
-        return Err(infcx.err_ctxt().report_fulfillment_errors(&errors, None));
+        return Err(infcx.err_ctxt().report_fulfillment_errors(&errors));
     }
 
     let outlives_environment = OutlivesEnvironment::new(param_env);
@@ -1831,7 +1831,7 @@ fn compare_type_predicate_entailment<'tcx>(
     // version.
     let errors = ocx.select_all_or_error();
     if !errors.is_empty() {
-        let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+        let reported = infcx.err_ctxt().report_fulfillment_errors(&errors);
         return Err(reported);
     }
 
@@ -2044,7 +2044,7 @@ pub(super) fn check_type_bounds<'tcx>(
     // version.
     let errors = ocx.select_all_or_error();
     if !errors.is_empty() {
-        let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+        let reported = infcx.err_ctxt().report_fulfillment_errors(&errors);
         return Err(reported);
     }
 
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 4cccdf30c5f..71050864ce0 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -111,7 +111,7 @@ pub(super) fn enter_wf_checking_ctxt<'tcx, F>(
 
     let errors = wfcx.select_all_or_error();
     if !errors.is_empty() {
-        infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+        infcx.err_ctxt().report_fulfillment_errors(&errors);
         return;
     }
 
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 8294d92c936..5e8f69677cf 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -345,7 +345,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
                     }),
                 );
                 if !errors.is_empty() {
-                    infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+                    infcx.err_ctxt().report_fulfillment_errors(&errors);
                 }
 
                 // Finally, resolve all regions.
@@ -585,7 +585,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn
         predicate_for_trait_def(tcx, param_env, cause, trait_def_id, 0, [source, target]);
     let errors = traits::fully_solve_obligation(&infcx, predicate);
     if !errors.is_empty() {
-        infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+        infcx.err_ctxt().report_fulfillment_errors(&errors);
     }
 
     // Finally, resolve all regions.
diff --git a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
index daa5d15704d..58dd03811f7 100644
--- a/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
+++ b/compiler/rustc_hir_analysis/src/impl_wf_check/min_specialization.rs
@@ -174,7 +174,7 @@ fn get_impl_substs(
 
     let errors = ocx.select_all_or_error();
     if !errors.is_empty() {
-        ocx.infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+        ocx.infcx.err_ctxt().report_fulfillment_errors(&errors);
         return None;
     }
 
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 33c132fd534..7abdde2c892 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -176,7 +176,7 @@ fn require_same_types<'tcx>(
     match &errors[..] {
         [] => true,
         errors => {
-            infcx.err_ctxt().report_fulfillment_errors(errors, None);
+            infcx.err_ctxt().report_fulfillment_errors(errors);
             false
         }
     }
@@ -309,7 +309,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
         ocx.register_bound(cause, param_env, norm_return_ty, term_did);
         let errors = ocx.select_all_or_error();
         if !errors.is_empty() {
-            infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+            infcx.err_ctxt().report_fulfillment_errors(&errors);
             error = true;
         }
         // now we can take the return type of the given main function
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index ac7d984c161..2075537cad7 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -581,7 +581,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if !errors.is_empty() {
             self.adjust_fulfillment_errors_for_expr_obligation(&mut errors);
-            self.err_ctxt().report_fulfillment_errors(&errors, self.inh.body_id);
+            self.err_ctxt().report_fulfillment_errors(&errors);
         }
     }
 
@@ -594,7 +594,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if !result.is_empty() {
             mutate_fulfillment_errors(&mut result);
             self.adjust_fulfillment_errors_for_expr_obligation(&mut result);
-            self.err_ctxt().report_fulfillment_errors(&result, self.inh.body_id);
+            self.err_ctxt().report_fulfillment_errors(&result);
         }
     }
 
@@ -1411,7 +1411,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         } else {
             let e = self.tainted_by_errors().unwrap_or_else(|| {
                 self.err_ctxt()
-                    .emit_inference_failure_err((**self).body_id, sp, ty.into(), E0282, true)
+                    .emit_inference_failure_err(self.body_id, sp, ty.into(), E0282, true)
                     .emit()
             });
             let err = self.tcx.ty_error(e);
diff --git a/compiler/rustc_hir_typeck/src/inherited.rs b/compiler/rustc_hir_typeck/src/inherited.rs
index 26020382d81..07fa7c55df6 100644
--- a/compiler/rustc_hir_typeck/src/inherited.rs
+++ b/compiler/rustc_hir_typeck/src/inherited.rs
@@ -58,8 +58,6 @@ pub struct Inherited<'tcx> {
     pub(super) deferred_generator_interiors:
         RefCell<Vec<(LocalDefId, hir::BodyId, Ty<'tcx>, hir::GeneratorKind)>>,
 
-    pub(super) body_id: Option<hir::BodyId>,
-
     /// Whenever we introduce an adjustment from `!` into a type variable,
     /// we record that type variable here. This is later used to inform
     /// fallback. See the `fallback` module for details.
@@ -80,7 +78,6 @@ impl<'tcx> Deref for Inherited<'tcx> {
 /// without using `Rc` or something similar.
 pub struct InheritedBuilder<'tcx> {
     infcx: infer::InferCtxtBuilder<'tcx>,
-    def_id: LocalDefId,
     typeck_results: RefCell<ty::TypeckResults<'tcx>>,
 }
 
@@ -93,7 +90,6 @@ impl<'tcx> Inherited<'tcx> {
                 .infer_ctxt()
                 .ignoring_regions()
                 .with_opaque_type_inference(DefiningAnchor::Bind(hir_owner.def_id)),
-            def_id,
             typeck_results: RefCell::new(ty::TypeckResults::new(hir_owner)),
         }
     }
@@ -104,19 +100,13 @@ impl<'tcx> InheritedBuilder<'tcx> {
     where
         F: FnOnce(&Inherited<'tcx>) -> R,
     {
-        let def_id = self.def_id;
-        f(&Inherited::new(self.infcx.build(), def_id, self.typeck_results))
+        f(&Inherited::new(self.infcx.build(), self.typeck_results))
     }
 }
 
 impl<'tcx> Inherited<'tcx> {
-    fn new(
-        infcx: InferCtxt<'tcx>,
-        def_id: LocalDefId,
-        typeck_results: RefCell<ty::TypeckResults<'tcx>>,
-    ) -> Self {
+    fn new(infcx: InferCtxt<'tcx>, typeck_results: RefCell<ty::TypeckResults<'tcx>>) -> Self {
         let tcx = infcx.tcx;
-        let body_id = tcx.hir().maybe_body_owned_by(def_id);
 
         Inherited {
             typeck_results,
@@ -130,7 +120,6 @@ impl<'tcx> Inherited<'tcx> {
             deferred_asm_checks: RefCell::new(Vec::new()),
             deferred_generator_interiors: RefCell::new(Vec::new()),
             diverging_type_vars: RefCell::new(Default::default()),
-            body_id,
             infer_var_info: RefCell::new(Default::default()),
         }
     }
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 00348f3afdc..af588b16d59 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -748,7 +748,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
                 .infcx
                 .err_ctxt()
                 .emit_inference_failure_err(
-                    Some(self.body.id()),
+                    self.tcx.hir().body_owner_def_id(self.body.id()),
                     self.span.to_span(self.tcx),
                     p.into(),
                     E0282,
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index a3151d2d365..bde16fad821 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -10,7 +10,7 @@ use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, IntoDiagnosticArg};
 use rustc_hir as hir;
 use rustc_hir::def::Res;
 use rustc_hir::def::{CtorOf, DefKind, Namespace};
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{Body, Closure, Expr, ExprKind, FnRetTy, HirId, Local, LocalSource};
 use rustc_middle::hir::nested_filter;
@@ -386,7 +386,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     #[instrument(level = "debug", skip(self, error_code))]
     pub fn emit_inference_failure_err(
         &self,
-        body_id: Option<hir::BodyId>,
+        body_def_id: LocalDefId,
         failure_span: Span,
         arg: GenericArg<'tcx>,
         error_code: TypeAnnotationNeeded,
@@ -403,8 +403,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         };
 
         let mut local_visitor = FindInferSourceVisitor::new(&self, typeck_results, arg);
-        if let Some(body_id) = body_id {
-            let expr = self.tcx.hir().expect_expr(body_id.hir_id);
+        if let Some(body_id) = self.tcx.hir().maybe_body_owned_by(
+            self.tcx.typeck_root_def_id(body_def_id.to_def_id()).expect_local(),
+        ) {
+            let expr = self.tcx.hir().body(body_id).value;
             local_visitor.visit_expr(expr);
         }
 
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index 3ca17e7273e..ae0bb4949c7 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -117,7 +117,7 @@ pub fn suggest_arbitrary_trait_bound<'tcx>(
     }
 
     let param_name = trait_pred.skip_binder().self_ty().to_string();
-    let mut constraint = trait_pred.print_modifiers_and_trait_path().to_string();
+    let mut constraint = trait_pred.to_string();
 
     if let Some((name, term)) = associated_ty {
         // FIXME: this case overlaps with code in TyCtxt::note_and_explain_type_err.
@@ -144,7 +144,7 @@ pub fn suggest_arbitrary_trait_bound<'tcx>(
              this requirement",
             if generics.where_clause_span.is_empty() { "introducing a" } else { "extending the" },
         ),
-        format!("{} {}: {}", generics.add_where_or_trailing_comma(), param_name, constraint),
+        format!("{} {constraint}", generics.add_where_or_trailing_comma()),
         Applicability::MaybeIncorrect,
     );
     true
diff --git a/compiler/rustc_parse/locales/en-US.ftl b/compiler/rustc_parse/locales/en-US.ftl
index e76e91fc1b1..5c7dc1e2abf 100644
--- a/compiler/rustc_parse/locales/en-US.ftl
+++ b/compiler/rustc_parse/locales/en-US.ftl
@@ -412,8 +412,7 @@ parse_fn_ptr_with_generics = function pointer types may not have generic paramet
         *[false] a
     } `for` parameter list
 
-parse_invalid_identifier_with_leading_number = expected identifier, found number literal
-    .label = identifiers cannot start with a number
+parse_invalid_identifier_with_leading_number = identifiers cannot start with a number
 
 parse_maybe_fn_typo_with_impl = you might have meant to write `impl` instead of `fn`
     .suggestion = replace `fn` with `impl` here
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 1662db36d10..63e5bc50513 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -939,6 +939,7 @@ pub(crate) struct ExpectedIdentifier {
     pub token: Token,
     pub suggest_raw: Option<SuggEscapeToUseAsIdentifier>,
     pub suggest_remove_comma: Option<SuggRemoveComma>,
+    pub help_cannot_start_number: Option<HelpIdentifierStartsWithNumber>,
 }
 
 impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
@@ -975,10 +976,18 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
             sugg.add_to_diagnostic(&mut diag);
         }
 
+        if let Some(help) = self.help_cannot_start_number {
+            help.add_to_diagnostic(&mut diag);
+        }
+
         diag
     }
 }
 
+#[derive(Subdiagnostic)]
+#[help(parse_invalid_identifier_with_leading_number)]
+pub(crate) struct HelpIdentifierStartsWithNumber;
+
 pub(crate) struct ExpectedSemi {
     pub span: Span,
     pub token: Token,
@@ -1208,14 +1217,6 @@ pub(crate) struct SelfParamNotFirst {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_invalid_identifier_with_leading_number)]
-pub(crate) struct InvalidIdentiferStartsWithNumber {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-}
-
-#[derive(Diagnostic)]
 #[diag(parse_const_generic_without_braces)]
 pub(crate) struct ConstGenericWithoutBraces {
     #[primary_span]
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 0a65c37ea7b..5b12bcc1822 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -8,14 +8,14 @@ use crate::errors::{
     ComparisonOperatorsCannotBeChained, ComparisonOperatorsCannotBeChainedSugg,
     ConstGenericWithoutBraces, ConstGenericWithoutBracesSugg, DocCommentOnParamType,
     DoubleColonInBound, ExpectedIdentifier, ExpectedSemi, ExpectedSemiSugg,
-    GenericParamsWithoutAngleBrackets, GenericParamsWithoutAngleBracketsSugg, InInTypo,
-    IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait, ParenthesesInForHead,
-    ParenthesesInForHeadSugg, PatternMethodParamWithoutBody, QuestionMarkInType,
-    QuestionMarkInTypeSugg, SelfParamNotFirst, StructLiteralBodyWithoutPath,
-    StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens, StructLiteralNeedingParensSugg,
-    SuggEscapeToUseAsIdentifier, SuggRemoveComma, UnexpectedConstInGenericParam,
-    UnexpectedConstParamDeclaration, UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets,
-    UseEqInstead,
+    GenericParamsWithoutAngleBrackets, GenericParamsWithoutAngleBracketsSugg,
+    HelpIdentifierStartsWithNumber, InInTypo, IncorrectAwait, IncorrectSemicolon,
+    IncorrectUseOfAwait, ParenthesesInForHead, ParenthesesInForHeadSugg,
+    PatternMethodParamWithoutBody, QuestionMarkInType, QuestionMarkInTypeSugg, SelfParamNotFirst,
+    StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens,
+    StructLiteralNeedingParensSugg, SuggEscapeToUseAsIdentifier, SuggRemoveComma,
+    UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
+    UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead,
 };
 
 use crate::fluent_generated as fluent;
@@ -280,6 +280,7 @@ impl<'a> Parser<'a> {
             TokenKind::CloseDelim(Delimiter::Brace),
             TokenKind::CloseDelim(Delimiter::Parenthesis),
         ];
+
         let suggest_raw = match self.token.ident() {
             Some((ident, false))
                 if ident.is_raw_guess()
@@ -295,18 +296,19 @@ impl<'a> Parser<'a> {
             _ => None,
         };
 
-        let suggest_remove_comma =
-            if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) {
-                Some(SuggRemoveComma { span: self.token.span })
-            } else {
-                None
-            };
+        let suggest_remove_comma = (self.token == token::Comma
+            && self.look_ahead(1, |t| t.is_ident()))
+        .then_some(SuggRemoveComma { span: self.token.span });
+
+        let help_cannot_start_number =
+            self.is_lit_bad_ident().then_some(HelpIdentifierStartsWithNumber);
 
         let err = ExpectedIdentifier {
             span: self.token.span,
             token: self.token.clone(),
             suggest_raw,
             suggest_remove_comma,
+            help_cannot_start_number,
         };
         let mut err = err.into_diagnostic(&self.sess.span_diagnostic);
 
@@ -365,6 +367,17 @@ impl<'a> Parser<'a> {
         err
     }
 
+    /// Checks if the current token is a integer or float literal and looks like
+    /// it could be a invalid identifier with digits at the start.
+    pub(super) fn is_lit_bad_ident(&mut self) -> bool {
+        matches!(self.token.uninterpolate().kind, token::Literal(Lit { kind: token::LitKind::Integer | token::LitKind::Float, .. })
+            // ensure that the integer literal is followed by a *invalid*
+            // suffix: this is how we know that it is a identifier with an
+            // invalid beginning.
+            if rustc_ast::MetaItemLit::from_token(&self.token).is_none()
+        )
+    }
+
     pub(super) fn expected_one_of_not_found(
         &mut self,
         edible: &[TokenKind],
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 8e920f1c421..fc9f1d1330a 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -348,6 +348,10 @@ impl<'a> Parser<'a> {
             lo = self.token.span;
         }
 
+        if self.is_lit_bad_ident() {
+            return Err(self.expected_ident_found());
+        }
+
         let pat = if self.check(&token::BinOp(token::And)) || self.token.kind == token::AndAnd {
             self.parse_pat_deref(expected)?
         } else if self.check(&token::OpenDelim(Delimiter::Parenthesis)) {
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 92a22ffc2b0..fbe5b88c49e 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -273,7 +273,6 @@ impl<'a> Parser<'a> {
             self.bump();
         }
 
-        self.report_invalid_identifier_error()?;
         let (pat, colon) =
             self.parse_pat_before_ty(None, RecoverComma::Yes, PatternLocation::LetBinding)?;
 
@@ -366,17 +365,6 @@ impl<'a> Parser<'a> {
         Ok(P(ast::Local { ty, pat, kind, id: DUMMY_NODE_ID, span: lo.to(hi), attrs, tokens: None }))
     }
 
-    /// report error for `let 1x = 123`
-    pub fn report_invalid_identifier_error(&mut self) -> PResult<'a, ()> {
-        if let token::Literal(lit) = self.token.uninterpolate().kind &&
-            rustc_ast::MetaItemLit::from_token(&self.token).is_none() &&
-            (lit.kind == token::LitKind::Integer || lit.kind == token::LitKind::Float) &&
-            self.look_ahead(1, |t| matches!(t.kind, token::Eq) || matches!(t.kind, token::Colon ) ) {
-                return Err(self.sess.create_err(errors::InvalidIdentiferStartsWithNumber { span: self.token.span }));
-        }
-        Ok(())
-    }
-
     fn check_let_else_init_bool_expr(&self, init: &ast::Expr) {
         if let ast::ExprKind::Binary(op, ..) = init.kind {
             if op.node.lazy() {
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
index 95612674eb9..ca438a103cf 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt.rs
@@ -93,37 +93,42 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         };
 
         // Guard against `<T as Trait<?0>>::Assoc = ?0>`.
-        struct ContainsTerm<'tcx> {
+        struct ContainsTerm<'a, 'tcx> {
             term: ty::Term<'tcx>,
+            infcx: &'a InferCtxt<'tcx>,
         }
-        impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTerm<'tcx> {
+        impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTerm<'_, 'tcx> {
             type BreakTy = ();
             fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
-                if t.needs_infer() {
-                    if ty::Term::from(t) == self.term {
-                        ControlFlow::Break(())
-                    } else {
-                        t.super_visit_with(self)
-                    }
+                if let Some(vid) = t.ty_vid()
+                    && let ty::TermKind::Ty(term) = self.term.unpack()
+                    && let Some(term_vid) = term.ty_vid()
+                    && self.infcx.root_var(vid) == self.infcx.root_var(term_vid)
+                {
+                    ControlFlow::Break(())
+                } else if t.has_non_region_infer() {
+                    t.super_visit_with(self)
                 } else {
                     ControlFlow::Continue(())
                 }
             }
 
             fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
-                if c.needs_infer() {
-                    if ty::Term::from(c) == self.term {
-                        ControlFlow::Break(())
-                    } else {
-                        c.super_visit_with(self)
-                    }
+                if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = c.kind()
+                    && let ty::TermKind::Const(term) = self.term.unpack()
+                    && let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
+                    && self.infcx.root_const_var(vid) == self.infcx.root_const_var(term_vid)
+                {
+                    ControlFlow::Break(())
+                } else if c.has_non_region_infer() {
+                    c.super_visit_with(self)
                 } else {
                     ControlFlow::Continue(())
                 }
             }
         }
 
-        let mut visitor = ContainsTerm { term: goal.predicate.term };
+        let mut visitor = ContainsTerm { infcx: self.infcx, term: goal.predicate.term };
 
         term_is_infer
             && goal.predicate.projection_ty.visit_with(&mut visitor).is_continue()
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index a844a1494e2..2dfebfcb904 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -24,11 +24,9 @@ use rustc_errors::{
 };
 use rustc_hir as hir;
 use rustc_hir::def::Namespace;
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::Visitor;
-use rustc_hir::GenericParam;
-use rustc_hir::Item;
-use rustc_hir::Node;
+use rustc_hir::{GenericParam, Item, Node};
 use rustc_infer::infer::error_reporting::TypeErrCtxt;
 use rustc_infer::infer::{InferOk, TypeTrace};
 use rustc_middle::traits::select::OverflowError;
@@ -126,11 +124,7 @@ pub trait TypeErrCtxtExt<'tcx> {
             + Print<'tcx, FmtPrinter<'tcx, 'tcx>, Output = FmtPrinter<'tcx, 'tcx>>,
         <T as Print<'tcx, FmtPrinter<'tcx, 'tcx>>>::Error: std::fmt::Debug;
 
-    fn report_fulfillment_errors(
-        &self,
-        errors: &[FulfillmentError<'tcx>],
-        body_id: Option<hir::BodyId>,
-    ) -> ErrorGuaranteed;
+    fn report_fulfillment_errors(&self, errors: &[FulfillmentError<'tcx>]) -> ErrorGuaranteed;
 
     fn report_overflow_obligation<T>(
         &self,
@@ -388,11 +382,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
 }
 
 impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
-    fn report_fulfillment_errors(
-        &self,
-        errors: &[FulfillmentError<'tcx>],
-        body_id: Option<hir::BodyId>,
-    ) -> ErrorGuaranteed {
+    fn report_fulfillment_errors(&self, errors: &[FulfillmentError<'tcx>]) -> ErrorGuaranteed {
         #[derive(Debug)]
         struct ErrorDescriptor<'tcx> {
             predicate: ty::Predicate<'tcx>,
@@ -469,7 +459,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         for from_expansion in [false, true] {
             for (error, suppressed) in iter::zip(errors, &is_suppressed) {
                 if !suppressed && error.obligation.cause.span.from_expansion() == from_expansion {
-                    self.report_fulfillment_error(error, body_id);
+                    self.report_fulfillment_error(error);
                 }
             }
         }
@@ -955,8 +945,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             );
                         }
 
-                        let body_hir_id =
-                            self.tcx.hir().local_def_id_to_hir_id(obligation.cause.body_id);
+                        let body_def_id = obligation.cause.body_id;
                         // Try to report a help message
                         if is_fn_trait
                             && let Ok((implemented_kind, params)) = self.type_implements_fn_trait(
@@ -1037,7 +1026,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                             if !self.report_similar_impl_candidates(
                                 impl_candidates,
                                 trait_ref,
-                                body_hir_id,
+                                body_def_id,
                                 &mut err,
                                 true,
                             ) {
@@ -1073,7 +1062,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                     self.report_similar_impl_candidates(
                                         impl_candidates,
                                         trait_ref,
-                                        body_hir_id,
+                                        body_def_id,
                                         &mut err,
                                         true,
                                     );
@@ -1494,11 +1483,7 @@ trait InferCtxtPrivExt<'tcx> {
     // `error` occurring implies that `cond` occurs.
     fn error_implies(&self, cond: ty::Predicate<'tcx>, error: ty::Predicate<'tcx>) -> bool;
 
-    fn report_fulfillment_error(
-        &self,
-        error: &FulfillmentError<'tcx>,
-        body_id: Option<hir::BodyId>,
-    );
+    fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>);
 
     fn report_projection_error(
         &self,
@@ -1531,7 +1516,7 @@ trait InferCtxtPrivExt<'tcx> {
         &self,
         impl_candidates: Vec<ImplCandidate<'tcx>>,
         trait_ref: ty::PolyTraitRef<'tcx>,
-        body_id: hir::HirId,
+        body_def_id: LocalDefId,
         err: &mut Diagnostic,
         other: bool,
     ) -> bool;
@@ -1561,11 +1546,7 @@ trait InferCtxtPrivExt<'tcx> {
         trait_ref_and_ty: ty::Binder<'tcx, (ty::TraitPredicate<'tcx>, Ty<'tcx>)>,
     ) -> PredicateObligation<'tcx>;
 
-    fn maybe_report_ambiguity(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        body_id: Option<hir::BodyId>,
-    );
+    fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>);
 
     fn predicate_can_apply(
         &self,
@@ -1647,11 +1628,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     }
 
     #[instrument(skip(self), level = "debug")]
-    fn report_fulfillment_error(
-        &self,
-        error: &FulfillmentError<'tcx>,
-        body_id: Option<hir::BodyId>,
-    ) {
+    fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) {
         match error.code {
             FulfillmentErrorCode::CodeSelectionError(ref selection_error) => {
                 self.report_selection_error(
@@ -1664,7 +1641,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 self.report_projection_error(&error.obligation, e);
             }
             FulfillmentErrorCode::CodeAmbiguity => {
-                self.maybe_report_ambiguity(&error.obligation, body_id);
+                self.maybe_report_ambiguity(&error.obligation);
             }
             FulfillmentErrorCode::CodeSubtypeError(ref expected_found, ref err) => {
                 self.report_mismatched_types(
@@ -2029,7 +2006,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         &self,
         impl_candidates: Vec<ImplCandidate<'tcx>>,
         trait_ref: ty::PolyTraitRef<'tcx>,
-        body_id: hir::HirId,
+        body_def_id: LocalDefId,
         err: &mut Diagnostic,
         other: bool,
     ) -> bool {
@@ -2120,9 +2097,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         // FIXME(compiler-errors): This could be generalized, both to
                         // be more granular, and probably look past other `#[fundamental]`
                         // types, too.
-                        self.tcx
-                            .visibility(def.did())
-                            .is_accessible_from(body_id.owner.def_id, self.tcx)
+                        self.tcx.visibility(def.did()).is_accessible_from(body_def_id, self.tcx)
                     } else {
                         true
                     }
@@ -2231,11 +2206,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     }
 
     #[instrument(skip(self), level = "debug")]
-    fn maybe_report_ambiguity(
-        &self,
-        obligation: &PredicateObligation<'tcx>,
-        body_id: Option<hir::BodyId>,
-    ) {
+    fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) {
         // Unable to successfully determine, probably means
         // insufficient type information, but could mean
         // ambiguous impls. The latter *ought* to be a
@@ -2277,7 +2248,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 if self.tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) {
                     if let None = self.tainted_by_errors() {
                         self.emit_inference_failure_err(
-                            body_id,
+                            obligation.cause.body_id,
                             span,
                             trait_ref.self_ty().skip_binder().into(),
                             ErrorCode::E0282,
@@ -2304,7 +2275,13 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 let subst = data.trait_ref.substs.iter().find(|s| s.has_non_region_infer());
 
                 let mut err = if let Some(subst) = subst {
-                    self.emit_inference_failure_err(body_id, span, subst, ErrorCode::E0283, true)
+                    self.emit_inference_failure_err(
+                        obligation.cause.body_id,
+                        span,
+                        subst,
+                        ErrorCode::E0283,
+                        true,
+                    )
                 } else {
                     struct_span_err!(
                         self.tcx.sess,
@@ -2348,12 +2325,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                 predicate.to_opt_poly_trait_pred().unwrap(),
                             );
                             if impl_candidates.len() < 10 {
-                                let hir =
-                                    self.tcx.hir().local_def_id_to_hir_id(obligation.cause.body_id);
                                 self.report_similar_impl_candidates(
                                     impl_candidates,
                                     trait_ref,
-                                    body_id.map(|id| id.hir_id).unwrap_or(hir),
+                                    obligation.cause.body_id,
                                     &mut err,
                                     false,
                                 );
@@ -2375,9 +2350,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     self.suggest_fully_qualified_path(&mut err, def_id, span, trait_ref.def_id());
                 }
 
-                if let (Some(body_id), Some(ty::subst::GenericArgKind::Type(_))) =
-                    (body_id, subst.map(|subst| subst.unpack()))
+                if let Some(ty::subst::GenericArgKind::Type(_)) = subst.map(|subst| subst.unpack())
                 {
+                    let body_id = self.tcx.hir().body_owned_by(obligation.cause.body_id);
                     let mut expr_finder = FindExprBySpan::new(span);
                     expr_finder.visit_expr(&self.tcx.hir().body(body_id).value);
 
@@ -2473,7 +2448,13 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     return;
                 }
 
-                self.emit_inference_failure_err(body_id, span, arg, ErrorCode::E0282, false)
+                self.emit_inference_failure_err(
+                    obligation.cause.body_id,
+                    span,
+                    arg,
+                    ErrorCode::E0282,
+                    false,
+                )
             }
 
             ty::PredicateKind::Subtype(data) => {
@@ -2487,7 +2468,13 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 let SubtypePredicate { a_is_expected: _, a, b } = data;
                 // both must be type variables, or the other would've been instantiated
                 assert!(a.is_ty_var() && b.is_ty_var());
-                self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282, true)
+                self.emit_inference_failure_err(
+                    obligation.cause.body_id,
+                    span,
+                    a.into(),
+                    ErrorCode::E0282,
+                    true,
+                )
             }
             ty::PredicateKind::Clause(ty::Clause::Projection(data)) => {
                 if predicate.references_error() || self.tainted_by_errors().is_some() {
@@ -2501,7 +2488,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     .find(|g| g.has_non_region_infer());
                 if let Some(subst) = subst {
                     let mut err = self.emit_inference_failure_err(
-                        body_id,
+                        obligation.cause.body_id,
                         span,
                         subst,
                         ErrorCode::E0284,
@@ -2530,7 +2517,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 let subst = data.walk().find(|g| g.is_non_region_infer());
                 if let Some(subst) = subst {
                     let err = self.emit_inference_failure_err(
-                        body_id,
+                        obligation.cause.body_id,
                         span,
                         subst,
                         ErrorCode::E0284,
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 62bad5b49b4..bfeda88a6d4 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -210,7 +210,7 @@ fn do_normalize_predicates<'tcx>(
     let predicates = match fully_normalize(&infcx, cause, elaborated_env, predicates) {
         Ok(predicates) => predicates,
         Err(errors) => {
-            let reported = infcx.err_ctxt().report_fulfillment_errors(&errors, None);
+            let reported = infcx.err_ctxt().report_fulfillment_errors(&errors);
             return Err(reported);
         }
     };
diff --git a/library/core/src/convert/num.rs b/library/core/src/convert/num.rs
index 4da7c323492..a74a56bc5b2 100644
--- a/library/core/src/convert/num.rs
+++ b/library/core/src/convert/num.rs
@@ -172,7 +172,18 @@ impl_from! { f32, f64, #[stable(feature = "lossless_float_conv", since = "1.6.0"
 #[stable(feature = "float_from_bool", since = "1.68.0")]
 #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
 impl const From<bool> for f32 {
-    /// Converts `bool` to `f32` losslessly.
+    /// Converts `bool` to `f32` losslessly. The resulting value is positive
+    /// `0.0` for `false` and `1.0` for `true` values.
+    ///
+    /// # Examples
+    /// ```
+    /// let x: f32 = false.into();
+    /// assert_eq!(x, 0.0);
+    /// assert!(x.is_sign_positive());
+    ///
+    /// let y: f32 = true.into();
+    /// assert_eq!(y, 1.0);
+    /// ```
     #[inline]
     fn from(small: bool) -> Self {
         small as u8 as Self
@@ -181,7 +192,18 @@ impl const From<bool> for f32 {
 #[stable(feature = "float_from_bool", since = "1.68.0")]
 #[rustc_const_unstable(feature = "const_num_from_num", issue = "87852")]
 impl const From<bool> for f64 {
-    /// Converts `bool` to `f64` losslessly.
+    /// Converts `bool` to `f64` losslessly. The resulting value is positive
+    /// `0.0` for `false` and `1.0` for `true` values.
+    ///
+    /// # Examples
+    /// ```
+    /// let x: f64 = false.into();
+    /// assert_eq!(x, 0.0);
+    /// assert!(x.is_sign_positive());
+    ///
+    /// let y: f64 = true.into();
+    /// assert_eq!(y, 1.0);
+    /// ```
     #[inline]
     fn from(small: bool) -> Self {
         small as u8 as Self
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 1ad9af1549a..f41be46abc9 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -691,7 +691,7 @@ where
 #[inline(always)]
 #[must_use]
 #[unstable(feature = "ptr_from_ref", issue = "106116")]
-pub fn from_ref<T: ?Sized>(r: &T) -> *const T {
+pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
     r
 }
 
@@ -702,7 +702,7 @@ pub fn from_ref<T: ?Sized>(r: &T) -> *const T {
 #[inline(always)]
 #[must_use]
 #[unstable(feature = "ptr_from_ref", issue = "106116")]
-pub fn from_mut<T: ?Sized>(r: &mut T) -> *mut T {
+pub const fn from_mut<T: ?Sized>(r: &mut T) -> *mut T {
     r
 }
 
diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs
index 5cb94c2f1d6..b79969663ca 100644
--- a/src/bootstrap/format.rs
+++ b/src/bootstrap/format.rs
@@ -165,8 +165,14 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
             if !CiEnv::is_ci() && paths.is_empty() {
                 match get_modified_rs_files(build) {
                     Ok(Some(files)) => {
+                        if files.len() <= 10 {
+                            for file in &files {
+                                println!("formatting modified file {file}");
+                            }
+                        } else {
+                            println!("formatting {} modified files", files.len());
+                        }
                         for file in files {
-                            println!("formatting modified file {file}");
                             ignore_fmt.add(&format!("/{file}")).expect(&file);
                         }
                     }
diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs
index 909e7d83a15..7f6d80c91ad 100644
--- a/src/bootstrap/native.rs
+++ b/src/bootstrap/native.rs
@@ -216,7 +216,7 @@ pub(crate) fn is_ci_llvm_available(config: &Config, asserts: bool) -> bool {
 
 /// Returns true if we're running in CI with modified LLVM (and thus can't download it)
 pub(crate) fn is_ci_llvm_modified(config: &Config) -> bool {
-    CiEnv::is_ci() && {
+    CiEnv::is_ci() && config.rust_info.is_managed_git_subrepository() && {
         // We assume we have access to git, so it's okay to unconditionally pass
         // `true` here.
         let llvm_sha = detect_llvm_sha(config, true);
diff --git a/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh b/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh
index cf784a66ae4..3939b4b7c41 100755
--- a/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh
+++ b/src/ci/docker/host-x86_64/dist-various-2/build-solaris-toolchain.sh
@@ -32,24 +32,22 @@ cd solaris
 
 dpkg --add-architecture $APT_ARCH
 apt-get update
-apt-get download $(apt-cache depends --recurse --no-replaces \
+apt-get install -y --download-only                           \
   libc:$APT_ARCH                                             \
-  liblgrp-dev:$APT_ARCH                                      \
   liblgrp:$APT_ARCH                                          \
   libm-dev:$APT_ARCH                                         \
   libpthread:$APT_ARCH                                       \
   libresolv:$APT_ARCH                                        \
   librt:$APT_ARCH                                            \
-  libsendfile-dev:$APT_ARCH                                  \
   libsendfile:$APT_ARCH                                      \
   libsocket:$APT_ARCH                                        \
   system-crt:$APT_ARCH                                       \
-  system-header:$APT_ARCH                                    \
-  | grep "^\w")
+  system-header:$APT_ARCH
 
-for deb in *$APT_ARCH.deb; do
+for deb in /var/cache/apt/archives/*$APT_ARCH.deb; do
   dpkg -x $deb .
 done
+apt-get clean
 
 # The -dev packages are not available from the apt repository we're using.
 # However, those packages are just symlinks from *.so to *.so.<version>.
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index bbd9f18973a..29c3afe0d95 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2065,23 +2065,81 @@ fn clean_bare_fn_ty<'tcx>(
     BareFunctionDecl { unsafety: bare_fn.unsafety, abi: bare_fn.abi, decl, generic_params }
 }
 
-/// This visitor is used to go through only the "top level" of a item and not enter any sub
-/// item while looking for a given `Ident` which is stored into `item` if found.
-struct OneLevelVisitor<'hir> {
+/// Get DefId of of an item's user-visible parent.
+///
+/// "User-visible" should account for re-exporting and inlining, which is why this function isn't
+/// just `tcx.parent(def_id)`. If the provided `path` has more than one path element, the `DefId`
+/// of the second-to-last will be given.
+///
+/// ```text
+/// use crate::foo::Bar;
+///            ^^^ DefId of this item will be returned
+/// ```
+///
+/// If the provided path has only one item, `tcx.parent(def_id)` will be returned instead.
+fn get_path_parent_def_id(
+    tcx: TyCtxt<'_>,
+    def_id: DefId,
+    path: &hir::UsePath<'_>,
+) -> Option<DefId> {
+    if let [.., parent_segment, _] = &path.segments {
+        match parent_segment.res {
+            hir::def::Res::Def(_, parent_def_id) => Some(parent_def_id),
+            _ if parent_segment.ident.name == kw::Crate => {
+                // In case the "parent" is the crate, it'll give `Res::Err` so we need to
+                // circumvent it this way.
+                Some(tcx.parent(def_id))
+            }
+            _ => None,
+        }
+    } else {
+        // If the path doesn't have a parent, then the parent is the current module.
+        Some(tcx.parent(def_id))
+    }
+}
+
+/// This visitor is used to find an HIR Item based on its `use` path. This doesn't use the ordinary
+/// name resolver because it does not walk all the way through a chain of re-exports.
+pub(crate) struct OneLevelVisitor<'hir> {
     map: rustc_middle::hir::map::Map<'hir>,
-    item: Option<&'hir hir::Item<'hir>>,
+    pub(crate) item: Option<&'hir hir::Item<'hir>>,
     looking_for: Ident,
     target_def_id: LocalDefId,
 }
 
 impl<'hir> OneLevelVisitor<'hir> {
-    fn new(map: rustc_middle::hir::map::Map<'hir>, target_def_id: LocalDefId) -> Self {
+    pub(crate) fn new(map: rustc_middle::hir::map::Map<'hir>, target_def_id: LocalDefId) -> Self {
         Self { map, item: None, looking_for: Ident::empty(), target_def_id }
     }
 
-    fn reset(&mut self, looking_for: Ident) {
-        self.looking_for = looking_for;
+    pub(crate) fn find_target(
+        &mut self,
+        tcx: TyCtxt<'_>,
+        def_id: DefId,
+        path: &hir::UsePath<'_>,
+    ) -> Option<&'hir hir::Item<'hir>> {
+        let parent_def_id = get_path_parent_def_id(tcx, def_id, path)?;
+        let parent = self.map.get_if_local(parent_def_id)?;
+
+        // We get the `Ident` we will be looking for into `item`.
+        self.looking_for = path.segments[path.segments.len() - 1].ident;
+        // We reset the `item`.
         self.item = None;
+
+        match parent {
+            hir::Node::Item(parent_item) => {
+                hir::intravisit::walk_item(self, parent_item);
+            }
+            hir::Node::Crate(m) => {
+                hir::intravisit::walk_mod(
+                    self,
+                    m,
+                    tcx.local_def_id_to_hir_id(parent_def_id.as_local().unwrap()),
+                );
+            }
+            _ => return None,
+        }
+        self.item
     }
 }
 
@@ -2129,41 +2187,7 @@ fn get_all_import_attributes<'hir>(
             add_without_unwanted_attributes(attributes, hir_map.attrs(item.hir_id()), is_inline);
         }
 
-        let def_id = if let [.., parent_segment, _] = &path.segments {
-            match parent_segment.res {
-                hir::def::Res::Def(_, def_id) => def_id,
-                _ if parent_segment.ident.name == kw::Crate => {
-                    // In case the "parent" is the crate, it'll give `Res::Err` so we need to
-                    // circumvent it this way.
-                    tcx.parent(item.owner_id.def_id.to_def_id())
-                }
-                _ => break,
-            }
-        } else {
-            // If the path doesn't have a parent, then the parent is the current module.
-            tcx.parent(item.owner_id.def_id.to_def_id())
-        };
-
-        let Some(parent) = hir_map.get_if_local(def_id) else { break };
-
-        // We get the `Ident` we will be looking for into `item`.
-        let looking_for = path.segments[path.segments.len() - 1].ident;
-        visitor.reset(looking_for);
-
-        match parent {
-            hir::Node::Item(parent_item) => {
-                hir::intravisit::walk_item(&mut visitor, parent_item);
-            }
-            hir::Node::Crate(m) => {
-                hir::intravisit::walk_mod(
-                    &mut visitor,
-                    m,
-                    tcx.local_def_id_to_hir_id(def_id.as_local().unwrap()),
-                );
-            }
-            _ => break,
-        }
-        if let Some(i) = visitor.item {
+        if let Some(i) = visitor.find_target(tcx, item.owner_id.def_id.to_def_id(), path) {
             item = i;
         } else {
             break;
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 1030fe74747..ed1eb66b97c 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -647,11 +647,35 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
                      </noscript>\
                      <link rel=\"stylesheet\" \
                          href=\"{static_root_path}{settings_css}\">\
-                     <script defer src=\"{static_root_path}{settings_js}\"></script>",
+                     <script defer src=\"{static_root_path}{settings_js}\"></script>\
+                     <link rel=\"preload\" href=\"{static_root_path}{theme_light_css}\" \
+                         as=\"style\">\
+                     <link rel=\"preload\" href=\"{static_root_path}{theme_dark_css}\" \
+                         as=\"style\">\
+                     <link rel=\"preload\" href=\"{static_root_path}{theme_ayu_css}\" \
+                         as=\"style\">",
                     static_root_path = page.get_static_root_path(),
                     settings_css = static_files::STATIC_FILES.settings_css,
                     settings_js = static_files::STATIC_FILES.settings_js,
-                )
+                    theme_light_css = static_files::STATIC_FILES.theme_light_css,
+                    theme_dark_css = static_files::STATIC_FILES.theme_dark_css,
+                    theme_ayu_css = static_files::STATIC_FILES.theme_ayu_css,
+                );
+                // Pre-load all theme CSS files, so that switching feels seamless.
+                //
+                // When loading settings.html as a popover, the equivalent HTML is
+                // generated in main.js.
+                for file in &shared.style_files {
+                    if let Ok(theme) = file.basename() {
+                        write!(
+                            buf,
+                            "<link rel=\"preload\" href=\"{root_path}{theme}{suffix}.css\" \
+                                as=\"style\">",
+                            root_path = page.static_root_path.unwrap_or(""),
+                            suffix = page.resource_suffix,
+                        );
+                    }
+                }
             },
             &shared.style_files,
         );
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index 4514894cabe..eb9262f472b 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -29,12 +29,12 @@ pub(crate) enum LinkFromSrc {
 
 /// This function will do at most two things:
 ///
-/// 1. Generate a `span` correspondance map which links an item `span` to its definition `span`.
+/// 1. Generate a `span` correspondence map which links an item `span` to its definition `span`.
 /// 2. Collect the source code files.
 ///
-/// It returns the `krate`, the source code files and the `span` correspondance map.
+/// It returns the `krate`, the source code files and the `span` correspondence map.
 ///
-/// Note about the `span` correspondance map: the keys are actually `(lo, hi)` of `span`s. We don't
+/// Note about the `span` correspondence map: the keys are actually `(lo, hi)` of `span`s. We don't
 /// need the `span` context later on, only their position, so instead of keep a whole `Span`, we
 /// only keep the `lo` and `hi`.
 pub(crate) fn collect_spans_and_sources(
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 5e8c0e8d10c..403b5004d65 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -1,20 +1,9 @@
 // Local js definitions:
 /* global addClass, getSettingValue, hasClass, searchState */
-/* global onEach, onEachLazy, removeClass */
+/* global onEach, onEachLazy, removeClass, getVar */
 
 "use strict";
 
-// Get a value from the rustdoc-vars div, which is used to convey data from
-// Rust to the JS. If there is no such element, return null.
-function getVar(name) {
-    const el = document.getElementById("rustdoc-vars");
-    if (el) {
-        return el.attributes["data-" + name].value;
-    } else {
-        return null;
-    }
-}
-
 // Given a basename (e.g. "storage") and an extension (e.g. ".js"), return a URL
 // for a resource under the root-path, with the resource-suffix.
 function resourcePath(basename, extension) {
@@ -187,6 +176,15 @@ function loadCss(cssUrl) {
     document.getElementsByTagName("head")[0].appendChild(link);
 }
 
+function preLoadCss(cssUrl) {
+    // https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload
+    const link = document.createElement("link");
+    link.href = cssUrl;
+    link.rel = "preload";
+    link.as = "style";
+    document.getElementsByTagName("head")[0].appendChild(link);
+}
+
 (function() {
     const isHelpPage = window.location.pathname.endsWith("/help.html");
 
@@ -207,6 +205,23 @@ function loadCss(cssUrl) {
         // hopefully be loaded when the JS will generate the settings content.
         loadCss(getVar("static-root-path") + getVar("settings-css"));
         loadScript(getVar("static-root-path") + getVar("settings-js"));
+        preLoadCss(getVar("static-root-path") + getVar("theme-light-css"));
+        preLoadCss(getVar("static-root-path") + getVar("theme-dark-css"));
+        preLoadCss(getVar("static-root-path") + getVar("theme-ayu-css"));
+        // Pre-load all theme CSS files, so that switching feels seamless.
+        //
+        // When loading settings.html as a standalone page, the equivalent HTML is
+        // generated in context.rs.
+        setTimeout(() => {
+            const themes = getVar("themes").split(",");
+            for (const theme of themes) {
+                // if there are no themes, do nothing
+                // "".split(",") == [""]
+                if (theme !== "") {
+                    preLoadCss(getVar("root-path") + theme + ".css");
+                }
+            }
+        }, 0);
     };
 
     window.searchState = {
diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js
index c72ac254fc0..c3fed9a72d4 100644
--- a/src/librustdoc/html/static/js/storage.js
+++ b/src/librustdoc/html/static/js/storage.js
@@ -7,7 +7,6 @@
 
 const darkThemes = ["dark", "ayu"];
 window.currentTheme = document.getElementById("themeStyle");
-window.mainTheme = document.getElementById("mainThemeStyle");
 
 // WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY
 // If you update this line, then you also need to update the media query with the same
@@ -44,8 +43,6 @@ function getSettingValue(settingName) {
 
 const localStoredTheme = getSettingValue("theme");
 
-const savedHref = [];
-
 // eslint-disable-next-line no-unused-vars
 function hasClass(elem, className) {
     return elem && elem.classList && elem.classList.contains(className);
@@ -102,6 +99,7 @@ function onEach(arr, func, reversed) {
  * @param {function(?)}                   func       - The callback
  * @param {boolean}                       [reversed] - Whether to iterate in reverse
  */
+// eslint-disable-next-line no-unused-vars
 function onEachLazy(lazyArray, func, reversed) {
     return onEach(
         Array.prototype.slice.call(lazyArray),
@@ -125,30 +123,37 @@ function getCurrentValue(name) {
     }
 }
 
-function switchTheme(styleElem, mainStyleElem, newThemeName, saveTheme) {
+// Get a value from the rustdoc-vars div, which is used to convey data from
+// Rust to the JS. If there is no such element, return null.
+const getVar = (function getVar(name) {
+    const el = document.getElementById("rustdoc-vars");
+    if (el) {
+        return el.attributes["data-" + name].value;
+    } else {
+        return null;
+    }
+});
+
+function switchTheme(newThemeName, saveTheme) {
     // If this new value comes from a system setting or from the previously
     // saved theme, no need to save it.
     if (saveTheme) {
         updateLocalStorage("theme", newThemeName);
     }
 
-    if (savedHref.length === 0) {
-        onEachLazy(document.getElementsByTagName("link"), el => {
-            savedHref.push(el.href);
-        });
+    let newHref;
+
+    if (newThemeName === "light" || newThemeName === "dark" || newThemeName === "ayu") {
+        newHref = getVar("static-root-path") + getVar("theme-" + newThemeName + "-css");
+    } else {
+        newHref = getVar("root-path") + newThemeName + getVar("resource-suffix") + ".css";
     }
-    const newHref = savedHref.find(url => {
-        const m = url.match(/static\.files\/(.*)-[a-f0-9]{16}\.css$/);
-        if (m && m[1] === newThemeName) {
-            return true;
-        }
-        const m2 = url.match(/\/([^/]*)\.css$/);
-        if (m2 && m2[1].startsWith(newThemeName)) {
-            return true;
-        }
-    });
-    if (newHref && newHref !== styleElem.href) {
-        styleElem.href = newHref;
+
+    if (!window.currentTheme) {
+        document.write(`<link rel="stylesheet" id="themeStyle" href="${newHref}">`);
+        window.currentTheme = document.getElementById("themeStyle");
+    } else if (newHref !== window.currentTheme.href) {
+        window.currentTheme.href = newHref;
     }
 }
 
@@ -164,7 +169,7 @@ const updateTheme = (function() {
      */
     function updateTheme() {
         const use = (theme, saveTheme) => {
-            switchTheme(window.currentTheme, window.mainTheme, theme, saveTheme);
+            switchTheme(theme, saveTheme);
         };
 
         // maybe the user has disabled the setting in the meantime!
diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html
index e896850fab6..532660e3d33 100644
--- a/src/librustdoc/html/templates/page.html
+++ b/src/librustdoc/html/templates/page.html
@@ -17,12 +17,6 @@
     <link rel="stylesheet" {#+ #}
           href="{{static_root_path|safe}}{{files.rustdoc_css}}" {#+ #}
           id="mainThemeStyle"> {# #}
-    <link rel="stylesheet" id="themeStyle" href="{{static_root_path|safe}}{{files.theme_light_css}}"> {# #}
-    <link rel="stylesheet" disabled href="{{static_root_path|safe}}{{files.theme_dark_css}}"> {# #}
-    <link rel="stylesheet" disabled href="{{static_root_path|safe}}{{files.theme_ayu_css}}"> {# #}
-    {% for theme in themes %}
-        <link rel="stylesheet" disabled href="{{page.root_path|safe}}{{theme}}{{page.resource_suffix}}.css"> {# #}
-    {% endfor %}
     {% if !layout.default_settings.is_empty() %}
     <script id="default-settings" {#+ #}
       {%~ for (k, v) in layout.default_settings ~%}
@@ -30,6 +24,21 @@
       {% endfor %}
     ></script> {# #}
     {% endif %}
+    <div id="rustdoc-vars" {#+ #}
+         data-root-path="{{page.root_path|safe}}" {#+ #}
+         data-static-root-path="{{static_root_path|safe}}" {#+ #}
+         data-current-crate="{{layout.krate}}" {#+ #}
+         data-themes="{{themes|join(",") }}" {#+ #}
+         data-resource-suffix="{{page.resource_suffix}}" {#+ #}
+         data-rustdoc-version="{{rustdoc_version}}" {#+ #}
+         data-search-js="{{files.search_js}}" {#+ #}
+         data-settings-js="{{files.settings_js}}" {#+ #}
+         data-settings-css="{{files.settings_css}}" {#+ #}
+         data-theme-light-css="{{files.theme_light_css}}" {#+ #}
+         data-theme-dark-css="{{files.theme_dark_css}}" {#+ #}
+         data-theme-ayu-css="{{files.theme_ayu_css}}" {#+ #}
+    > {# #}
+    </div> {# #}
     <script src="{{static_root_path|safe}}{{files.storage_js}}"></script> {# #}
     {% if page.css_class.contains("crate") %}
     <script defer src="{{page.root_path|safe}}crates{{page.resource_suffix}}.js"></script> {# #}
@@ -45,6 +54,12 @@
     {% endif %}
     <noscript> {# #}
         <link rel="stylesheet" {#+ #}
+           media="(prefers-color-scheme:light)" {#+ #}
+           href="{{static_root_path|safe}}{{files.theme_light_css}}"> {# #}
+        <link rel="stylesheet" {#+ #}
+           media="(prefers-color-scheme:dark)" {#+ #}
+           href="{{static_root_path|safe}}{{files.theme_dark_css}}"> {# #}
+        <link rel="stylesheet" {#+ #}
            href="{{static_root_path|safe}}{{files.noscript_css}}"> {# #}
     </noscript> {# #}
     {% if layout.css_file_extension.is_some() %}
@@ -132,17 +147,5 @@
         {% if page.css_class != "source" %}</div>{% endif %}
     </main> {# #}
     {{ layout.external_html.after_content|safe }}
-    <div id="rustdoc-vars" {#+ #}
-         data-root-path="{{page.root_path|safe}}" {#+ #}
-         data-static-root-path="{{static_root_path|safe}}" {#+ #}
-         data-current-crate="{{layout.krate}}" {#+ #}
-         data-themes="{{themes|join(",") }}" {#+ #}
-         data-resource-suffix="{{page.resource_suffix}}" {#+ #}
-         data-rustdoc-version="{{rustdoc_version}}" {#+ #}
-         data-search-js="{{files.search_js}}" {#+ #}
-         data-settings-js="{{files.settings_js}}" {#+ #}
-         data-settings-css="{{files.settings_css}}" {#+ #}
-    > {# #}
-    </div> {# #}
 </body> {# #}
 </html> {# #}
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 5bbbff175cf..e09a68069e8 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -15,7 +15,7 @@ use rustc_span::Span;
 
 use std::mem;
 
-use crate::clean::{cfg::Cfg, AttributesExt, NestedAttributesExt};
+use crate::clean::{cfg::Cfg, AttributesExt, NestedAttributesExt, OneLevelVisitor};
 use crate::core;
 
 /// This module is used to store stuff from Rust's AST in a more convenient
@@ -220,9 +220,15 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         renamed: Option<Symbol>,
         glob: bool,
         please_inline: bool,
+        path: &hir::UsePath<'_>,
     ) -> bool {
         debug!("maybe_inline_local res: {:?}", res);
 
+        if renamed == Some(kw::Underscore) {
+            // We never inline `_` reexports.
+            return false;
+        }
+
         if self.cx.output_format.is_json() {
             return false;
         }
@@ -263,6 +269,22 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             return false;
         }
 
+        if !please_inline &&
+            let mut visitor = OneLevelVisitor::new(self.cx.tcx.hir(), res_did) &&
+            let Some(item) = visitor.find_target(self.cx.tcx, def_id.to_def_id(), path) &&
+            let item_def_id = item.owner_id.def_id &&
+            item_def_id != def_id &&
+            self
+                .cx
+                .cache
+                .effective_visibilities
+                .is_directly_public(self.cx.tcx, item_def_id.to_def_id()) &&
+            !inherits_doc_hidden(self.cx.tcx, item_def_id)
+        {
+            // The imported item is public and not `doc(hidden)` so no need to inline it.
+            return false;
+        }
+
         let ret = match tcx.hir().get_by_def_id(res_did) {
             Node::Item(&hir::Item { kind: hir::ItemKind::Mod(ref m), .. }) if glob => {
                 let prev = mem::replace(&mut self.inlining, true);
@@ -329,8 +351,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                     self.visit_foreign_item_inner(item, None);
                 }
             }
-            // If we're inlining, skip private items or item reexported as "_".
-            _ if self.inlining && (!is_pub || renamed == Some(kw::Underscore)) => {}
+            // If we're inlining, skip private items.
+            _ if self.inlining && !is_pub => {}
             hir::ItemKind::GlobalAsm(..) => {}
             hir::ItemKind::Use(_, hir::UseKind::ListStem) => {}
             hir::ItemKind::Use(path, kind) => {
@@ -361,6 +383,7 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
                             ident,
                             is_glob,
                             please_inline,
+                            path,
                         ) {
                             continue;
                         }
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index 33938ac9a0a..6d6d3c89a3c 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -62,6 +62,8 @@ const EXCEPTION_PATHS: &[&str] = &[
     "library/std/src/panic.rs",   // fuchsia-specific panic backtrace handling
     "library/std/src/personality.rs",
     "library/std/src/personality/",
+    "library/std/src/thread/mod.rs",
+    "library/std/src/thread/local.rs",
 ];
 
 pub fn check(path: &Path, bad: &mut bool) {
@@ -128,6 +130,7 @@ fn check_cfgs(
             || cfg.contains("target_env")
             || cfg.contains("target_abi")
             || cfg.contains("target_vendor")
+            || cfg.contains("target_family")
             || cfg.contains("unix")
             || cfg.contains("windows");
 
diff --git a/tests/run-make-fulldeps/rustdoc-themes/foo.rs b/tests/run-make-fulldeps/rustdoc-themes/foo.rs
index 58efaf7d5a0..995544aeff9 100644
--- a/tests/run-make-fulldeps/rustdoc-themes/foo.rs
+++ b/tests/run-make-fulldeps/rustdoc-themes/foo.rs
@@ -1,4 +1,4 @@
 // @has test.css
 // @has foo/struct.Foo.html
-// @has - '//link[@rel="stylesheet"]/@href' '../test.css'
+// @has - '//*[@id="rustdoc-vars"]/@data-themes' 'test'
 pub struct Foo;
diff --git a/tests/rustdoc-gui/scrape-examples-button-focus.goml b/tests/rustdoc-gui/scrape-examples-button-focus.goml
index 1b5c3a0d202..16f0ced8c6e 100644
--- a/tests/rustdoc-gui/scrape-examples-button-focus.goml
+++ b/tests/rustdoc-gui/scrape-examples-button-focus.goml
@@ -8,24 +8,24 @@ focus: ".scraped-example-list > .scraped-example .next"
 press-key: "Enter"
 assert-property-false: (".scraped-example-list > .scraped-example pre", {
     "scrollTop": |initialScrollTop|
-})
+}, NEAR)
 focus: ".scraped-example-list > .scraped-example .prev"
 press-key: "Enter"
 assert-property: (".scraped-example-list > .scraped-example pre", {
     "scrollTop": |initialScrollTop|
-})
+}, NEAR)
 
 // The expand button increases the scrollHeight of the minimized code viewport
 store-property: (smallOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight")
 assert-property-false: (".scraped-example-list > .scraped-example pre", {
     "scrollHeight": |smallOffsetHeight|
-})
+}, NEAR)
 focus: ".scraped-example-list > .scraped-example .expand"
 press-key: "Enter"
 assert-property-false: (".scraped-example-list > .scraped-example pre", {
     "offsetHeight": |smallOffsetHeight|
-})
+}, NEAR)
 store-property: (fullOffsetHeight, ".scraped-example-list > .scraped-example pre", "offsetHeight")
 assert-property: (".scraped-example-list > .scraped-example pre", {
     "scrollHeight": |fullOffsetHeight|
-})
+}, NEAR)
diff --git a/tests/rustdoc/anonymous-reexport.rs b/tests/rustdoc/anonymous-reexport.rs
index 6b884ff14df..839c1a30346 100644
--- a/tests/rustdoc/anonymous-reexport.rs
+++ b/tests/rustdoc/anonymous-reexport.rs
@@ -4,9 +4,13 @@
 
 // @has 'foo/index.html'
 // @has - '//*[@id="main-content"]' ''
-// We check that the only "h2" present is for "Bla".
-// @count - '//*[@id="main-content"]/h2' 1
+// We check that the only "h2" present are "Structs" (for "Bla") and "Re-exports".
+// @count - '//*[@id="main-content"]/h2' 2
 // @has - '//*[@id="main-content"]/h2' 'Structs'
+// @has - '//*[@id="main-content"]/h2' 'Re-exports'
+// The 3 re-exports.
+// @count - '//*[@id="main-content"]//*[@class="item-table"]//li//code' 3
+// The public struct.
 // @count - '//*[@id="main-content"]//a[@class="struct"]' 1
 
 mod ext {
diff --git a/tests/rustdoc/issue-108679-reexport-of-reexport.rs b/tests/rustdoc/issue-108679-reexport-of-reexport.rs
new file mode 100644
index 00000000000..5f977801cfd
--- /dev/null
+++ b/tests/rustdoc/issue-108679-reexport-of-reexport.rs
@@ -0,0 +1,29 @@
+// This test ensures that the `struct.B.html` only exists in `a`:
+// since `a::B` is public (and inlined too), `self::a::B` doesn't
+// need to be inlined as well.
+
+#![crate_name = "foo"]
+
+pub mod a {
+    // @has 'foo/a/index.html'
+    // Should only contain "Structs".
+    // @count - '//*[@id="main-content"]//*[@class="item-table"]' 1
+    // @has - '//*[@id="structs"]' 'Structs'
+    // @has - '//*[@id="main-content"]//a[@href="struct.A.html"]' 'A'
+    // @has - '//*[@id="main-content"]//a[@href="struct.B.html"]' 'B'
+    mod b {
+        pub struct B;
+    }
+    pub use self::b::B;
+    pub struct A;
+}
+
+// @has 'foo/index.html'
+// @!has - '//*[@id="structs"]' 'Structs'
+// @has - '//*[@id="reexports"]' 'Re-exports'
+// @has - '//*[@id="modules"]' 'Modules'
+// @has - '//*[@id="main-content"]//*[@id="reexport.A"]' 'pub use self::a::A;'
+// @has - '//*[@id="main-content"]//*[@id="reexport.B"]' 'pub use self::a::B;'
+// Should only contain "Modules" and "Re-exports".
+// @count - '//*[@id="main-content"]//*[@class="item-table"]' 2
+pub use self::a::{A, B};
diff --git a/tests/rustdoc/issue-108931-anonymous-reexport.rs b/tests/rustdoc/issue-108931-anonymous-reexport.rs
new file mode 100644
index 00000000000..302f7413398
--- /dev/null
+++ b/tests/rustdoc/issue-108931-anonymous-reexport.rs
@@ -0,0 +1,21 @@
+// Ensuring that anonymous re-exports are always inlined.
+
+#![crate_name = "foo"]
+
+pub mod foo {
+    pub struct Foo;
+}
+
+mod bar {
+    pub struct Bar;
+}
+
+// @has 'foo/index.html'
+// We check that the only "h2" present are "Re-exports" and "Modules".
+// @count - '//*[@id="main-content"]/h2' 2
+// @has - '//*[@id="main-content"]/h2' 'Re-exports'
+// @has - '//*[@id="main-content"]/h2' 'Modules'
+// @has - '//*[@id="main-content"]//*[@class="item-table"]//li//code' 'pub use foo::Foo as _;'
+// @has - '//*[@id="main-content"]//*[@class="item-table"]//li//code' 'pub use bar::Bar as _;'
+pub use foo::Foo as _;
+pub use bar::Bar as _;
diff --git a/tests/ui/parser/integer-literal-start-ident.rs b/tests/ui/parser/integer-literal-start-ident.rs
new file mode 100644
index 00000000000..12537482e0f
--- /dev/null
+++ b/tests/ui/parser/integer-literal-start-ident.rs
@@ -0,0 +1,2 @@
+fn 1main() {}
+//~^ ERROR expected identifier, found `1main`
diff --git a/tests/ui/parser/integer-literal-start-ident.stderr b/tests/ui/parser/integer-literal-start-ident.stderr
new file mode 100644
index 00000000000..51c37a0d24c
--- /dev/null
+++ b/tests/ui/parser/integer-literal-start-ident.stderr
@@ -0,0 +1,10 @@
+error: expected identifier, found `1main`
+  --> $DIR/integer-literal-start-ident.rs:1:4
+   |
+LL | fn 1main() {}
+   |    ^^^^^ expected identifier
+   |
+   = help: identifiers cannot start with a number
+
+error: aborting due to previous error
+
diff --git a/tests/ui/parser/issues/issue-104088.rs b/tests/ui/parser/issues/issue-104088.rs
index 5f794fe2dc9..86988c8cd21 100644
--- a/tests/ui/parser/issues/issue-104088.rs
+++ b/tests/ui/parser/issues/issue-104088.rs
@@ -4,12 +4,12 @@ fn test() {
 
 fn test_2() {
     let 1x = 123;
-    //~^ ERROR expected identifier, found number literal
+    //~^ ERROR expected identifier, found `1x`
 }
 
 fn test_3() {
     let 2x: i32 = 123;
-    //~^ ERROR expected identifier, found number literal
+    //~^ ERROR expected identifier, found `2x`
 }
 
 fn test_4() {
@@ -20,7 +20,7 @@ fn test_4() {
 
 fn test_5() {
     let 23name = 123;
-    //~^ ERROR expected identifier, found number literal
+    //~^ ERROR expected identifier, found `23name`
 }
 
 fn main() {}
diff --git a/tests/ui/parser/issues/issue-104088.stderr b/tests/ui/parser/issues/issue-104088.stderr
index ff4b4bdb695..6511a313149 100644
--- a/tests/ui/parser/issues/issue-104088.stderr
+++ b/tests/ui/parser/issues/issue-104088.stderr
@@ -1,20 +1,26 @@
-error: expected identifier, found number literal
+error: expected identifier, found `1x`
   --> $DIR/issue-104088.rs:6:9
    |
 LL |     let 1x = 123;
-   |         ^^ identifiers cannot start with a number
+   |         ^^ expected identifier
+   |
+   = help: identifiers cannot start with a number
 
-error: expected identifier, found number literal
+error: expected identifier, found `2x`
   --> $DIR/issue-104088.rs:11:9
    |
 LL |     let 2x: i32 = 123;
-   |         ^^ identifiers cannot start with a number
+   |         ^^ expected identifier
+   |
+   = help: identifiers cannot start with a number
 
-error: expected identifier, found number literal
+error: expected identifier, found `23name`
   --> $DIR/issue-104088.rs:22:9
    |
 LL |     let 23name = 123;
-   |         ^^^^^^ identifiers cannot start with a number
+   |         ^^^^^^ expected identifier
+   |
+   = help: identifiers cannot start with a number
 
 error[E0308]: mismatched types
   --> $DIR/issue-104088.rs:16:12
diff --git a/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.rs b/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.rs
new file mode 100644
index 00000000000..e56c8622ece
--- /dev/null
+++ b/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.rs
@@ -0,0 +1,16 @@
+trait Foo
+where
+    for<'a> &'a Self: Bar,
+{
+}
+
+impl Foo for () {}
+
+trait Bar {}
+
+impl Bar for &() {}
+
+fn foo<T: Foo>() {}
+//~^ ERROR the trait bound `for<'a> &'a T: Bar` is not satisfied
+
+fn main() {}
diff --git a/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.stderr b/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.stderr
new file mode 100644
index 00000000000..2298e7f4e0c
--- /dev/null
+++ b/tests/ui/suggestions/correct-binder-for-arbitrary-bound-sugg.stderr
@@ -0,0 +1,22 @@
+error[E0277]: the trait bound `for<'a> &'a T: Bar` is not satisfied
+  --> $DIR/correct-binder-for-arbitrary-bound-sugg.rs:13:11
+   |
+LL | fn foo<T: Foo>() {}
+   |           ^^^ the trait `for<'a> Bar` is not implemented for `&'a T`
+   |
+note: required by a bound in `Foo`
+  --> $DIR/correct-binder-for-arbitrary-bound-sugg.rs:3:23
+   |
+LL | trait Foo
+   |       --- required by a bound in this trait
+LL | where
+LL |     for<'a> &'a Self: Bar,
+   |                       ^^^ required by this bound in `Foo`
+help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
+   |
+LL | fn foo<T: Foo>() where for<'a> &'a T: Bar {}
+   |                  ++++++++++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/triagebot.toml b/triagebot.toml
index 403a7087ee1..e39a0b06b97 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -451,6 +451,10 @@ cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"]
 message = "`rustc_macros::diagnostics` was changed"
 cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"]
 
+[mentions."compiler/rustc_smir"]
+message = "This PR changes Stable MIR"
+cc = ["@oli-obk", "@celinval"]
+
 [mentions."compiler/rustc_target/src/spec"]
 message = """
 These commits modify **compiler targets**.
@@ -497,6 +501,7 @@ compiler-team-contributors = [
     "@TaKO8Ki",
     "@Nilstrieb",
     "@WaffleLapkin",
+    "@b-naber",
 ]
 compiler = [
     "compiler-team",