diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 31b7eb5ee7df3..353345958337c 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -783,6 +783,9 @@ lint_tykind = usage of `ty::TyKind`
 lint_tykind_kind = usage of `ty::TyKind::<kind>`
     .suggestion = try using `ty::<kind>` directly
 
+lint_type_ir_inherent_usage = do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
+    .note = the method or struct you're looking for is likely defined somewhere else downstream in the compiler
+
 lint_undropped_manually_drops = calls to `std::mem::drop` with `std::mem::ManuallyDrop` instead of the inner value does nothing
     .label = argument has type `{$arg_ty}`
     .suggestion = use `std::mem::ManuallyDrop::into_inner` to get the inner value
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 65571815019ea..2e8116b8ba892 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -18,7 +18,7 @@ use tracing::debug;
 use crate::lints::{
     BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword,
     NonGlobImportTypeIrInherent, QueryInstability, SpanUseEqCtxtDiag, TyQualified, TykindDiag,
-    TykindKind, UntranslatableDiag,
+    TykindKind, TypeIrInherentUsage, UntranslatableDiag,
 };
 use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
 
@@ -277,13 +277,39 @@ declare_tool_lint! {
     report_in_external_macro: true
 }
 
-declare_lint_pass!(TypeIr => [NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT]);
+declare_tool_lint! {
+    /// The `usage_of_type_ir_inherent` lint detects usage `rustc_type_ir::inherent`.
+    ///
+    /// This module should only be used within the trait solver.
+    pub rustc::USAGE_OF_TYPE_IR_INHERENT,
+    Allow,
+    "usage `rustc_type_ir::inherent` outside of trait system",
+    report_in_external_macro: true
+}
+
+declare_lint_pass!(TypeIr => [NON_GLOB_IMPORT_OF_TYPE_IR_INHERENT, USAGE_OF_TYPE_IR_INHERENT]);
 
 impl<'tcx> LateLintPass<'tcx> for TypeIr {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
         let rustc_hir::ItemKind::Use(path, kind) = item.kind else { return };
 
         let is_mod_inherent = |def_id| cx.tcx.is_diagnostic_item(sym::type_ir_inherent, def_id);
+
+        // Path segments except for the final.
+        if let Some(seg) =
+            path.segments.iter().find(|seg| seg.res.opt_def_id().is_some_and(is_mod_inherent))
+        {
+            cx.emit_span_lint(USAGE_OF_TYPE_IR_INHERENT, seg.ident.span, TypeIrInherentUsage);
+        }
+        // Final path resolutions, like `use rustc_type_ir::inherent`
+        else if path.res.iter().any(|res| res.opt_def_id().is_some_and(is_mod_inherent)) {
+            cx.emit_span_lint(
+                USAGE_OF_TYPE_IR_INHERENT,
+                path.segments.last().unwrap().ident.span,
+                TypeIrInherentUsage,
+            );
+        }
+
         let (lo, hi, snippet) = match path.segments {
             [.., penultimate, segment]
                 if penultimate.res.opt_def_id().is_some_and(is_mod_inherent) =>
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 2712e25668a48..7ca282b7c8541 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -918,6 +918,11 @@ pub(crate) struct TyQualified {
     pub suggestion: Span,
 }
 
+#[derive(LintDiagnostic)]
+#[diag(lint_type_ir_inherent_usage)]
+#[note]
+pub(crate) struct TypeIrInherentUsage;
+
 #[derive(LintDiagnostic)]
 #[diag(lint_non_glob_import_type_ir_inherent)]
 pub(crate) struct NonGlobImportTypeIrInherent {
diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
index 61a1d8cc90240..e503119a3495b 100644
--- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
+++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
@@ -86,7 +86,7 @@ fn add_move_for_packed_drop<'tcx>(
 
     let source_info = terminator.source_info;
     let ty = place.ty(body, tcx).ty;
-    let temp = patch.new_temp(ty, terminator.source_info.span);
+    let temp = patch.new_temp(ty, source_info.span);
 
     let storage_dead_block = patch.new_block(BasicBlockData {
         statements: vec![Statement { source_info, kind: StatementKind::StorageDead(temp) }],
diff --git a/compiler/rustc_mir_transform/src/check_packed_ref.rs b/compiler/rustc_mir_transform/src/check_packed_ref.rs
index 9902002580aed..eb76a39be57ff 100644
--- a/compiler/rustc_mir_transform/src/check_packed_ref.rs
+++ b/compiler/rustc_mir_transform/src/check_packed_ref.rs
@@ -37,24 +37,17 @@ impl<'tcx> Visitor<'tcx> for PackedRefChecker<'_, 'tcx> {
     }
 
     fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) {
-        if context.is_borrow() {
-            if util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
-                let def_id = self.body.source.instance.def_id();
-                if let Some(impl_def_id) = self.tcx.impl_of_method(def_id)
-                    && self.tcx.is_builtin_derived(impl_def_id)
-                {
-                    // If we ever reach here it means that the generated derive
-                    // code is somehow doing an unaligned reference, which it
-                    // shouldn't do.
-                    span_bug!(
-                        self.source_info.span,
-                        "builtin derive created an unaligned reference"
-                    );
-                } else {
-                    self.tcx
-                        .dcx()
-                        .emit_err(errors::UnalignedPackedRef { span: self.source_info.span });
-                }
+        if context.is_borrow() && util::is_disaligned(self.tcx, self.body, self.param_env, *place) {
+            let def_id = self.body.source.instance.def_id();
+            if let Some(impl_def_id) = self.tcx.impl_of_method(def_id)
+                && self.tcx.is_builtin_derived(impl_def_id)
+            {
+                // If we ever reach here it means that the generated derive
+                // code is somehow doing an unaligned reference, which it
+                // shouldn't do.
+                span_bug!(self.source_info.span, "builtin derive created an unaligned reference");
+            } else {
+                self.tcx.dcx().emit_err(errors::UnalignedPackedRef { span: self.source_info.span });
             }
         }
     }
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index 8051fca9e7c9d..80ba1c4266811 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -63,7 +63,9 @@ use rustc_index::bit_set::{BitMatrix, BitSet, GrowableBitSet};
 use rustc_index::{Idx, IndexVec};
 use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
 use rustc_middle::mir::*;
-use rustc_middle::ty::{self, CoroutineArgs, CoroutineArgsExt, InstanceKind, Ty, TyCtxt};
+use rustc_middle::ty::{
+    self, CoroutineArgs, CoroutineArgsExt, GenericArgsRef, InstanceKind, Ty, TyCtxt,
+};
 use rustc_middle::{bug, span_bug};
 use rustc_mir_dataflow::impls::{
     MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive,
@@ -113,47 +115,18 @@ impl<'tcx> MutVisitor<'tcx> for RenameLocalVisitor<'tcx> {
     }
 }
 
-struct DerefArgVisitor<'tcx> {
+struct SelfArgVisitor<'tcx> {
     tcx: TyCtxt<'tcx>,
+    new_base: Place<'tcx>,
 }
 
-impl<'tcx> MutVisitor<'tcx> for DerefArgVisitor<'tcx> {
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.tcx
-    }
-
-    fn visit_local(&mut self, local: &mut Local, _: PlaceContext, _: Location) {
-        assert_ne!(*local, SELF_ARG);
-    }
-
-    fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
-        if place.local == SELF_ARG {
-            replace_base(
-                place,
-                Place {
-                    local: SELF_ARG,
-                    projection: self.tcx().mk_place_elems(&[ProjectionElem::Deref]),
-                },
-                self.tcx,
-            );
-        } else {
-            self.visit_local(&mut place.local, context, location);
-
-            for elem in place.projection.iter() {
-                if let PlaceElem::Index(local) = elem {
-                    assert_ne!(local, SELF_ARG);
-                }
-            }
-        }
+impl<'tcx> SelfArgVisitor<'tcx> {
+    fn new(tcx: TyCtxt<'tcx>, elem: ProjectionElem<Local, Ty<'tcx>>) -> Self {
+        Self { tcx, new_base: Place { local: SELF_ARG, projection: tcx.mk_place_elems(&[elem]) } }
     }
 }
 
-struct PinArgVisitor<'tcx> {
-    ref_coroutine_ty: Ty<'tcx>,
-    tcx: TyCtxt<'tcx>,
-}
-
-impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
+impl<'tcx> MutVisitor<'tcx> for SelfArgVisitor<'tcx> {
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
@@ -164,17 +137,7 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
 
     fn visit_place(&mut self, place: &mut Place<'tcx>, context: PlaceContext, location: Location) {
         if place.local == SELF_ARG {
-            replace_base(
-                place,
-                Place {
-                    local: SELF_ARG,
-                    projection: self.tcx().mk_place_elems(&[ProjectionElem::Field(
-                        FieldIdx::ZERO,
-                        self.ref_coroutine_ty,
-                    )]),
-                },
-                self.tcx,
-            );
+            replace_base(place, self.new_base, self.tcx);
         } else {
             self.visit_local(&mut place.local, context, location);
 
@@ -198,15 +161,6 @@ fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtx
 
 const SELF_ARG: Local = Local::from_u32(1);
 
-/// Coroutine has not been resumed yet.
-const UNRESUMED: usize = CoroutineArgs::UNRESUMED;
-/// Coroutine has returned / is completed.
-const RETURNED: usize = CoroutineArgs::RETURNED;
-/// Coroutine has panicked and is poisoned.
-const POISONED: usize = CoroutineArgs::POISONED;
-/// Number of reserved variants of coroutine state.
-const RESERVED_VARIANTS: usize = CoroutineArgs::RESERVED_VARIANTS;
-
 /// A `yield` point in the coroutine.
 struct SuspensionPoint<'tcx> {
     /// State discriminant used when suspending or resuming at this point.
@@ -261,14 +215,10 @@ impl<'tcx> TransformVisitor<'tcx> {
             // `gen` continues return `None`
             CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
                 let option_def_id = self.tcx.require_lang_item(LangItem::Option, None);
-                Rvalue::Aggregate(
-                    Box::new(AggregateKind::Adt(
-                        option_def_id,
-                        VariantIdx::ZERO,
-                        self.tcx.mk_args(&[self.old_yield_ty.into()]),
-                        None,
-                        None,
-                    )),
+                make_aggregate_adt(
+                    option_def_id,
+                    VariantIdx::ZERO,
+                    self.tcx.mk_args(&[self.old_yield_ty.into()]),
                     IndexVec::new(),
                 )
             }
@@ -317,64 +267,28 @@ impl<'tcx> TransformVisitor<'tcx> {
         is_return: bool,
         statements: &mut Vec<Statement<'tcx>>,
     ) {
+        const ZERO: VariantIdx = VariantIdx::ZERO;
+        const ONE: VariantIdx = VariantIdx::from_usize(1);
         let rvalue = match self.coroutine_kind {
             CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => {
                 let poll_def_id = self.tcx.require_lang_item(LangItem::Poll, None);
                 let args = self.tcx.mk_args(&[self.old_ret_ty.into()]);
-                if is_return {
-                    // Poll::Ready(val)
-                    Rvalue::Aggregate(
-                        Box::new(AggregateKind::Adt(
-                            poll_def_id,
-                            VariantIdx::ZERO,
-                            args,
-                            None,
-                            None,
-                        )),
-                        IndexVec::from_raw(vec![val]),
-                    )
+                let (variant_idx, operands) = if is_return {
+                    (ZERO, IndexVec::from_raw(vec![val])) // Poll::Ready(val)
                 } else {
-                    // Poll::Pending
-                    Rvalue::Aggregate(
-                        Box::new(AggregateKind::Adt(
-                            poll_def_id,
-                            VariantIdx::from_usize(1),
-                            args,
-                            None,
-                            None,
-                        )),
-                        IndexVec::new(),
-                    )
-                }
+                    (ONE, IndexVec::new()) // Poll::Pending
+                };
+                make_aggregate_adt(poll_def_id, variant_idx, args, operands)
             }
             CoroutineKind::Desugared(CoroutineDesugaring::Gen, _) => {
                 let option_def_id = self.tcx.require_lang_item(LangItem::Option, None);
                 let args = self.tcx.mk_args(&[self.old_yield_ty.into()]);
-                if is_return {
-                    // None
-                    Rvalue::Aggregate(
-                        Box::new(AggregateKind::Adt(
-                            option_def_id,
-                            VariantIdx::ZERO,
-                            args,
-                            None,
-                            None,
-                        )),
-                        IndexVec::new(),
-                    )
+                let (variant_idx, operands) = if is_return {
+                    (ZERO, IndexVec::new()) // None
                 } else {
-                    // Some(val)
-                    Rvalue::Aggregate(
-                        Box::new(AggregateKind::Adt(
-                            option_def_id,
-                            VariantIdx::from_usize(1),
-                            args,
-                            None,
-                            None,
-                        )),
-                        IndexVec::from_raw(vec![val]),
-                    )
-                }
+                    (ONE, IndexVec::from_raw(vec![val])) // Some(val)
+                };
+                make_aggregate_adt(option_def_id, variant_idx, args, operands)
             }
             CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, _) => {
                 if is_return {
@@ -400,31 +314,17 @@ impl<'tcx> TransformVisitor<'tcx> {
                 let coroutine_state_def_id =
                     self.tcx.require_lang_item(LangItem::CoroutineState, None);
                 let args = self.tcx.mk_args(&[self.old_yield_ty.into(), self.old_ret_ty.into()]);
-                if is_return {
-                    // CoroutineState::Complete(val)
-                    Rvalue::Aggregate(
-                        Box::new(AggregateKind::Adt(
-                            coroutine_state_def_id,
-                            VariantIdx::from_usize(1),
-                            args,
-                            None,
-                            None,
-                        )),
-                        IndexVec::from_raw(vec![val]),
-                    )
+                let variant_idx = if is_return {
+                    ONE // CoroutineState::Complete(val)
                 } else {
-                    // CoroutineState::Yielded(val)
-                    Rvalue::Aggregate(
-                        Box::new(AggregateKind::Adt(
-                            coroutine_state_def_id,
-                            VariantIdx::ZERO,
-                            args,
-                            None,
-                            None,
-                        )),
-                        IndexVec::from_raw(vec![val]),
-                    )
-                }
+                    ZERO // CoroutineState::Yielded(val)
+                };
+                make_aggregate_adt(
+                    coroutine_state_def_id,
+                    variant_idx,
+                    args,
+                    IndexVec::from_raw(vec![val]),
+                )
             }
         };
 
@@ -517,7 +417,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
             self.make_state(v, source_info, is_return, &mut data.statements);
             let state = if let Some((resume, mut resume_arg)) = resume {
                 // Yield
-                let state = RESERVED_VARIANTS + self.suspension_points.len();
+                let state = CoroutineArgs::RESERVED_VARIANTS + self.suspension_points.len();
 
                 // The resume arg target location might itself be remapped if its base local is
                 // live across a yield.
@@ -550,7 +450,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
                 VariantIdx::new(state)
             } else {
                 // Return
-                VariantIdx::new(RETURNED) // state for returned
+                VariantIdx::new(CoroutineArgs::RETURNED) // state for returned
             };
             data.statements.push(self.set_discr(state, source_info));
             data.terminator_mut().kind = TerminatorKind::Return;
@@ -560,6 +460,15 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
     }
 }
 
+fn make_aggregate_adt<'tcx>(
+    def_id: DefId,
+    variant_idx: VariantIdx,
+    args: GenericArgsRef<'tcx>,
+    operands: IndexVec<FieldIdx, Operand<'tcx>>,
+) -> Rvalue<'tcx> {
+    Rvalue::Aggregate(Box::new(AggregateKind::Adt(def_id, variant_idx, args, None, None)), operands)
+}
+
 fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     let coroutine_ty = body.local_decls.raw[1].ty;
 
@@ -569,7 +478,7 @@ fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Bo
     body.local_decls.raw[1].ty = ref_coroutine_ty;
 
     // Add a deref to accesses of the coroutine state
-    DerefArgVisitor { tcx }.visit_body(body);
+    SelfArgVisitor::new(tcx, ProjectionElem::Deref).visit_body(body);
 }
 
 fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
@@ -584,7 +493,8 @@ fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body
     body.local_decls.raw[1].ty = pin_ref_coroutine_ty;
 
     // Add the Pin field access to accesses of the coroutine state
-    PinArgVisitor { ref_coroutine_ty, tcx }.visit_body(body);
+    SelfArgVisitor::new(tcx, ProjectionElem::Field(FieldIdx::ZERO, ref_coroutine_ty))
+        .visit_body(body);
 }
 
 /// Allocates a new local and replaces all references of `local` with it. Returns the new local.
@@ -651,8 +561,6 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
                         let local = eliminate_get_context_call(&mut body[bb]);
                         replace_resume_ty_local(tcx, body, local, context_mut_ref);
                     }
-                } else {
-                    continue;
                 }
             }
             TerminatorKind::Yield { resume_arg, .. } => {
@@ -665,24 +573,23 @@ fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
 
 fn eliminate_get_context_call<'tcx>(bb_data: &mut BasicBlockData<'tcx>) -> Local {
     let terminator = bb_data.terminator.take().unwrap();
-    if let TerminatorKind::Call { args, destination, target, .. } = terminator.kind {
-        let [arg] = *Box::try_from(args).unwrap();
-        let local = arg.node.place().unwrap().local;
-
-        let arg = Rvalue::Use(arg.node);
-        let assign = Statement {
-            source_info: terminator.source_info,
-            kind: StatementKind::Assign(Box::new((destination, arg))),
-        };
-        bb_data.statements.push(assign);
-        bb_data.terminator = Some(Terminator {
-            source_info: terminator.source_info,
-            kind: TerminatorKind::Goto { target: target.unwrap() },
-        });
-        local
-    } else {
+    let TerminatorKind::Call { args, destination, target, .. } = terminator.kind else {
         bug!();
-    }
+    };
+    let [arg] = *Box::try_from(args).unwrap();
+    let local = arg.node.place().unwrap().local;
+
+    let arg = Rvalue::Use(arg.node);
+    let assign = Statement {
+        source_info: terminator.source_info,
+        kind: StatementKind::Assign(Box::new((destination, arg))),
+    };
+    bb_data.statements.push(assign);
+    bb_data.terminator = Some(Terminator {
+        source_info: terminator.source_info,
+        kind: TerminatorKind::Goto { target: target.unwrap() },
+    });
+    local
 }
 
 #[cfg_attr(not(debug_assertions), allow(unused))]
@@ -1085,10 +992,11 @@ fn compute_layout<'tcx>(
     // Build the coroutine variant field list.
     // Create a map from local indices to coroutine struct indices.
     let mut variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, CoroutineSavedLocal>> =
-        iter::repeat(IndexVec::new()).take(RESERVED_VARIANTS).collect();
+        iter::repeat(IndexVec::new()).take(CoroutineArgs::RESERVED_VARIANTS).collect();
     let mut remap = IndexVec::from_elem_n(None, saved_locals.domain_size());
     for (suspension_point_idx, live_locals) in live_locals_at_suspension_points.iter().enumerate() {
-        let variant_index = VariantIdx::from(RESERVED_VARIANTS + suspension_point_idx);
+        let variant_index =
+            VariantIdx::from(CoroutineArgs::RESERVED_VARIANTS + suspension_point_idx);
         let mut fields = IndexVec::new();
         for (idx, saved_local) in live_locals.iter().enumerate() {
             fields.push(saved_local);
@@ -1183,12 +1091,10 @@ fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
                 source_info,
                 kind: TerminatorKind::Drop { place, target, unwind, replace: _ },
             } => {
-                if let Some(local) = place.as_local() {
-                    if local == SELF_ARG {
-                        (target, unwind, source_info)
-                    } else {
-                        continue;
-                    }
+                if let Some(local) = place.as_local()
+                    && local == SELF_ARG
+                {
+                    (target, unwind, source_info)
                 } else {
                     continue;
                 }
@@ -1237,7 +1143,7 @@ fn create_coroutine_drop_shim<'tcx>(
 
     let mut cases = create_cases(&mut body, transform, Operation::Drop);
 
-    cases.insert(0, (UNRESUMED, drop_clean));
+    cases.insert(0, (CoroutineArgs::UNRESUMED, drop_clean));
 
     // The returned state and the poisoned state fall through to the default
     // case which is just to return
@@ -1387,7 +1293,9 @@ fn create_coroutine_resume_function<'tcx>(
     if can_unwind {
         let source_info = SourceInfo::outermost(body.span);
         let poison_block = body.basic_blocks_mut().push(BasicBlockData {
-            statements: vec![transform.set_discr(VariantIdx::new(POISONED), source_info)],
+            statements: vec![
+                transform.set_discr(VariantIdx::new(CoroutineArgs::POISONED), source_info),
+            ],
             terminator: Some(Terminator { source_info, kind: TerminatorKind::UnwindResume }),
             is_cleanup: true,
         });
@@ -1419,13 +1327,16 @@ fn create_coroutine_resume_function<'tcx>(
     use rustc_middle::mir::AssertKind::{ResumedAfterPanic, ResumedAfterReturn};
 
     // Jump to the entry point on the unresumed
-    cases.insert(0, (UNRESUMED, START_BLOCK));
+    cases.insert(0, (CoroutineArgs::UNRESUMED, START_BLOCK));
 
     // Panic when resumed on the returned or poisoned state
     if can_unwind {
         cases.insert(
             1,
-            (POISONED, insert_panic_block(tcx, body, ResumedAfterPanic(transform.coroutine_kind))),
+            (
+                CoroutineArgs::POISONED,
+                insert_panic_block(tcx, body, ResumedAfterPanic(transform.coroutine_kind)),
+            ),
         );
     }
 
@@ -1440,7 +1351,7 @@ fn create_coroutine_resume_function<'tcx>(
                 transform.insert_none_ret_block(body)
             }
         };
-        cases.insert(1, (RETURNED, block));
+        cases.insert(1, (CoroutineArgs::RETURNED, block));
     }
 
     insert_switch(body, cases, &transform, TerminatorKind::Unreachable);
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 7a531977267e8..9e460a725eeb2 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -3,13 +3,11 @@
 #![feature(box_patterns)]
 #![feature(const_type_name)]
 #![feature(cow_is_borrowed)]
-#![feature(decl_macro)]
 #![feature(if_let_guard)]
 #![feature(impl_trait_in_assoc_type)]
 #![feature(let_chains)]
 #![feature(map_try_insert)]
 #![feature(never_type)]
-#![feature(option_get_or_insert_default)]
 #![feature(round_char_boundary)]
 #![feature(try_blocks)]
 #![feature(yeet_expr)]
@@ -17,6 +15,7 @@
 
 use hir::ConstContext;
 use required_consts::RequiredConstsVisitor;
+use rustc_const_eval::check_consts::{self, ConstCx};
 use rustc_const_eval::util;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_data_structures::steal::Steal;
@@ -33,6 +32,7 @@ use rustc_middle::mir::{
 use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
 use rustc_middle::util::Providers;
 use rustc_middle::{bug, query, span_bug};
+use rustc_mir_dataflow::rustc_peek;
 use rustc_span::source_map::Spanned;
 use rustc_span::{sym, DUMMY_SP};
 use rustc_trait_selection::traits;
@@ -108,9 +108,6 @@ mod unreachable_enum_branching;
 mod unreachable_prop;
 mod validate;
 
-use rustc_const_eval::check_consts::{self, ConstCx};
-use rustc_mir_dataflow::rustc_peek;
-
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
 pub fn provide(providers: &mut Providers) {
@@ -128,7 +125,7 @@ pub fn provide(providers: &mut Providers) {
         mir_coroutine_witnesses: coroutine::mir_coroutine_witnesses,
         optimized_mir,
         is_mir_available,
-        is_ctfe_mir_available: |tcx, did| is_mir_available(tcx, did),
+        is_ctfe_mir_available: is_mir_available,
         mir_callgraph_reachable: inline::cycle::mir_callgraph_reachable,
         mir_inliner_callees: inline::cycle::mir_inliner_callees,
         promoted_mir,
@@ -221,10 +218,8 @@ fn is_mir_available(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
 /// Finds the full set of `DefId`s within the current crate that have
 /// MIR associated with them.
 fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
-    let mut set = FxIndexSet::default();
-
     // All body-owners have MIR associated with them.
-    set.extend(tcx.hir().body_owners());
+    let mut set: FxIndexSet<_> = tcx.hir().body_owners().collect();
 
     // Additionally, tuple struct/variant constructors have MIR, but
     // they don't have a BodyId, so we need to build them separately.
@@ -249,8 +244,7 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
 
     // No need to const-check a non-const `fn`.
     match const_kind {
-        Some(ConstContext::Const { .. } | ConstContext::Static(_))
-        | Some(ConstContext::ConstFn) => {}
+        Some(ConstContext::Const { .. } | ConstContext::Static(_) | ConstContext::ConstFn) => {}
         None => span_bug!(
             tcx.def_span(def),
             "`mir_const_qualif` should only be called on const fns and const items"
diff --git a/compiler/rustc_next_trait_solver/src/lib.rs b/compiler/rustc_next_trait_solver/src/lib.rs
index ea244b5107ad6..ca140500e2cd3 100644
--- a/compiler/rustc_next_trait_solver/src/lib.rs
+++ b/compiler/rustc_next_trait_solver/src/lib.rs
@@ -5,6 +5,7 @@
 //! So if you got to this crate from the old solver, it's totally normal.
 
 // tidy-alphabetical-start
+#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_inherent))]
 #![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index a70d51606f7d3..0fedb998463a2 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -223,7 +223,7 @@ impl<'a, 'b, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'b, 'tcx> {
                 // we must create two defs.
                 let coroutine_def =
                     self.create_def(coroutine_kind.closure_id(), kw::Empty, DefKind::Closure, span);
-                self.with_parent(coroutine_def, |this| visit::walk_expr(this, body));
+                self.with_parent(coroutine_def, |this| this.visit_expr(body));
             }
             _ => visit::walk_fn(self, fn_kind),
         }
diff --git a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs
index 215c0724f91de..80d58e5baceac 100644
--- a/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv64imac_unknown_nuttx_elf.rs
@@ -21,7 +21,6 @@ pub fn target() -> Target {
             os: "nuttx".into(),
             linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
             linker: Some("rust-lld".into()),
-            llvm_abiname: "lp64d".into(),
             cpu: "generic-rv64".into(),
             max_atomic_width: Some(64),
             features: "+m,+a,+c".into(),
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index de41d2f3cc512..f763153a5fc88 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -5,6 +5,7 @@
     feature(associated_type_defaults, never_type, rustc_attrs, negative_impls)
 )]
 #![cfg_attr(feature = "nightly", allow(internal_features))]
+#![cfg_attr(not(bootstrap), allow(rustc::usage_of_type_ir_inherent))]
 // tidy-alphabetical-end
 
 extern crate self as rustc_type_ir;
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index f6f773cc42a4f..c7908578522a5 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -3302,7 +3302,7 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMutKey<'a, K, V, A> {
         Some(kv)
     }
 
-    /// Removes the precending element from the `BTreeMap`.
+    /// Removes the preceding element from the `BTreeMap`.
     ///
     /// The element that was removed is returned. The cursor position is
     /// unchanged (after the removed element).
@@ -3408,7 +3408,7 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMut<'a, K, V, A> {
         self.inner.remove_next()
     }
 
-    /// Removes the precending element from the `BTreeMap`.
+    /// Removes the preceding element from the `BTreeMap`.
     ///
     /// The element that was removed is returned. The cursor position is
     /// unchanged (after the removed element).
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 973e7c660670c..2b5bebcd8cd08 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -2298,7 +2298,7 @@ impl<'a, T: Ord, A: Allocator + Clone> CursorMut<'a, T, A> {
         self.inner.remove_next().map(|(k, _)| k)
     }
 
-    /// Removes the precending element from the `BTreeSet`.
+    /// Removes the preceding element from the `BTreeSet`.
     ///
     /// The element that was removed is returned. The cursor position is
     /// unchanged (after the removed element).
@@ -2384,7 +2384,7 @@ impl<'a, T: Ord, A: Allocator + Clone> CursorMutKey<'a, T, A> {
         self.inner.remove_next().map(|(k, _)| k)
     }
 
-    /// Removes the precending element from the `BTreeSet`.
+    /// Removes the preceding element from the `BTreeSet`.
     ///
     /// The element that was removed is returned. The cursor position is
     /// unchanged (after the removed element).
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 61c713c9e81cf..c63f261edabfa 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -37,7 +37,7 @@ pub use iter::IntoIter;
 ///
 /// # Example
 ///
-/// Creating muliple copies of a `String`:
+/// Creating multiple copies of a `String`:
 /// ```rust
 /// #![feature(array_repeat)]
 ///
diff --git a/library/core/src/future/async_drop.rs b/library/core/src/future/async_drop.rs
index 8971a2c0aafd1..16ac77fa15045 100644
--- a/library/core/src/future/async_drop.rs
+++ b/library/core/src/future/async_drop.rs
@@ -157,7 +157,7 @@ async unsafe fn surface_drop_in_place<T: Drop + ?Sized>(ptr: *mut T) {
     unsafe { crate::ops::fallback_surface_drop(&mut *ptr) }
 }
 
-/// Wraps a future to continue outputing `Poll::Ready(())` once after
+/// Wraps a future to continue outputting `Poll::Ready(())` once after
 /// wrapped future completes by returning `Poll::Ready(())` on poll. This
 /// is useful for constructing async destructors to guarantee this
 /// "fuse" property
@@ -223,7 +223,7 @@ where
 /// # Safety
 ///
 /// Same as `async_drop_in_place` except is lazy to avoid creating
-/// multiple mutable refernces.
+/// multiple mutable references.
 #[lang = "async_drop_defer"]
 async unsafe fn defer<T: ?Sized>(to_drop: *mut T) {
     // SAFETY: same safety requirements as `async_drop_in_place`
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index 6ca5e53df3b01..a69f0afdb0a59 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -1,6 +1,7 @@
 #![stable(feature = "core_hint", since = "1.27.0")]
 
 //! Hints to compiler that affects how code should be emitted or optimized.
+//!
 //! Hints may be compile time or runtime.
 
 use crate::{intrinsics, ub_checks};
diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs
index c7cec396e1f2e..fb0aa5398a55b 100644
--- a/library/core/src/intrinsics/mir.rs
+++ b/library/core/src/intrinsics/mir.rs
@@ -310,7 +310,7 @@ define!(
 );
 define!(
     "mir_unwind_cleanup",
-    /// An unwind action that continues execution in a given basic blok.
+    /// An unwind action that continues execution in a given basic block.
     fn UnwindCleanup(goto: BasicBlock) -> UnwindActionArg
 );
 
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index ac51a40d9f478..888832251f6da 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -1072,7 +1072,7 @@ pub(crate) mod builtin {
     /// If the environment variable is not defined, then a compilation error
     /// will be emitted. To not emit a compile error, use the [`option_env!`]
     /// macro instead. A compilation error will also be emitted if the
-    /// environment variable is not a vaild Unicode string.
+    /// environment variable is not a valid Unicode string.
     ///
     /// # Examples
     ///
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index a7037b2a119ff..5451e45f6c817 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -832,8 +832,9 @@ mod prim_array {}
 #[doc(alias = "[")]
 #[doc(alias = "]")]
 #[doc(alias = "[]")]
-/// A dynamically-sized view into a contiguous sequence, `[T]`. Contiguous here
-/// means that elements are laid out so that every element is the same
+/// A dynamically-sized view into a contiguous sequence, `[T]`.
+///
+/// Contiguous here means that elements are laid out so that every element is the same
 /// distance from its neighbors.
 ///
 /// *[See also the `std::slice` module](crate::slice).*
diff --git a/library/std/build.rs b/library/std/build.rs
index fecdf2c3e1f43..72254cafc850d 100644
--- a/library/std/build.rs
+++ b/library/std/build.rs
@@ -142,7 +142,7 @@ fn main() {
 
     // Configure platforms that have reliable basics but may have unreliable math.
 
-    // LLVM is currenlty adding missing routines, <https://github.com/llvm/llvm-project/issues/93566>
+    // LLVM is currently adding missing routines, <https://github.com/llvm/llvm-project/issues/93566>
     let has_reliable_f16_math = has_reliable_f16
         && match (target_arch.as_str(), target_os.as_str()) {
             // FIXME: Disabled on Miri as the intrinsics are not implemented yet.
diff --git a/library/std/src/io/tests.rs b/library/std/src/io/tests.rs
index bb6a53bb290f9..24e5a1dfd5c00 100644
--- a/library/std/src/io/tests.rs
+++ b/library/std/src/io/tests.rs
@@ -738,7 +738,7 @@ fn read_buf_full_read() {
 #[test]
 // Miri does not support signalling OOM
 #[cfg_attr(miri, ignore)]
-// 64-bit only to be sure the allocator will fail fast on an impossible to satsify size
+// 64-bit only to be sure the allocator will fail fast on an impossible to satisfy size
 #[cfg(target_pointer_width = "64")]
 fn try_oom_error() {
     let mut v = Vec::<u8>::new();
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index 307a543c9d215..b6f36931ec28a 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -146,7 +146,7 @@ fn lang_start_internal(
             rtabort!("drop of the panic payload panicked");
         });
     panic::catch_unwind(cleanup).map_err(rt_abort)?;
-    // Guard against multple threads calling `libc::exit` concurrently.
+    // Guard against multiple threads calling `libc::exit` concurrently.
     // See the documentation for `unique_thread_exit` for more information.
     panic::catch_unwind(|| crate::sys::exit_guard::unique_thread_exit()).map_err(rt_abort)?;
     ret_code
diff --git a/library/std/src/sync/mpmc/list.rs b/library/std/src/sync/mpmc/list.rs
index bbe205cad04e6..88a8c75f7c8b9 100644
--- a/library/std/src/sync/mpmc/list.rs
+++ b/library/std/src/sync/mpmc/list.rs
@@ -551,7 +551,7 @@ impl<T> Channel<T> {
 
         let mut head = self.head.index.load(Ordering::Acquire);
         // The channel may be uninitialized, so we have to swap to avoid overwriting any sender's attempts
-        // to initalize the first block before noticing that the receivers disconnected. Late allocations
+        // to initialize the first block before noticing that the receivers disconnected. Late allocations
         // will be deallocated by the sender in Drop.
         let mut block = self.head.block.swap(ptr::null_mut(), Ordering::AcqRel);
 
diff --git a/library/std/src/sys/pal/uefi/process.rs b/library/std/src/sys/pal/uefi/process.rs
index fdc5f5d7e4fea..0cc9cecb89db0 100644
--- a/library/std/src/sys/pal/uefi/process.rs
+++ b/library/std/src/sys/pal/uefi/process.rs
@@ -470,7 +470,7 @@ mod uefi_command_internal {
             let st_size = unsafe { (*self.st.as_ptr()).hdr.header_size as usize };
             let mut crc32: u32 = 0;
 
-            // Set crc to 0 before calcuation
+            // Set crc to 0 before calculation
             unsafe {
                 (*self.st.as_mut_ptr()).hdr.crc32 = 0;
             }
diff --git a/library/std/src/sys/pal/unix/net.rs b/library/std/src/sys/pal/unix/net.rs
index bc0e3f4eeeac8..d75a666d350ff 100644
--- a/library/std/src/sys/pal/unix/net.rs
+++ b/library/std/src/sys/pal/unix/net.rs
@@ -215,7 +215,7 @@ impl Socket {
                 _ => {
                     if cfg!(target_os = "vxworks") {
                         // VxWorks poll does not return  POLLHUP or POLLERR in revents. Check if the
-                        // connnection actually succeeded and return ok only when the socket is
+                        // connection actually succeeded and return ok only when the socket is
                         // ready and no errors were found.
                         if let Some(e) = self.take_error()? {
                             return Err(e);
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index fc4033f832042..dc34c7844bfdd 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -1250,6 +1250,7 @@ fn render_assoc_items_inner(
     let Some(v) = cache.impls.get(&it) else { return };
     let (non_trait, traits): (Vec<_>, _) = v.iter().partition(|i| i.inner_impl().trait_.is_none());
     if !non_trait.is_empty() {
+        let mut close_tags = <Vec<&str>>::with_capacity(1);
         let mut tmp_buf = Buffer::html();
         let (render_mode, id, class_html) = match what {
             AssocItemRender::All => {
@@ -1260,6 +1261,8 @@ fn render_assoc_items_inner(
                 let id =
                     cx.derive_id(small_url_encode(format!("deref-methods-{:#}", type_.print(cx))));
                 let derived_id = cx.derive_id(&id);
+                tmp_buf.write_str("<details class=\"toggle big-toggle\" open><summary>");
+                close_tags.push("</details>");
                 write_impl_section_heading(
                     &mut tmp_buf,
                     &format!(
@@ -1269,6 +1272,7 @@ fn render_assoc_items_inner(
                     ),
                     &id,
                 );
+                tmp_buf.write_str("</summary>");
                 if let Some(def_id) = type_.def_id(cx.cache()) {
                     cx.deref_id_map.insert(def_id, id);
                 }
@@ -1302,6 +1306,9 @@ fn render_assoc_items_inner(
                 impls_buf.into_inner()
             )
             .unwrap();
+            for tag in close_tags.into_iter().rev() {
+                w.write_str(tag).unwrap();
+            }
         }
     }
 
@@ -1558,7 +1565,7 @@ fn render_impl(
     let cache = &shared.cache;
     let traits = &cache.traits;
     let trait_ = i.trait_did().map(|did| &traits[&did]);
-    let mut close_tags = String::new();
+    let mut close_tags = <Vec<&str>>::with_capacity(2);
 
     // For trait implementations, the `interesting` output contains all methods that have doc
     // comments, and the `boring` output contains all methods that do not. The distinction is
@@ -1870,7 +1877,7 @@ fn render_impl(
     if render_mode == RenderMode::Normal {
         let toggled = !(impl_items.is_empty() && default_impl_items.is_empty());
         if toggled {
-            close_tags.insert_str(0, "</details>");
+            close_tags.push("</details>");
             write!(
                 w,
                 "<details class=\"toggle implementors-toggle\"{}>\
@@ -1916,14 +1923,16 @@ fn render_impl(
         }
         if !default_impl_items.is_empty() || !impl_items.is_empty() {
             w.write_str("<div class=\"impl-items\">");
-            close_tags.insert_str(0, "</div>");
+            close_tags.push("</div>");
         }
     }
     if !default_impl_items.is_empty() || !impl_items.is_empty() {
         w.push_buffer(default_impl_items);
         w.push_buffer(impl_items);
     }
-    w.write_str(&close_tags);
+    for tag in close_tags.into_iter().rev() {
+        w.write_str(tag);
+    }
 }
 
 // Render the items that appear on the right side of methods, impls, and
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 28df8d3f011fe..1e48306228967 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -1852,6 +1852,11 @@ details.toggle {
 	position: relative;
 }
 
+details.big-toggle {
+	/* This makes [-] on the same line as <summary>. */
+	contain: inline-size;
+}
+
 /* The hideme class is used on summary tags that contain a span with
 	placeholder text shown only when the toggle is closed. For instance,
 	"Expand description" or "Show methods". */
@@ -1942,6 +1947,11 @@ details.toggle > summary:not(.hideme)::before {
 	left: -24px;
 }
 
+details.big-toggle > summary:not(.hideme)::before {
+	left: -34px;
+	top: 9px;
+}
+
 /* When a "hideme" summary is open and the "Expand description" or "Show
 	methods" text is hidden, we want the [-] toggle that remains to not
 	affect the layout of the items to its right. To do that, we use
diff --git a/tests/run-make/rustdoc-output-stdout/rmake.rs b/tests/run-make/rustdoc-output-stdout/rmake.rs
index dbc9892f3f59a..bcf5e4d97239f 100644
--- a/tests/run-make/rustdoc-output-stdout/rmake.rs
+++ b/tests/run-make/rustdoc-output-stdout/rmake.rs
@@ -4,17 +4,28 @@
 use std::path::PathBuf;
 
 use run_make_support::path_helpers::{cwd, has_extension, read_dir_entries_recursive};
-use run_make_support::rustdoc;
+use run_make_support::{rustdoc, serde_json};
 
 fn main() {
-    // First we check that we generate the JSON in the stdout.
-    rustdoc()
+    let json_string = rustdoc()
         .input("foo.rs")
         .out_dir("-")
         .arg("-Zunstable-options")
         .output_format("json")
         .run()
-        .assert_stdout_contains("{\"");
+        .stdout_utf8();
+
+    // First we check that we generate the JSON in the stdout.
+    let json_value: serde_json::Value =
+        serde_json::from_str(&json_string).expect("stdout should be valid json");
+
+    // We don't care to test the specifics of the JSON, as that's done
+    // elsewhere, just check that it has a format_version (as all JSON output
+    // should).
+    let format_version = json_value["format_version"]
+        .as_i64()
+        .expect("json output should contain format_version field");
+    assert!(format_version > 30);
 
     // Then we check it didn't generate any JSON file.
     read_dir_entries_recursive(cwd(), |path| {
diff --git a/tests/rustdoc-gui/deref-block.goml b/tests/rustdoc-gui/deref-block.goml
new file mode 100644
index 0000000000000..24f612f8a6fd1
--- /dev/null
+++ b/tests/rustdoc-gui/deref-block.goml
@@ -0,0 +1,30 @@
+// This test ensures that several clickable items actually have the pointer cursor.
+go-to: "file://" + |DOC_PATH| + "/lib2/struct.Derefer.html"
+
+assert-text: (".big-toggle summary", "Methods from Deref<Target = str>§")
+// We ensure it doesn't go over `§`.
+assert-css: (".big-toggle summary::before", {
+    "left": "-34px",
+    "top": "9px",
+})
+// It should NOT have the same X or Y position as the other toggles.
+compare-elements-position-false: (
+    ".big-toggle summary::before",
+    ".method-toggle summary::before",
+    ["x", "y"],
+)
+
+// We now check that if we're in mobile mode, it gets back to its original X position.
+set-window-size: (600, 600)
+assert-css: (".big-toggle summary::before", {
+    "left": "-11px",
+    "top": "9px",
+})
+// It should have the same X position as the other toggles.
+compare-elements-position: (".big-toggle summary::before", ".method-toggle summary::before", ["x"])
+// But still shouldn't have the same Y position.
+compare-elements-position-false: (
+    ".big-toggle summary::before",
+    ".method-toggle summary::before",
+    ["y"],
+)
diff --git a/tests/rustdoc-gui/src/lib2/lib.rs b/tests/rustdoc-gui/src/lib2/lib.rs
index 2467c7adae1a3..8db754f91ce61 100644
--- a/tests/rustdoc-gui/src/lib2/lib.rs
+++ b/tests/rustdoc-gui/src/lib2/lib.rs
@@ -356,3 +356,13 @@ pub mod scroll_traits {
         fn this_is_a_method_with_a_long_name_returning_something() -> String;
     }
 }
+
+pub struct Derefer(String);
+
+impl std::ops::Deref for Derefer {
+    type Target = str;
+
+    fn deref(&self) -> &Self::Target {
+        &self.0
+    }
+}
diff --git a/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.rs b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.rs
new file mode 100644
index 0000000000000..08d86606a6bab
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.rs
@@ -0,0 +1,18 @@
+//@ compile-flags: -Z unstable-options
+
+// #[cfg(bootstrap)]: We can stop ignoring next beta bump; afterward this ALWAYS should run.
+//@ ignore-stage1
+
+#![feature(rustc_private)]
+#![deny(rustc::usage_of_type_ir_inherent)]
+
+extern crate rustc_type_ir;
+
+use rustc_type_ir::inherent::*;
+//~^ ERROR do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
+use rustc_type_ir::inherent;
+//~^ ERROR do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
+use rustc_type_ir::inherent::Predicate;
+//~^ ERROR do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
+
+fn main() {}
diff --git a/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.stderr b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.stderr
new file mode 100644
index 0000000000000..cc6cb9170c0d4
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/import-of-type-ir-inherent.stderr
@@ -0,0 +1,31 @@
+error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
+  --> $DIR/import-of-type-ir-inherent.rs:11:20
+   |
+LL | use rustc_type_ir::inherent::*;
+   |                    ^^^^^^^^
+   |
+   = note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler
+note: the lint level is defined here
+  --> $DIR/import-of-type-ir-inherent.rs:7:9
+   |
+LL | #![deny(rustc::usage_of_type_ir_inherent)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
+  --> $DIR/import-of-type-ir-inherent.rs:13:20
+   |
+LL | use rustc_type_ir::inherent;
+   |                    ^^^^^^^^
+   |
+   = note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler
+
+error: do not use `rustc_type_ir::inherent` unless you're inside of the trait solver
+  --> $DIR/import-of-type-ir-inherent.rs:15:20
+   |
+LL | use rustc_type_ir::inherent::Predicate;
+   |                    ^^^^^^^^
+   |
+   = note: the method or struct you're looking for is likely defined somewhere else downstream in the compiler
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/async-await/async-closures/mac-body.rs b/tests/ui/async-await/async-closures/mac-body.rs
new file mode 100644
index 0000000000000..a416227c3904f
--- /dev/null
+++ b/tests/ui/async-await/async-closures/mac-body.rs
@@ -0,0 +1,12 @@
+//@ edition: 2021
+//@ check-pass
+
+#![feature(async_closure)]
+
+// Make sure we don't ICE if an async closure has a macro body.
+// This happened because we were calling walk instead of visit
+// in the def collector, oops!
+
+fn main() {
+    let _ = async || println!();
+}
diff --git a/triagebot.toml b/triagebot.toml
index d3333b67d155b..651d27f034108 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -913,7 +913,14 @@ cc = ["@kobzol"]
 [assign]
 warn_non_default_branch = true
 contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
-users_on_vacation = ["jyn514", "jhpratt", "oli-obk", "kobzol", "joboet"]
+users_on_vacation = [
+    "jhpratt",
+    "joboet",
+    "jyn514",
+    "kobzol",
+    "oli-obk",
+    "tgross35",
+]
 
 [assign.adhoc_groups]
 compiler-team = [