about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/input_output.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/call.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs12
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs5
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs22
-rw-r--r--compiler/rustc_const_eval/src/interpret/util.rs35
-rw-r--r--compiler/rustc_errors/src/emitter.rs135
-rw-r--r--compiler/rustc_errors/src/lib.rs11
-rw-r--r--compiler/rustc_expand/src/expand.rs3
-rw-r--r--compiler/rustc_hir/src/def.rs4
-rw-r--r--compiler/rustc_hir/src/hir.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/loops.rs50
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs4
-rw-r--r--compiler/rustc_infer/src/infer/outlives/obligations.rs2
-rw-r--r--compiler/rustc_interface/src/passes.rs4
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs1
-rw-r--r--compiler/rustc_middle/src/hir/map.rs12
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs3
-rw-r--r--compiler/rustc_middle/src/query/mod.rs7
-rw-r--r--compiler/rustc_middle/src/ty/generic_args.rs29
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs8
-rw-r--r--compiler/rustc_mir_build/messages.ftl2
-rw-r--r--compiler/rustc_mir_build/src/builder/expr/as_operand.rs4
-rw-r--r--compiler/rustc_mir_build/src/errors.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs4
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/initialized.rs3
-rw-r--r--compiler/rustc_mir_transform/src/ctfe_limit.rs2
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drop.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs20
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs11
-rw-r--r--compiler/rustc_privacy/src/lib.rs24
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs25
-rw-r--r--compiler/rustc_resolve/src/errors.rs52
-rw-r--r--compiler/rustc_resolve/src/late.rs10
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs5
-rw-r--r--compiler/rustc_span/src/hygiene.rs4
-rw-r--r--compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs1
-rw-r--r--compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs2
-rw-r--r--compiler/rustc_thread_pool/src/scope/mod.rs6
-rw-r--r--compiler/rustc_thread_pool/src/sleep/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs64
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs16
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs43
-rw-r--r--compiler/rustc_type_ir/src/flags.rs11
-rw-r--r--compiler/rustc_type_ir/src/ty_kind/closure.rs27
57 files changed, 449 insertions, 299 deletions
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 68f1637e07e..f1320048533 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -417,7 +417,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// minimum values.
     ///
     /// For example:
-    /// ```
+    /// ```ignore (illustrative)
     /// fn foo<'a, 'b>( /* ... */ ) where 'a: 'b { /* ... */ }
     /// ```
     /// would initialize two variables like so:
diff --git a/compiler/rustc_borrowck/src/type_check/input_output.rs b/compiler/rustc_borrowck/src/type_check/input_output.rs
index 99392ea1915..eb31b5de05d 100644
--- a/compiler/rustc_borrowck/src/type_check/input_output.rs
+++ b/compiler/rustc_borrowck/src/type_check/input_output.rs
@@ -86,7 +86,6 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         // them with fresh ty vars.
                         resume_ty: next_ty_var(),
                         yield_ty: next_ty_var(),
-                        witness: next_ty_var(),
                     },
                 )
                 .args,
diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs
index 5b3adba0265..b8a65369825 100644
--- a/compiler/rustc_const_eval/src/interpret/call.rs
+++ b/compiler/rustc_const_eval/src/interpret/call.rs
@@ -11,6 +11,7 @@ use rustc_middle::ty::{self, AdtDef, Instance, Ty, VariantDef};
 use rustc_middle::{bug, mir, span_bug};
 use rustc_span::sym;
 use rustc_target::callconv::{ArgAbi, FnAbi, PassMode};
+use tracing::field::Empty;
 use tracing::{info, instrument, trace};
 
 use super::{
@@ -18,7 +19,8 @@ use super::{
     Projectable, Provenance, ReturnAction, ReturnContinuation, Scalar, StackPopInfo, interp_ok,
     throw_ub, throw_ub_custom, throw_unsup_format,
 };
-use crate::fluent_generated as fluent;
+use crate::interpret::EnteredTraceSpan;
+use crate::{enter_trace_span, fluent_generated as fluent};
 
 /// An argument passed to a function.
 #[derive(Clone, Debug)]
@@ -344,6 +346,8 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         destination: &PlaceTy<'tcx, M::Provenance>,
         mut cont: ReturnContinuation,
     ) -> InterpResult<'tcx> {
+        let _span = enter_trace_span!(M, step::init_stack_frame, %instance, tracing_separate_thread = Empty);
+
         // Compute callee information.
         // FIXME: for variadic support, do we have to somehow determine callee's extra_args?
         let callee_fn_abi = self.fn_abi_of_instance(instance, ty::List::empty())?;
@@ -523,7 +527,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         target: Option<mir::BasicBlock>,
         unwind: mir::UnwindAction,
     ) -> InterpResult<'tcx> {
-        trace!("init_fn_call: {:#?}", fn_val);
+        let _span =
+            enter_trace_span!(M, step::init_fn_call, tracing_separate_thread = Empty, ?fn_val)
+                .or_if_tracing_disabled(|| trace!("init_fn_call: {:#?}", fn_val));
 
         let instance = match fn_val {
             FnVal::Instance(instance) => instance,
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 21afd082a05..41713457908 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -13,6 +13,7 @@ use rustc_middle::ty::print::{FmtPrinter, PrettyPrinter};
 use rustc_middle::ty::{ConstInt, ScalarInt, Ty, TyCtxt};
 use rustc_middle::{bug, mir, span_bug, ty};
 use rustc_span::DUMMY_SP;
+use tracing::field::Empty;
 use tracing::trace;
 
 use super::{
@@ -20,6 +21,7 @@ use super::{
     OffsetMode, PlaceTy, Pointer, Projectable, Provenance, Scalar, alloc_range, err_ub,
     from_known_layout, interp_ok, mir_assign_valid_types, throw_ub,
 };
+use crate::enter_trace_span;
 
 /// An `Immediate` represents a single immediate self-contained Rust value.
 ///
@@ -770,6 +772,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         mir_place: mir::Place<'tcx>,
         layout: Option<TyAndLayout<'tcx>>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
+        let _span = enter_trace_span!(
+            M,
+            step::eval_place_to_op,
+            ?mir_place,
+            tracing_separate_thread = Empty
+        );
+
         // Do not use the layout passed in as argument if the base we are looking at
         // here is not the entire place.
         let layout = if mir_place.projection.is_empty() { layout } else { None };
@@ -813,6 +822,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         mir_op: &mir::Operand<'tcx>,
         layout: Option<TyAndLayout<'tcx>>,
     ) -> InterpResult<'tcx, OpTy<'tcx, M::Provenance>> {
+        let _span =
+            enter_trace_span!(M, step::eval_operand, ?mir_op, tracing_separate_thread = Empty);
+
         use rustc_middle::mir::Operand::*;
         let op = match mir_op {
             // FIXME: do some more logic on `move` to invalidate the old location
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index e2284729efd..45c4edb8503 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -9,6 +9,7 @@ use rustc_abi::{BackendRepr, HasDataLayout, Size};
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::{bug, mir, span_bug};
+use tracing::field::Empty;
 use tracing::{instrument, trace};
 
 use super::{
@@ -16,6 +17,7 @@ use super::{
     InterpResult, Machine, MemoryKind, Misalignment, OffsetMode, OpTy, Operand, Pointer,
     Projectable, Provenance, Scalar, alloc_range, interp_ok, mir_assign_valid_types,
 };
+use crate::enter_trace_span;
 
 #[derive(Copy, Clone, Hash, PartialEq, Eq, Debug)]
 /// Information required for the sound usage of a `MemPlace`.
@@ -524,6 +526,9 @@ where
         &self,
         mir_place: mir::Place<'tcx>,
     ) -> InterpResult<'tcx, PlaceTy<'tcx, M::Provenance>> {
+        let _span =
+            enter_trace_span!(M, step::eval_place, ?mir_place, tracing_separate_thread = Empty);
+
         let mut place = self.local_to_place(mir_place.local)?;
         // Using `try_fold` turned out to be bad for performance, hence the loop.
         for elem in mir_place.projection.iter() {
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 629dcc3523c..9df49c0f4cc 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -9,13 +9,15 @@ use rustc_middle::ty::{self, Instance, Ty};
 use rustc_middle::{bug, mir, span_bug};
 use rustc_span::source_map::Spanned;
 use rustc_target::callconv::FnAbi;
+use tracing::field::Empty;
 use tracing::{info, instrument, trace};
 
 use super::{
     FnArg, FnVal, ImmTy, Immediate, InterpCx, InterpResult, Machine, MemPlaceMeta, PlaceTy,
     Projectable, Scalar, interp_ok, throw_ub, throw_unsup_format,
 };
-use crate::util;
+use crate::interpret::EnteredTraceSpan;
+use crate::{enter_trace_span, util};
 
 struct EvaluatedCalleeAndArgs<'tcx, M: Machine<'tcx>> {
     callee: FnVal<'tcx, M::ExtraFnVal>,
@@ -74,7 +76,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
     ///
     /// This does NOT move the statement counter forward, the caller has to do that!
     pub fn eval_statement(&mut self, stmt: &mir::Statement<'tcx>) -> InterpResult<'tcx> {
-        info!("{:?}", stmt);
+        let _span = enter_trace_span!(
+            M,
+            step::eval_statement,
+            stmt = ?stmt.kind,
+            span = ?stmt.source_info.span,
+            tracing_separate_thread = Empty,
+        )
+        .or_if_tracing_disabled(|| info!(stmt = ?stmt.kind));
 
         use rustc_middle::mir::StatementKind::*;
 
@@ -456,7 +465,14 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
     }
 
     fn eval_terminator(&mut self, terminator: &mir::Terminator<'tcx>) -> InterpResult<'tcx> {
-        info!("{:?}", terminator.kind);
+        let _span = enter_trace_span!(
+            M,
+            step::eval_terminator,
+            terminator = ?terminator.kind,
+            span = ?terminator.source_info.span,
+            tracing_separate_thread = Empty,
+        )
+        .or_if_tracing_disabled(|| info!(terminator = ?terminator.kind));
 
         use rustc_middle::mir::TerminatorKind::*;
         match terminator.kind {
diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs
index 6696a0c5026..71800950faa 100644
--- a/compiler/rustc_const_eval/src/interpret/util.rs
+++ b/compiler/rustc_const_eval/src/interpret/util.rs
@@ -48,10 +48,24 @@ pub(crate) fn create_static_alloc<'tcx>(
 
 /// A marker trait returned by [crate::interpret::Machine::enter_trace_span], identifying either a
 /// real [tracing::span::EnteredSpan] in case tracing is enabled, or the dummy type `()` when
-/// tracing is disabled.
-pub trait EnteredTraceSpan {}
-impl EnteredTraceSpan for () {}
-impl EnteredTraceSpan for tracing::span::EnteredSpan {}
+/// tracing is disabled. Also see [crate::enter_trace_span!] below.
+pub trait EnteredTraceSpan {
+    /// Allows executing an alternative function when tracing is disabled. Useful for example if you
+    /// want to open a trace span when tracing is enabled, and alternatively just log a line when
+    /// tracing is disabled.
+    fn or_if_tracing_disabled(self, f: impl FnOnce()) -> Self;
+}
+impl EnteredTraceSpan for () {
+    fn or_if_tracing_disabled(self, f: impl FnOnce()) -> Self {
+        f(); // tracing is disabled, execute the function
+        self
+    }
+}
+impl EnteredTraceSpan for tracing::span::EnteredSpan {
+    fn or_if_tracing_disabled(self, _f: impl FnOnce()) -> Self {
+        self // tracing is enabled, don't execute anything
+    }
+}
 
 /// Shortand for calling [crate::interpret::Machine::enter_trace_span] on a [tracing::info_span!].
 /// This is supposed to be compiled out when [crate::interpret::Machine::enter_trace_span] has the
@@ -112,6 +126,19 @@ impl EnteredTraceSpan for tracing::span::EnteredSpan {}
 /// # type M = rustc_const_eval::const_eval::CompileTimeMachine<'static>;
 /// let _span = enter_trace_span!(M, step::eval_statement, tracing_separate_thread = tracing::field::Empty);
 /// ```
+///
+/// ### Executing something else when tracing is disabled
+///
+/// [crate::interpret::Machine::enter_trace_span] returns [EnteredTraceSpan], on which you can call
+/// [EnteredTraceSpan::or_if_tracing_disabled], to e.g. log a line as an alternative to the tracing
+/// span for when tracing is disabled. For example:
+/// ```rust
+/// # use rustc_const_eval::enter_trace_span;
+/// # use rustc_const_eval::interpret::EnteredTraceSpan;
+/// # type M = rustc_const_eval::const_eval::CompileTimeMachine<'static>;
+/// let _span = enter_trace_span!(M, step::eval_statement)
+///     .or_if_tracing_disabled(|| tracing::info!("eval_statement"));
+/// ```
 #[macro_export]
 macro_rules! enter_trace_span {
     ($machine:ty, $name:ident :: $subname:ident $($tt:tt)*) => {
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 8794bf930fd..84970e7c162 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -262,19 +262,11 @@ pub trait Emitter {
                     format!("help: {msg}")
                 } else {
                     // Show the default suggestion text with the substitution
-                    format!(
-                        "help: {}{}: `{}`",
-                        msg,
-                        if self
-                            .source_map()
-                            .is_some_and(|sm| is_case_difference(sm, snippet, part.span,))
-                        {
-                            " (notice the capitalization)"
-                        } else {
-                            ""
-                        },
-                        snippet,
-                    )
+                    let confusion_type = self
+                        .source_map()
+                        .map(|sm| detect_confusion_type(sm, snippet, part.span))
+                        .unwrap_or(ConfusionType::None);
+                    format!("help: {}{}: `{}`", msg, confusion_type.label_text(), snippet,)
                 };
                 primary_span.push_span_label(part.span, msg);
 
@@ -2031,12 +2023,12 @@ impl HumanEmitter {
         buffer.append(0, ": ", Style::HeaderMsg);
 
         let mut msg = vec![(suggestion.msg.to_owned(), Style::NoStyle)];
-        if suggestions
-            .iter()
-            .take(MAX_SUGGESTIONS)
-            .any(|(_, _, _, only_capitalization)| *only_capitalization)
+        if let Some(confusion_type) =
+            suggestions.iter().take(MAX_SUGGESTIONS).find_map(|(_, _, _, confusion_type)| {
+                if confusion_type.has_confusion() { Some(*confusion_type) } else { None }
+            })
         {
-            msg.push((" (notice the capitalization difference)".into(), Style::NoStyle));
+            msg.push((confusion_type.label_text().into(), Style::NoStyle));
         }
         self.msgs_to_buffer(
             &mut buffer,
@@ -3531,24 +3523,107 @@ pub fn is_different(sm: &SourceMap, suggested: &str, sp: Span) -> bool {
 }
 
 /// Whether the original and suggested code are visually similar enough to warrant extra wording.
-pub fn is_case_difference(sm: &SourceMap, suggested: &str, sp: Span) -> bool {
-    // FIXME: this should probably be extended to also account for `FO0` → `FOO` and unicode.
+pub fn detect_confusion_type(sm: &SourceMap, suggested: &str, sp: Span) -> ConfusionType {
     let found = match sm.span_to_snippet(sp) {
         Ok(snippet) => snippet,
         Err(e) => {
             warn!(error = ?e, "Invalid span {:?}", sp);
-            return false;
+            return ConfusionType::None;
         }
     };
-    let ascii_confusables = &['c', 'f', 'i', 'k', 'o', 's', 'u', 'v', 'w', 'x', 'y', 'z'];
-    // All the chars that differ in capitalization are confusable (above):
-    let confusable = iter::zip(found.chars(), suggested.chars())
-        .filter(|(f, s)| f != s)
-        .all(|(f, s)| ascii_confusables.contains(&f) || ascii_confusables.contains(&s));
-    confusable && found.to_lowercase() == suggested.to_lowercase()
-            // FIXME: We sometimes suggest the same thing we already have, which is a
-            //        bug, but be defensive against that here.
-            && found != suggested
+
+    let mut has_case_confusion = false;
+    let mut has_digit_letter_confusion = false;
+
+    if found.len() == suggested.len() {
+        let mut has_case_diff = false;
+        let mut has_digit_letter_confusable = false;
+        let mut has_other_diff = false;
+
+        let ascii_confusables = &['c', 'f', 'i', 'k', 'o', 's', 'u', 'v', 'w', 'x', 'y', 'z'];
+
+        let digit_letter_confusables = [('0', 'O'), ('1', 'l'), ('5', 'S'), ('8', 'B'), ('9', 'g')];
+
+        for (f, s) in iter::zip(found.chars(), suggested.chars()) {
+            if f != s {
+                if f.to_lowercase().to_string() == s.to_lowercase().to_string() {
+                    // Check for case differences (any character that differs only in case)
+                    if ascii_confusables.contains(&f) || ascii_confusables.contains(&s) {
+                        has_case_diff = true;
+                    } else {
+                        has_other_diff = true;
+                    }
+                } else if digit_letter_confusables.contains(&(f, s))
+                    || digit_letter_confusables.contains(&(s, f))
+                {
+                    // Check for digit-letter confusables (like 0 vs O, 1 vs l, etc.)
+                    has_digit_letter_confusable = true;
+                } else {
+                    has_other_diff = true;
+                }
+            }
+        }
+
+        // If we have case differences and no other differences
+        if has_case_diff && !has_other_diff && found != suggested {
+            has_case_confusion = true;
+        }
+        if has_digit_letter_confusable && !has_other_diff && found != suggested {
+            has_digit_letter_confusion = true;
+        }
+    }
+
+    match (has_case_confusion, has_digit_letter_confusion) {
+        (true, true) => ConfusionType::Both,
+        (true, false) => ConfusionType::Case,
+        (false, true) => ConfusionType::DigitLetter,
+        (false, false) => ConfusionType::None,
+    }
+}
+
+/// Represents the type of confusion detected between original and suggested code.
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum ConfusionType {
+    /// No confusion detected
+    None,
+    /// Only case differences (e.g., "hello" vs "Hello")
+    Case,
+    /// Only digit-letter confusion (e.g., "0" vs "O", "1" vs "l")
+    DigitLetter,
+    /// Both case and digit-letter confusion
+    Both,
+}
+
+impl ConfusionType {
+    /// Returns the appropriate label text for this confusion type.
+    pub fn label_text(&self) -> &'static str {
+        match self {
+            ConfusionType::None => "",
+            ConfusionType::Case => " (notice the capitalization)",
+            ConfusionType::DigitLetter => " (notice the digit/letter confusion)",
+            ConfusionType::Both => " (notice the capitalization and digit/letter confusion)",
+        }
+    }
+
+    /// Combines two confusion types. If either is `Both`, the result is `Both`.
+    /// If one is `Case` and the other is `DigitLetter`, the result is `Both`.
+    /// Otherwise, returns the non-`None` type, or `None` if both are `None`.
+    pub fn combine(self, other: ConfusionType) -> ConfusionType {
+        match (self, other) {
+            (ConfusionType::None, other) => other,
+            (this, ConfusionType::None) => this,
+            (ConfusionType::Both, _) | (_, ConfusionType::Both) => ConfusionType::Both,
+            (ConfusionType::Case, ConfusionType::DigitLetter)
+            | (ConfusionType::DigitLetter, ConfusionType::Case) => ConfusionType::Both,
+            (ConfusionType::Case, ConfusionType::Case) => ConfusionType::Case,
+            (ConfusionType::DigitLetter, ConfusionType::DigitLetter) => ConfusionType::DigitLetter,
+        }
+    }
+
+    /// Returns true if this confusion type represents any kind of confusion.
+    pub fn has_confusion(&self) -> bool {
+        *self != ConfusionType::None
+    }
 }
 
 pub(crate) fn should_show_source_code(
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 381d780077d..2534cddf105 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -50,7 +50,7 @@ pub use diagnostic_impls::{
     IndicateAnonymousLifetime, SingleLabelManySpans,
 };
 pub use emitter::ColorConfig;
-use emitter::{DynEmitter, Emitter, is_case_difference, is_different};
+use emitter::{ConfusionType, DynEmitter, Emitter, detect_confusion_type, is_different};
 use rustc_data_structures::AtomicRef;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_data_structures::stable_hasher::StableHasher;
@@ -308,7 +308,7 @@ impl CodeSuggestion {
     pub(crate) fn splice_lines(
         &self,
         sm: &SourceMap,
-    ) -> Vec<(String, Vec<SubstitutionPart>, Vec<Vec<SubstitutionHighlight>>, bool)> {
+    ) -> Vec<(String, Vec<SubstitutionPart>, Vec<Vec<SubstitutionHighlight>>, ConfusionType)> {
         // For the `Vec<Vec<SubstitutionHighlight>>` value, the first level of the vector
         // corresponds to the output snippet's lines, while the second level corresponds to the
         // substrings within that line that should be highlighted.
@@ -414,14 +414,15 @@ impl CodeSuggestion {
                 // We need to keep track of the difference between the existing code and the added
                 // or deleted code in order to point at the correct column *after* substitution.
                 let mut acc = 0;
-                let mut only_capitalization = false;
+                let mut confusion_type = ConfusionType::None;
                 for part in &mut substitution.parts {
                     // If this is a replacement of, e.g. `"a"` into `"ab"`, adjust the
                     // suggestion and snippet to look as if we just suggested to add
                     // `"b"`, which is typically much easier for the user to understand.
                     part.trim_trivial_replacements(sm);
 
-                    only_capitalization |= is_case_difference(sm, &part.snippet, part.span);
+                    let part_confusion = detect_confusion_type(sm, &part.snippet, part.span);
+                    confusion_type = confusion_type.combine(part_confusion);
                     let cur_lo = sm.lookup_char_pos(part.span.lo());
                     if prev_hi.line == cur_lo.line {
                         let mut count =
@@ -511,7 +512,7 @@ impl CodeSuggestion {
                 if highlights.iter().all(|parts| parts.is_empty()) {
                     None
                 } else {
-                    Some((buf, substitution.parts, highlights, only_capitalization))
+                    Some((buf, substitution.parts, highlights, confusion_type))
                 }
             })
             .collect()
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 0517fd0419d..f02aa6c120f 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -1411,9 +1411,8 @@ impl InvocationCollectorNode for P<ast::Item> {
                     }
                 }
             }
-
             let mut idents = Vec::new();
-            collect_use_tree_leaves(ut, &mut idents);
+            collect_use_tree_leaves(&ut, &mut idents);
             idents
         } else {
             self.kind.ident().into_iter().collect()
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 3fee9af01b3..2201d493f2d 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -360,7 +360,7 @@ impl DefKind {
 /// For example, everything prefixed with `/* Res */` in this example has
 /// an associated `Res`:
 ///
-/// ```
+/// ```ignore (illustrative)
 /// fn str_to_string(s: & /* Res */ str) -> /* Res */ String {
 ///     /* Res */ String::from(/* Res */ s)
 /// }
@@ -421,7 +421,7 @@ pub enum Res<Id = hir::HirId> {
     /// }
     ///
     /// impl Foo for Bar {
-    ///     fn foo() -> Box<Self> { // SelfTyAlias
+    ///     fn foo() -> Box<Self /* SelfTyAlias */> {
     ///         let _: Self;        // SelfTyAlias
     ///
     ///         todo!()
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 1b1b3ced44d..08361718108 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3016,7 +3016,7 @@ impl fmt::Display for LoopIdError {
     }
 }
 
-#[derive(Copy, Clone, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, Debug, PartialEq, HashStable_Generic)]
 pub struct Destination {
     /// This is `Some(_)` iff there is an explicit user-specified 'label
     pub label: Option<Label>,
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 e24426f9fed..bd9125363fc 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -425,7 +425,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateParam<'tcx> {
 ///
 /// trait Foo {
 ///     fn bar() -> impl Deref<Target = impl Sized>;
-///              // ^- RPITIT #1        ^- RPITIT #2
+///     //          ^- RPITIT #1        ^- RPITIT #2
 /// }
 ///
 /// impl Foo for () {
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index 31e9c3b80fb..e2462c2d465 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -379,20 +379,14 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
         // for info on the usage of each of these fields.
         let dummy_args = match kind {
             ClosureKind::Closure => &["<closure_kind>", "<closure_signature>", "<upvars>"][..],
-            ClosureKind::Coroutine(_) => &[
-                "<coroutine_kind>",
-                "<resume_ty>",
-                "<yield_ty>",
-                "<return_ty>",
-                "<witness>",
-                "<upvars>",
-            ][..],
+            ClosureKind::Coroutine(_) => {
+                &["<coroutine_kind>", "<resume_ty>", "<yield_ty>", "<return_ty>", "<upvars>"][..]
+            }
             ClosureKind::CoroutineClosure(_) => &[
                 "<closure_kind>",
                 "<closure_signature_parts>",
                 "<upvars>",
                 "<bound_captures_by_ref>",
-                "<witness>",
             ][..],
         };
 
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index a413f805873..82b7c578a1f 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -161,8 +161,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // Resume type defaults to `()` if the coroutine has no argument.
                 let resume_ty = liberated_sig.inputs().get(0).copied().unwrap_or(tcx.types.unit);
 
-                let interior = Ty::new_coroutine_witness(tcx, expr_def_id.to_def_id(), parent_args);
-
                 // Coroutines that come from coroutine closures have not yet determined
                 // their kind ty, so make a fresh infer var which will be constrained
                 // later during upvar analysis. Regular coroutines always have the kind
@@ -182,7 +180,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         resume_ty,
                         yield_ty,
                         return_ty: liberated_sig.output(),
-                        witness: interior,
                         tupled_upvars_ty,
                     },
                 );
@@ -210,7 +207,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 };
                 // Compute all of the variables that will be used to populate the coroutine.
                 let resume_ty = self.next_ty_var(expr_span);
-                let interior = self.next_ty_var(expr_span);
 
                 let closure_kind_ty = match expected_kind {
                     Some(kind) => Ty::from_closure_kind(tcx, kind),
@@ -243,7 +239,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         ),
                         tupled_upvars_ty,
                         coroutine_captures_by_ref_ty,
-                        coroutine_witness_ty: interior,
                     },
                 );
 
diff --git a/compiler/rustc_hir_typeck/src/loops.rs b/compiler/rustc_hir_typeck/src/loops.rs
index d47a3246964..acfa5c473aa 100644
--- a/compiler/rustc_hir_typeck/src/loops.rs
+++ b/compiler/rustc_hir_typeck/src/loops.rs
@@ -2,7 +2,6 @@ use std::collections::BTreeMap;
 use std::fmt;
 
 use Context::*;
-use rustc_ast::Label;
 use rustc_hir as hir;
 use rustc_hir::attrs::AttributeKind;
 use rustc_hir::def::DefKind;
@@ -42,8 +41,8 @@ enum Context {
     ConstBlock,
     /// E.g. `#[loop_match] loop { state = 'label: { /* ... */ } }`.
     LoopMatch {
-        /// The label of the labeled block (not of the loop itself).
-        labeled_block: Label,
+        /// The destination pointing to the labeled block (not to the loop itself).
+        labeled_block: Destination,
     },
 }
 
@@ -186,18 +185,18 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
             {
                 self.with_context(UnlabeledBlock(b.span.shrink_to_lo()), |v| v.visit_block(b));
             }
-            hir::ExprKind::Break(break_label, ref opt_expr) => {
+            hir::ExprKind::Break(break_destination, ref opt_expr) => {
                 if let Some(e) = opt_expr {
                     self.visit_expr(e);
                 }
 
-                if self.require_label_in_labeled_block(e.span, &break_label, "break") {
+                if self.require_label_in_labeled_block(e.span, &break_destination, "break") {
                     // If we emitted an error about an unlabeled break in a labeled
                     // block, we don't need any further checking for this break any more
                     return;
                 }
 
-                let loop_id = match break_label.target_id {
+                let loop_id = match break_destination.target_id {
                     Ok(loop_id) => Some(loop_id),
                     Err(hir::LoopIdError::OutsideLoopScope) => None,
                     Err(hir::LoopIdError::UnlabeledCfInWhileCondition) => {
@@ -212,18 +211,25 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
 
                 // A `#[const_continue]` must break to a block in a `#[loop_match]`.
                 if find_attr!(self.tcx.hir_attrs(e.hir_id), AttributeKind::ConstContinue(_)) {
-                    if let Some(break_label) = break_label.label {
-                        let is_target_label = |cx: &Context| match cx {
-                            Context::LoopMatch { labeled_block } => {
-                                break_label.ident.name == labeled_block.ident.name
-                            }
-                            _ => false,
-                        };
+                    let Some(label) = break_destination.label else {
+                        let span = e.span;
+                        self.tcx.dcx().emit_fatal(ConstContinueBadLabel { span });
+                    };
 
-                        if !self.cx_stack.iter().rev().any(is_target_label) {
-                            let span = break_label.ident.span;
-                            self.tcx.dcx().emit_fatal(ConstContinueBadLabel { span });
+                    let is_target_label = |cx: &Context| match cx {
+                        Context::LoopMatch { labeled_block } => {
+                            // NOTE: with macro expansion, the label's span might be different here
+                            // even though it does still refer to the same HIR node. A block
+                            // can't have two labels, so the hir_id is a unique identifier.
+                            assert!(labeled_block.target_id.is_ok()); // see `is_loop_match`.
+                            break_destination.target_id == labeled_block.target_id
                         }
+                        _ => false,
+                    };
+
+                    if !self.cx_stack.iter().rev().any(is_target_label) {
+                        let span = label.ident.span;
+                        self.tcx.dcx().emit_fatal(ConstContinueBadLabel { span });
                     }
                 }
 
@@ -249,7 +255,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
                         Some(kind) => {
                             let suggestion = format!(
                                 "break{}",
-                                break_label
+                                break_destination
                                     .label
                                     .map_or_else(String::new, |l| format!(" {}", l.ident))
                             );
@@ -259,7 +265,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
                                 kind: kind.name(),
                                 suggestion,
                                 loop_label,
-                                break_label: break_label.label,
+                                break_label: break_destination.label,
                                 break_expr_kind: &break_expr.kind,
                                 break_expr_span: break_expr.span,
                             });
@@ -268,7 +274,7 @@ impl<'hir> Visitor<'hir> for CheckLoopVisitor<'hir> {
                 }
 
                 let sp_lo = e.span.with_lo(e.span.lo() + BytePos("break".len() as u32));
-                let label_sp = match break_label.label {
+                let label_sp = match break_destination.label {
                     Some(label) => sp_lo.with_hi(label.ident.span.hi()),
                     None => sp_lo.shrink_to_lo(),
                 };
@@ -416,7 +422,7 @@ impl<'hir> CheckLoopVisitor<'hir> {
         &self,
         e: &'hir hir::Expr<'hir>,
         body: &'hir hir::Block<'hir>,
-    ) -> Option<Label> {
+    ) -> Option<Destination> {
         if !find_attr!(self.tcx.hir_attrs(e.hir_id), AttributeKind::LoopMatch(_)) {
             return None;
         }
@@ -438,8 +444,8 @@ impl<'hir> CheckLoopVisitor<'hir> {
 
         let hir::ExprKind::Assign(_, rhs_expr, _) = loop_body_expr.kind else { return None };
 
-        let hir::ExprKind::Block(_, label) = rhs_expr.kind else { return None };
+        let hir::ExprKind::Block(block, label) = rhs_expr.kind else { return None };
 
-        label
+        Some(Destination { label, target_id: Ok(block.hir_id) })
     }
 }
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index df38c3a1214..50fa3f2cc9d 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -2391,13 +2391,11 @@ fn migration_suggestion_for_2229(
 /// let mut p = Point { x: 10, y: 10 };
 ///
 /// let c = || {
-///     p.x     += 10;
-/// // ^ E1 ^
+///     p.x += 10; // E1
 ///     // ...
 ///     // More code
 ///     // ...
 ///     p.x += 10; // E2
-/// // ^ E2 ^
 /// };
 /// ```
 /// `CaptureKind` associated with both `E1` and `E2` will be ByRef(MutBorrow),
diff --git a/compiler/rustc_infer/src/infer/outlives/obligations.rs b/compiler/rustc_infer/src/infer/outlives/obligations.rs
index bb3b51c0ab2..b989d419057 100644
--- a/compiler/rustc_infer/src/infer/outlives/obligations.rs
+++ b/compiler/rustc_infer/src/infer/outlives/obligations.rs
@@ -36,7 +36,7 @@
 //! fn bar<T>(a: T, b: impl for<'a> Fn(&'a T)) {}
 //! fn foo<T>(x: T) {
 //!     bar(x, |y| { /* ... */})
-//!          // ^ closure arg
+//!     //      ^ closure arg
 //! }
 //! ```
 //!
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 83ac981429c..8dec8069bc7 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -1151,7 +1151,9 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) {
 
                 parallel!(
                     {
-                        tcx.ensure_ok().check_private_in_public(());
+                        tcx.par_hir_for_each_module(|module| {
+                            tcx.ensure_ok().check_private_in_public(module)
+                        })
                     },
                     {
                         tcx.par_hir_for_each_module(|module| {
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index b1edb5c3044..3b84c6b6110 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -125,6 +125,7 @@ declare_lint_pass! {
         UNSAFE_OP_IN_UNSAFE_FN,
         UNSTABLE_NAME_COLLISIONS,
         UNSTABLE_SYNTAX_PRE_EXPANSION,
+        UNSUPPORTED_CALLING_CONVENTIONS,
         UNUSED_ASSIGNMENTS,
         UNUSED_ASSOCIATED_TYPE_BOUNDS,
         UNUSED_ATTRIBUTES,
diff --git a/compiler/rustc_middle/src/hir/map.rs b/compiler/rustc_middle/src/hir/map.rs
index 3683d1e251c..4370816d38e 100644
--- a/compiler/rustc_middle/src/hir/map.rs
+++ b/compiler/rustc_middle/src/hir/map.rs
@@ -533,8 +533,10 @@ impl<'tcx> TyCtxt<'tcx> {
     /// ```
     /// fn foo(x: usize) -> bool {
     ///     if x == 1 {
-    ///         true  // If `get_fn_id_for_return_block` gets passed the `id` corresponding
-    ///     } else {  // to this, it will return `foo`'s `HirId`.
+    ///         // If `get_fn_id_for_return_block` gets passed the `id` corresponding to this, it
+    ///         // will return `foo`'s `HirId`.
+    ///         true
+    ///     } else {
     ///         false
     ///     }
     /// }
@@ -543,8 +545,10 @@ impl<'tcx> TyCtxt<'tcx> {
     /// ```compile_fail,E0308
     /// fn foo(x: usize) -> bool {
     ///     loop {
-    ///         true  // If `get_fn_id_for_return_block` gets passed the `id` corresponding
-    ///     }         // to this, it will return `None`.
+    ///         // If `get_fn_id_for_return_block` gets passed the `id` corresponding to this, it
+    ///         // will return `None`.
+    ///         true
+    ///     }
     ///     false
     /// }
     /// ```
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index e819aa2d8f8..c55c7fc6002 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -1017,7 +1017,8 @@ pub struct LocalDecl<'tcx> {
     /// ```
     /// fn foo(x: &str) {
     ///     #[allow(unused_mut)]
-    ///     let mut x: u32 = { // <- one unused mut
+    ///     let mut x: u32 = {
+    ///         //^ one unused mut
     ///         let mut y: u32 = x.parse().unwrap();
     ///         y + 2
     ///     };
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index b02433d2feb..2941808e806 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -1390,8 +1390,11 @@ rustc_queries! {
         eval_always
         desc { "checking effective visibilities" }
     }
-    query check_private_in_public(_: ()) {
-        desc { "checking for private elements in public interfaces" }
+    query check_private_in_public(module_def_id: LocalModDefId) {
+        desc { |tcx|
+            "checking for private elements in public interfaces for {}",
+            describe_as_module(module_def_id, tcx)
+        }
     }
 
     query reachable_set(_: ()) -> &'tcx LocalDefIdSet {
diff --git a/compiler/rustc_middle/src/ty/generic_args.rs b/compiler/rustc_middle/src/ty/generic_args.rs
index 7d34d8df3f3..b02abb5ab43 100644
--- a/compiler/rustc_middle/src/ty/generic_args.rs
+++ b/compiler/rustc_middle/src/ty/generic_args.rs
@@ -96,14 +96,12 @@ impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArg
                 signature_parts_ty,
                 tupled_upvars_ty,
                 coroutine_captures_by_ref_ty,
-                coroutine_witness_ty,
             ] => ty::CoroutineClosureArgsParts {
                 parent_args,
                 closure_kind_ty: closure_kind_ty.expect_ty(),
                 signature_parts_ty: signature_parts_ty.expect_ty(),
                 tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
                 coroutine_captures_by_ref_ty: coroutine_captures_by_ref_ty.expect_ty(),
-                coroutine_witness_ty: coroutine_witness_ty.expect_ty(),
             },
             _ => bug!("closure args missing synthetics"),
         }
@@ -111,23 +109,16 @@ impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArg
 
     fn split_coroutine_args(self) -> ty::CoroutineArgsParts<TyCtxt<'tcx>> {
         match self[..] {
-            [
-                ref parent_args @ ..,
-                kind_ty,
-                resume_ty,
-                yield_ty,
-                return_ty,
-                witness,
-                tupled_upvars_ty,
-            ] => ty::CoroutineArgsParts {
-                parent_args,
-                kind_ty: kind_ty.expect_ty(),
-                resume_ty: resume_ty.expect_ty(),
-                yield_ty: yield_ty.expect_ty(),
-                return_ty: return_ty.expect_ty(),
-                witness: witness.expect_ty(),
-                tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
-            },
+            [ref parent_args @ .., kind_ty, resume_ty, yield_ty, return_ty, tupled_upvars_ty] => {
+                ty::CoroutineArgsParts {
+                    parent_args,
+                    kind_ty: kind_ty.expect_ty(),
+                    resume_ty: resume_ty.expect_ty(),
+                    yield_ty: yield_ty.expect_ty(),
+                    return_ty: return_ty.expect_ty(),
+                    tupled_upvars_ty: tupled_upvars_ty.expect_ty(),
+                }
+            }
             _ => bug!("coroutine args missing synthetics"),
         }
     }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 5c44b10ba71..71eac294f15 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -913,9 +913,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                         " yield_ty=",
                         print(args.as_coroutine().yield_ty()),
                         " return_ty=",
-                        print(args.as_coroutine().return_ty()),
-                        " witness=",
-                        print(args.as_coroutine().witness())
+                        print(args.as_coroutine().return_ty())
                     );
                 }
 
@@ -1035,9 +1033,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
                         " upvar_tys=",
                         print(args.as_coroutine_closure().tupled_upvars_ty()),
                         " coroutine_captures_by_ref_ty=",
-                        print(args.as_coroutine_closure().coroutine_captures_by_ref_ty()),
-                        " coroutine_witness_ty=",
-                        print(args.as_coroutine_closure().coroutine_witness_ty())
+                        print(args.as_coroutine_closure().coroutine_captures_by_ref_ty())
                     );
                 }
                 p!("}}");
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index abfe8eb66dd..287639de663 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -87,7 +87,7 @@ mir_build_confused = missing patterns are not covered because `{$variable}` is i
 mir_build_const_continue_bad_const = could not determine the target branch for this `#[const_continue]`
     .label = this value is too generic
 
-mir_build_const_continue_missing_value = a `#[const_continue]` must break to a label with a value
+mir_build_const_continue_missing_label_or_value = a `#[const_continue]` must break to a label with a value
 
 mir_build_const_continue_not_const = could not determine the target branch for this `#[const_continue]`
     .help = try extracting the expression into a `const` item
diff --git a/compiler/rustc_mir_build/src/builder/expr/as_operand.rs b/compiler/rustc_mir_build/src/builder/expr/as_operand.rs
index 982e7aa8246..6a422223990 100644
--- a/compiler/rustc_mir_build/src/builder/expr/as_operand.rs
+++ b/compiler/rustc_mir_build/src/builder/expr/as_operand.rs
@@ -57,7 +57,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// ```
     /// #![feature(unsized_fn_params)]
     /// # use core::fmt::Debug;
-    /// fn foo(_p: dyn Debug) { /* ... */ }
+    /// fn foo(_p: dyn Debug) {
+    ///     /* ... */
+    /// }
     ///
     /// fn bar(box_p: Box<dyn Debug>) { foo(*box_p); }
     /// ```
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index f1fbd5c4a49..1a52c6c85cb 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -1254,8 +1254,8 @@ pub(crate) struct ConstContinueBadConst {
 }
 
 #[derive(Diagnostic)]
-#[diag(mir_build_const_continue_missing_value)]
-pub(crate) struct ConstContinueMissingValue {
+#[diag(mir_build_const_continue_missing_label_or_value)]
+pub(crate) struct ConstContinueMissingLabelOrValue {
     #[primary_span]
     pub span: Span,
 }
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index a0d3913c159..81b0e21a5f5 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -852,9 +852,9 @@ impl<'tcx> ThirBuildCx<'tcx> {
                 if find_attr!(self.tcx.hir_attrs(expr.hir_id), AttributeKind::ConstContinue(_)) {
                     match dest.target_id {
                         Ok(target_id) => {
-                            let Some(value) = value else {
+                            let (Some(value), Some(_)) = (value, dest.label) else {
                                 let span = expr.span;
-                                self.tcx.dcx().emit_fatal(ConstContinueMissingValue { span })
+                                self.tcx.dcx().emit_fatal(ConstContinueMissingLabelOrValue { span })
                             };
 
                             ExprKind::ConstContinue {
diff --git a/compiler/rustc_mir_dataflow/src/impls/initialized.rs b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
index 117525eb777..5937d68f389 100644
--- a/compiler/rustc_mir_dataflow/src/impls/initialized.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/initialized.rs
@@ -108,6 +108,7 @@ impl<'tcx> MaybePlacesSwitchIntData<'tcx> {
 ///
 /// ```rust
 /// struct S;
+/// #[rustfmt::skip]
 /// fn foo(pred: bool) {                        // maybe-init:
 ///                                             // {}
 ///     let a = S; let mut b = S; let c; let d; // {a, b}
@@ -197,6 +198,7 @@ impl<'a, 'tcx> HasMoveData<'tcx> for MaybeInitializedPlaces<'a, 'tcx> {
 ///
 /// ```rust
 /// struct S;
+/// #[rustfmt::skip]
 /// fn foo(pred: bool) {                        // maybe-uninit:
 ///                                             // {a, b, c, d}
 ///     let a = S; let mut b = S; let c; let d; // {      c, d}
@@ -289,6 +291,7 @@ impl<'tcx> HasMoveData<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
 ///
 /// ```rust
 /// struct S;
+/// #[rustfmt::skip]
 /// fn foo(pred: bool) {                        // ever-init:
 ///                                             // {          }
 ///     let a = S; let mut b = S; let c; let d; // {a, b      }
diff --git a/compiler/rustc_mir_transform/src/ctfe_limit.rs b/compiler/rustc_mir_transform/src/ctfe_limit.rs
index fb17cca30f4..ac46336b834 100644
--- a/compiler/rustc_mir_transform/src/ctfe_limit.rs
+++ b/compiler/rustc_mir_transform/src/ctfe_limit.rs
@@ -18,7 +18,7 @@ impl<'tcx> crate::MirPass<'tcx> for CtfeLimit {
             .basic_blocks
             .iter_enumerated()
             .filter_map(|(node, node_data)| {
-                if matches!(node_data.terminator().kind, TerminatorKind::Call { .. })
+                if matches!(node_data.terminator().kind, TerminatorKind::Call { .. } | TerminatorKind::TailCall { .. })
                     // Back edges in a CFG indicate loops
                     || has_back_edge(doms, node, node_data)
                 {
diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs
index df4853c1dcb..4f3c53d761f 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drop.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs
@@ -611,6 +611,7 @@ where
     ///
     /// For example, with 3 fields, the drop ladder is
     ///
+    /// ```text
     /// .d0:
     ///     ELAB(drop location.0 [target=.d1, unwind=.c1])
     /// .d1:
@@ -621,8 +622,10 @@ where
     ///     ELAB(drop location.1 [target=.c2])
     /// .c2:
     ///     ELAB(drop location.2 [target=`self.unwind`])
+    /// ```
     ///
     /// For possible-async drops in coroutines we also need dropline ladder
+    /// ```text
     /// .d0 (mainline):
     ///     ELAB(drop location.0 [target=.d1, unwind=.c1, drop=.e1])
     /// .d1 (mainline):
@@ -637,6 +640,7 @@ where
     ///     ELAB(drop location.1 [target=.e2, unwind=.c2])
     /// .e2 (dropline):
     ///     ELAB(drop location.2 [target=`self.drop`, unwind=`self.unwind`])
+    /// ```
     ///
     /// NOTE: this does not clear the master drop flag, so you need
     /// to point succ/unwind on a `drop_ladder_bottom`.
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
index c0bebdf6fb6..faa86734d08 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
@@ -75,9 +75,16 @@ where
             Ok(ty::Binder::dummy(vec![args.as_coroutine_closure().tupled_upvars_ty()]))
         }
 
-        ty::Coroutine(_, args) => {
+        ty::Coroutine(def_id, args) => {
             let coroutine_args = args.as_coroutine();
-            Ok(ty::Binder::dummy(vec![coroutine_args.tupled_upvars_ty(), coroutine_args.witness()]))
+            Ok(ty::Binder::dummy(vec![
+                coroutine_args.tupled_upvars_ty(),
+                Ty::new_coroutine_witness(
+                    ecx.cx(),
+                    def_id,
+                    ecx.cx().mk_args(coroutine_args.parent_args().as_slice()),
+                ),
+            ]))
         }
 
         ty::CoroutineWitness(def_id, args) => Ok(ecx
@@ -245,7 +252,14 @@ where
             Movability::Movable => {
                 if ecx.cx().features().coroutine_clone() {
                     let coroutine = args.as_coroutine();
-                    Ok(ty::Binder::dummy(vec![coroutine.tupled_upvars_ty(), coroutine.witness()]))
+                    Ok(ty::Binder::dummy(vec![
+                        coroutine.tupled_upvars_ty(),
+                        Ty::new_coroutine_witness(
+                            ecx.cx(),
+                            def_id,
+                            ecx.cx().mk_args(coroutine.parent_args().as_slice()),
+                        ),
+                    ]))
                 } else {
                     Err(NoSolution)
                 }
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 650b85d99d2..31991565b0d 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -229,7 +229,7 @@ where
         }
 
         // We need to make sure to stall any coroutines we are inferring to avoid query cycles.
-        if let Some(cand) = ecx.try_stall_coroutine_witness(goal.predicate.self_ty()) {
+        if let Some(cand) = ecx.try_stall_coroutine(goal.predicate.self_ty()) {
             return cand;
         }
 
@@ -294,7 +294,7 @@ where
         }
 
         // We need to make sure to stall any coroutines we are inferring to avoid query cycles.
-        if let Some(cand) = ecx.try_stall_coroutine_witness(goal.predicate.self_ty()) {
+        if let Some(cand) = ecx.try_stall_coroutine(goal.predicate.self_ty()) {
             return cand;
         }
 
@@ -1432,11 +1432,8 @@ where
         self.merge_trait_candidates(candidates)
     }
 
-    fn try_stall_coroutine_witness(
-        &mut self,
-        self_ty: I::Ty,
-    ) -> Option<Result<Candidate<I>, NoSolution>> {
-        if let ty::CoroutineWitness(def_id, _) = self_ty.kind() {
+    fn try_stall_coroutine(&mut self, self_ty: I::Ty) -> Option<Result<Candidate<I>, NoSolution>> {
+        if let ty::Coroutine(def_id, _) = self_ty.kind() {
             match self.typing_mode() {
                 TypingMode::Analysis {
                     defining_opaque_types_and_generators: stalled_generators,
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index e12e74c0f1a..641815f4d9a 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -1423,8 +1423,6 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
         };
 
         let vis = self.tcx.local_visibility(local_def_id);
-        let span = self.tcx.def_span(self.item_def_id.to_def_id());
-        let vis_span = self.tcx.def_span(def_id);
         if self.in_assoc_ty && !vis.is_at_least(self.required_visibility, self.tcx) {
             let vis_descr = match vis {
                 ty::Visibility::Public => "public",
@@ -1441,6 +1439,8 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
                 }
             };
 
+            let span = self.tcx.def_span(self.item_def_id.to_def_id());
+            let vis_span = self.tcx.def_span(def_id);
             self.tcx.dcx().emit_err(InPublicInterface {
                 span,
                 vis_descr,
@@ -1463,6 +1463,8 @@ impl SearchInterfaceForPrivateItemsVisitor<'_> {
             } else {
                 lint::builtin::PRIVATE_BOUNDS
             };
+            let span = self.tcx.def_span(self.item_def_id.to_def_id());
+            let vis_span = self.tcx.def_span(def_id);
             self.tcx.emit_node_span_lint(
                 lint,
                 self.tcx.local_def_id_to_hir_id(self.item_def_id),
@@ -1594,7 +1596,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
         self.effective_visibilities.effective_vis(def_id).copied()
     }
 
-    fn check_item(&mut self, id: ItemId) {
+    fn check_item(&self, id: ItemId) {
         let tcx = self.tcx;
         let def_id = id.owner_id.def_id;
         let item_visibility = tcx.local_visibility(def_id);
@@ -1722,7 +1724,7 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'_, 'tcx> {
         }
     }
 
-    fn check_foreign_item(&mut self, id: ForeignItemId) {
+    fn check_foreign_item(&self, id: ForeignItemId) {
         let tcx = self.tcx;
         let def_id = id.owner_id.def_id;
         let item_visibility = tcx.local_visibility(def_id);
@@ -1854,16 +1856,12 @@ fn effective_visibilities(tcx: TyCtxt<'_>, (): ()) -> &EffectiveVisibilities {
     tcx.arena.alloc(visitor.effective_visibilities)
 }
 
-fn check_private_in_public(tcx: TyCtxt<'_>, (): ()) {
+fn check_private_in_public(tcx: TyCtxt<'_>, module_def_id: LocalModDefId) {
     let effective_visibilities = tcx.effective_visibilities(());
     // Check for private types in public interfaces.
-    let mut checker = PrivateItemsInPublicInterfacesChecker { tcx, effective_visibilities };
+    let checker = PrivateItemsInPublicInterfacesChecker { tcx, effective_visibilities };
 
-    let crate_items = tcx.hir_crate_items(());
-    for id in crate_items.free_items() {
-        checker.check_item(id);
-    }
-    for id in crate_items.foreign_items() {
-        checker.check_foreign_item(id);
-    }
+    let crate_items = tcx.hir_module_items(module_def_id);
+    let _ = crate_items.par_items(|id| Ok(checker.check_item(id)));
+    let _ = crate_items.par_foreign_items(|id| Ok(checker.check_foreign_item(id)));
 }
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index b14a6edb791..3b57f6e883a 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -801,10 +801,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                     }
                     err.multipart_suggestion(msg, suggestions, applicability);
                 }
-                if let Some(ModuleOrUniformRoot::Module(module)) = module
-                    && let Some(module) = module.opt_def_id()
-                    && let Some(segment) = segment
-                {
+
+                if let Some(segment) = segment {
+                    let module = match module {
+                        Some(ModuleOrUniformRoot::Module(m)) if let Some(id) = m.opt_def_id() => id,
+                        _ => CRATE_DEF_ID.to_def_id(),
+                    };
                     self.find_cfg_stripped(&mut err, &segment, module);
                 }
 
@@ -2839,16 +2841,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
                 continue;
             }
 
-            let note = errors::FoundItemConfigureOut { span: ident.span };
-            err.subdiagnostic(note);
-
-            if let CfgEntry::NameValue { value: Some((feature, _)), .. } = cfg.0 {
-                let note = errors::ItemWasBehindFeature { feature, span: cfg.1 };
-                err.subdiagnostic(note);
+            let item_was = if let CfgEntry::NameValue { value: Some((feature, _)), .. } = cfg.0 {
+                errors::ItemWas::BehindFeature { feature, span: cfg.1 }
             } else {
-                let note = errors::ItemWasCfgOut { span: cfg.1 };
-                err.subdiagnostic(note);
-            }
+                errors::ItemWas::CfgOut { span: cfg.1 }
+            };
+            let note = errors::FoundItemConfigureOut { span: ident.span, item_was };
+            err.subdiagnostic(note);
         }
     }
 }
diff --git a/compiler/rustc_resolve/src/errors.rs b/compiler/rustc_resolve/src/errors.rs
index d6b1e4de6ea..2747ba135ed 100644
--- a/compiler/rustc_resolve/src/errors.rs
+++ b/compiler/rustc_resolve/src/errors.rs
@@ -1,10 +1,13 @@
 use rustc_errors::codes::*;
-use rustc_errors::{Applicability, ElidedLifetimeInPathSubdiag, MultiSpan};
+use rustc_errors::{
+    Applicability, Diag, ElidedLifetimeInPathSubdiag, EmissionGuarantee, IntoDiagArg, MultiSpan,
+    Subdiagnostic,
+};
 use rustc_macros::{Diagnostic, Subdiagnostic};
 use rustc_span::{Ident, Span, Symbol};
 
-use crate::Res;
 use crate::late::PatternSource;
+use crate::{Res, fluent_generated as fluent};
 
 #[derive(Diagnostic)]
 #[diag(resolve_generic_params_from_outer_item, code = E0401)]
@@ -1201,26 +1204,35 @@ pub(crate) struct IdentInScopeButItIsDesc<'a> {
     pub(crate) imported_ident_desc: &'a str,
 }
 
-#[derive(Subdiagnostic)]
-#[note(resolve_found_an_item_configured_out)]
 pub(crate) struct FoundItemConfigureOut {
-    #[primary_span]
-    pub(crate) span: Span,
-}
-
-#[derive(Subdiagnostic)]
-#[note(resolve_item_was_behind_feature)]
-pub(crate) struct ItemWasBehindFeature {
-    pub(crate) feature: Symbol,
-    #[primary_span]
-    pub(crate) span: Span,
-}
-
-#[derive(Subdiagnostic)]
-#[note(resolve_item_was_cfg_out)]
-pub(crate) struct ItemWasCfgOut {
-    #[primary_span]
     pub(crate) span: Span,
+    pub(crate) item_was: ItemWas,
+}
+
+pub(crate) enum ItemWas {
+    BehindFeature { feature: Symbol, span: Span },
+    CfgOut { span: Span },
+}
+
+impl Subdiagnostic for FoundItemConfigureOut {
+    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
+        let mut multispan: MultiSpan = self.span.into();
+        match self.item_was {
+            ItemWas::BehindFeature { feature, span } => {
+                let key = "feature".into();
+                let value = feature.into_diag_arg(&mut None);
+                let msg = diag.dcx.eagerly_translate_to_string(
+                    fluent::resolve_item_was_behind_feature,
+                    [(&key, &value)].into_iter(),
+                );
+                multispan.push_span_label(span, msg);
+            }
+            ItemWas::CfgOut { span } => {
+                multispan.push_span_label(span, fluent::resolve_item_was_cfg_out);
+            }
+        }
+        diag.span_note(multispan, fluent::resolve_found_an_item_configured_out);
+    }
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 261d099abdc..163e4b5b7a9 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -4231,13 +4231,21 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 //
                 // And that's what happens below - we're just mixing both messages
                 // into a single one.
+                let failed_to_resolve = match parent_err.node {
+                    ResolutionError::FailedToResolve { .. } => true,
+                    _ => false,
+                };
                 let mut parent_err = this.r.into_struct_error(parent_err.span, parent_err.node);
 
                 // overwrite all properties with the parent's error message
                 err.messages = take(&mut parent_err.messages);
                 err.code = take(&mut parent_err.code);
                 swap(&mut err.span, &mut parent_err.span);
-                err.children = take(&mut parent_err.children);
+                if failed_to_resolve {
+                    err.children = take(&mut parent_err.children);
+                } else {
+                    err.children.append(&mut parent_err.children);
+                }
                 err.sort_span = parent_err.sort_span;
                 err.is_lint = parent_err.is_lint.clone();
 
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 98e48664e68..236b1404eeb 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -525,9 +525,8 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         }
         self.err_code_special_cases(&mut err, source, path, span);
 
-        if let Some(module) = base_error.module {
-            self.r.find_cfg_stripped(&mut err, &path.last().unwrap().ident.name, module);
-        }
+        let module = base_error.module.unwrap_or_else(|| CRATE_DEF_ID.to_def_id());
+        self.r.find_cfg_stripped(&mut err, &path.last().unwrap().ident.name, module);
 
         (err, candidates)
     }
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 97d1d9c2d2a..19494ffc37e 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -768,7 +768,9 @@ impl SyntaxContext {
     ///
     /// ```rust
     /// #![feature(decl_macro)]
-    /// mod foo { pub fn f() {} } // `f`'s `SyntaxContext` is empty.
+    /// mod foo {
+    ///     pub fn f() {} // `f`'s `SyntaxContext` is empty.
+    /// }
     /// m!(f);
     /// macro m($f:ident) {
     ///     mod bar {
diff --git a/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs
index f7416a7e0fd..1abf0537cda 100644
--- a/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/hexagon_unknown_linux_musl.rs
@@ -7,7 +7,6 @@ pub(crate) fn target() -> Target {
     // FIXME: HVX length defaults are per-CPU
     base.features = "-small-data,+hvx-length128b".into();
 
-    base.crt_static_default = false;
     base.has_rpath = true;
     base.linker_flavor = LinkerFlavor::Unix(Cc::Yes);
 
diff --git a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
index f95ce756354..94ecd3590a9 100644
--- a/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
+++ b/compiler/rustc_target/src/spec/targets/mips64_unknown_linux_muslabi64.rs
@@ -23,8 +23,6 @@ pub(crate) fn target() -> Target {
             abi: "abi64".into(),
             endian: Endian::Big,
             mcount: "_mcount".into(),
-            // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
-            crt_static_default: true,
             llvm_abiname: "n64".into(),
             ..base
         },
diff --git a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs
index 4dc76f0936c..482b6790dad 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc64_unknown_linux_musl.rs
@@ -10,8 +10,6 @@ pub(crate) fn target() -> Target {
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m64"]);
     base.max_atomic_width = Some(64);
     base.stack_probes = StackProbeType::Inline;
-    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
-    base.crt_static_default = true;
     base.abi = "elfv2".into();
     base.llvm_abiname = "elfv2".into();
 
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs
index 316b62d941b..f39142d0101 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_musl.rs
@@ -9,8 +9,6 @@ pub(crate) fn target() -> Target {
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-m32"]);
     base.max_atomic_width = Some(32);
     base.stack_probes = StackProbeType::Inline;
-    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
-    base.crt_static_default = true;
 
     Target {
         llvm_target: "powerpc-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs
index 30d0d9cb60a..8ddb45483b3 100644
--- a/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs
+++ b/compiler/rustc_target/src/spec/targets/powerpc_unknown_linux_muslspe.rs
@@ -9,8 +9,6 @@ pub(crate) fn target() -> Target {
     base.add_pre_link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-mspe"]);
     base.max_atomic_width = Some(32);
     base.stack_probes = StackProbeType::Inline;
-    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
-    base.crt_static_default = true;
 
     Target {
         llvm_target: "powerpc-unknown-linux-muslspe".into(),
diff --git a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
index 938b39b10c6..eb592cca1c8 100644
--- a/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/riscv32gc_unknown_linux_musl.rs
@@ -23,8 +23,6 @@ pub(crate) fn target() -> Target {
             llvm_abiname: "ilp32d".into(),
             max_atomic_width: Some(32),
             supported_split_debuginfo: Cow::Borrowed(&[SplitDebuginfo::Off]),
-            // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
-            crt_static_default: true,
             ..base::linux_musl::opts()
         },
     }
diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
index e9522ac760e..0cdbb626739 100644
--- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
@@ -13,8 +13,6 @@ pub(crate) fn target() -> Target {
     base.stack_probes = StackProbeType::Inline;
     base.supported_sanitizers =
         SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::MEMORY | SanitizerSet::THREAD;
-    // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
-    base.crt_static_default = true;
 
     Target {
         llvm_target: "s390x-unknown-linux-musl".into(),
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs
index 81c502bfead..e026595439f 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7neon_unknown_linux_musleabihf.rs
@@ -27,8 +27,6 @@ pub(crate) fn target() -> Target {
             features: "+v7,+thumb-mode,+thumb2,+vfp3,+neon".into(),
             max_atomic_width: Some(64),
             mcount: "\u{1}mcount".into(),
-            // FIXME(compiler-team#422): musl targets should be dynamically linked by default.
-            crt_static_default: true,
             ..base::linux_musl::opts()
         },
     }
diff --git a/compiler/rustc_thread_pool/src/scope/mod.rs b/compiler/rustc_thread_pool/src/scope/mod.rs
index 38230383965..677009a9bc3 100644
--- a/compiler/rustc_thread_pool/src/scope/mod.rs
+++ b/compiler/rustc_thread_pool/src/scope/mod.rs
@@ -501,9 +501,9 @@ impl<'scope> Scope<'scope> {
     /// let mut value_c = None;
     /// rayon::scope(|s| {
     ///     s.spawn(|s1| {
-    ///           // ^ this is the same scope as `s`; this handle `s1`
-    ///           //   is intended for use by the spawned task,
-    ///           //   since scope handles cannot cross thread boundaries.
+    ///         //   ^ this is the same scope as `s`; this handle `s1`
+    ///         //     is intended for use by the spawned task,
+    ///         //     since scope handles cannot cross thread boundaries.
     ///
     ///         value_a = Some(22);
     ///
diff --git a/compiler/rustc_thread_pool/src/sleep/mod.rs b/compiler/rustc_thread_pool/src/sleep/mod.rs
index 31bf7184b42..aa666609214 100644
--- a/compiler/rustc_thread_pool/src/sleep/mod.rs
+++ b/compiler/rustc_thread_pool/src/sleep/mod.rs
@@ -44,7 +44,7 @@ impl SleepData {
 /// jobs are published, and it either blocks threads or wakes them in response to these
 /// events. See the [`README.md`] in this module for more details.
 ///
-/// [`README.md`] README.md
+/// [`README.md`]: README.md
 pub(super) struct Sleep {
     /// One "sleep state" per worker. Used to track if a worker is sleeping and to have
     /// them block.
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 01bdae7435d..3f628d80662 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -355,7 +355,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for StalledOnCoroutines<'tcx> {
             return ControlFlow::Continue(());
         }
 
-        if let ty::CoroutineWitness(def_id, _) = *ty.kind()
+        if let ty::Coroutine(def_id, _) = *ty.kind()
             && def_id.as_local().is_some_and(|def_id| self.stalled_coroutines.contains(&def_id))
         {
             ControlFlow::Break(())
diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
index 38cfdcdc22d..b1b331d1b61 100644
--- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
@@ -318,7 +318,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
             })
         }
 
-        ty::Coroutine(_, args) => {
+        ty::Coroutine(def_id, args) => {
             // rust-lang/rust#49918: types can be constructed, stored
             // in the interior, and sit idle when coroutine yields
             // (and is subsequently dropped).
@@ -346,7 +346,10 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
             // While we conservatively assume that all coroutines require drop
             // to avoid query cycles during MIR building, we can check the actual
             // witness during borrowck to avoid unnecessary liveness constraints.
-            if args.witness().needs_drop(tcx, tcx.erase_regions(typing_env)) {
+            let typing_env = tcx.erase_regions(typing_env);
+            if tcx.mir_coroutine_witnesses(def_id).is_some_and(|witness| {
+                witness.field_tys.iter().any(|field| field.ty.needs_drop(tcx, typing_env))
+            }) {
                 constraints.outlives.extend(args.upvar_tys().iter().map(ty::GenericArg::from));
                 constraints.outlives.push(args.resume_ty().into());
             }
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 2c7089507a8..62795c8a3a6 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -794,18 +794,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     // The auto impl might apply; we don't know.
                     candidates.ambiguous = true;
                 }
-                ty::Coroutine(coroutine_def_id, _)
-                    if self.tcx().is_lang_item(def_id, LangItem::Unpin) =>
-                {
-                    match self.tcx().coroutine_movability(coroutine_def_id) {
-                        hir::Movability::Static => {
-                            // Immovable coroutines are never `Unpin`, so
-                            // suppress the normal auto-impl candidate for it.
+                ty::Coroutine(coroutine_def_id, _) => {
+                    if self.tcx().is_lang_item(def_id, LangItem::Unpin) {
+                        match self.tcx().coroutine_movability(coroutine_def_id) {
+                            hir::Movability::Static => {
+                                // Immovable coroutines are never `Unpin`, so
+                                // suppress the normal auto-impl candidate for it.
+                            }
+                            hir::Movability::Movable => {
+                                // Movable coroutines are always `Unpin`, so add an
+                                // unconditional builtin candidate with no sub-obligations.
+                                candidates.vec.push(BuiltinCandidate);
+                            }
                         }
-                        hir::Movability::Movable => {
-                            // Movable coroutines are always `Unpin`, so add an
-                            // unconditional builtin candidate.
-                            candidates.vec.push(BuiltinCandidate);
+                    } else {
+                        if self.should_stall_coroutine(coroutine_def_id) {
+                            candidates.ambiguous = true;
+                        } else {
+                            // Coroutines implement all other auto traits normally.
+                            candidates.vec.push(AutoImplCandidate);
                         }
                     }
                 }
@@ -842,12 +849,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     }
                 }
 
-                ty::CoroutineWitness(def_id, _) => {
-                    if self.should_stall_coroutine_witness(def_id) {
-                        candidates.ambiguous = true;
-                    } else {
-                        candidates.vec.push(AutoImplCandidate);
-                    }
+                ty::CoroutineWitness(..) => {
+                    candidates.vec.push(AutoImplCandidate);
                 }
 
                 ty::Bool
@@ -866,7 +869,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 | ty::FnPtr(..)
                 | ty::Closure(..)
                 | ty::CoroutineClosure(..)
-                | ty::Coroutine(..)
                 | ty::Never
                 | ty::Tuple(_)
                 | ty::UnsafeBinder(_) => {
@@ -1153,15 +1155,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ty::Ref(_, _, hir::Mutability::Mut) => {}
 
             ty::Coroutine(coroutine_def_id, args) => {
+                if self.should_stall_coroutine(coroutine_def_id) {
+                    candidates.ambiguous = true;
+                    return;
+                }
+
                 match self.tcx().coroutine_movability(coroutine_def_id) {
                     hir::Movability::Static => {}
                     hir::Movability::Movable => {
                         if self.tcx().features().coroutine_clone() {
                             let resolved_upvars =
                                 self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
-                            let resolved_witness =
-                                self.infcx.shallow_resolve(args.as_coroutine().witness());
-                            if resolved_upvars.is_ty_var() || resolved_witness.is_ty_var() {
+                            if resolved_upvars.is_ty_var() {
                                 // Not yet resolved.
                                 candidates.ambiguous = true;
                             } else {
@@ -1194,12 +1199,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 }
             }
 
-            ty::CoroutineWitness(coroutine_def_id, _) => {
-                if self.should_stall_coroutine_witness(coroutine_def_id) {
-                    candidates.ambiguous = true;
-                } else {
-                    candidates.vec.push(SizedCandidate);
-                }
+            ty::CoroutineWitness(..) => {
+                candidates.vec.push(SizedCandidate);
             }
 
             // Fallback to whatever user-defined impls or param-env clauses exist in this case.
@@ -1238,7 +1239,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             | ty::RawPtr(..)
             | ty::Char
             | ty::Ref(..)
-            | ty::Coroutine(..)
             | ty::Array(..)
             | ty::Closure(..)
             | ty::CoroutineClosure(..)
@@ -1247,14 +1247,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 candidates.vec.push(SizedCandidate);
             }
 
-            ty::CoroutineWitness(coroutine_def_id, _) => {
-                if self.should_stall_coroutine_witness(coroutine_def_id) {
+            ty::Coroutine(coroutine_def_id, _) => {
+                if self.should_stall_coroutine(coroutine_def_id) {
                     candidates.ambiguous = true;
                 } else {
                     candidates.vec.push(SizedCandidate);
                 }
             }
 
+            ty::CoroutineWitness(..) => {
+                candidates.vec.push(SizedCandidate);
+            }
+
             // Conditionally `Sized`.
             ty::Tuple(..) | ty::Pat(..) | ty::Adt(..) | ty::UnsafeBinder(_) => {
                 candidates.vec.push(SizedCandidate);
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index d7c3543cb3f..7ea1548f8f2 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2196,7 +2196,11 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                                 args.as_coroutine()
                                     .upvar_tys()
                                     .iter()
-                                    .chain([args.as_coroutine().witness()])
+                                    .chain([Ty::new_coroutine_witness(
+                                        self.tcx(),
+                                        coroutine_def_id,
+                                        self.tcx().mk_args(args.as_coroutine().parent_args()),
+                                    )])
                                     .collect::<Vec<_>>(),
                             )
                         } else {
@@ -2327,9 +2331,13 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 ty::Binder::dummy(AutoImplConstituents { types: vec![ty], assumptions: vec![] })
             }
 
-            ty::Coroutine(_, args) => {
+            ty::Coroutine(def_id, args) => {
                 let ty = self.infcx.shallow_resolve(args.as_coroutine().tupled_upvars_ty());
-                let witness = args.as_coroutine().witness();
+                let witness = Ty::new_coroutine_witness(
+                    self.tcx(),
+                    def_id,
+                    self.tcx().mk_args(args.as_coroutine().parent_args()),
+                );
                 ty::Binder::dummy(AutoImplConstituents {
                     types: [ty].into_iter().chain(iter::once(witness)).collect(),
                     assumptions: vec![],
@@ -2841,7 +2849,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
         obligations
     }
 
-    fn should_stall_coroutine_witness(&self, def_id: DefId) -> bool {
+    fn should_stall_coroutine(&self, def_id: DefId) -> bool {
         match self.infcx.typing_mode() {
             TypingMode::Analysis { defining_opaque_types_and_generators: stalled_generators } => {
                 def_id.as_local().is_some_and(|def_id| stalled_generators.contains(&def_id))
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index c3b04c20f4b..13d56889bd1 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -101,9 +101,6 @@ fn has_significant_drop_raw<'tcx>(
 struct NeedsDropTypes<'tcx, F> {
     tcx: TyCtxt<'tcx>,
     typing_env: ty::TypingEnv<'tcx>,
-    /// Whether to reveal coroutine witnesses, this is set
-    /// to `false` unless we compute `needs_drop` for a coroutine witness.
-    reveal_coroutine_witnesses: bool,
     query_ty: Ty<'tcx>,
     seen_tys: FxHashSet<Ty<'tcx>>,
     /// A stack of types left to process, and the recursion depth when we
@@ -115,6 +112,15 @@ struct NeedsDropTypes<'tcx, F> {
     adt_components: F,
     /// Set this to true if an exhaustive list of types involved in
     /// drop obligation is requested.
+    // FIXME: Calling this bool `exhaustive` is confusing and possibly a footgun,
+    // since it does two things: It makes the iterator yield *all* of the types
+    // that need drop, and it also affects the computation of the drop components
+    // on `Coroutine`s. The latter is somewhat confusing, and probably should be
+    // a function of `typing_env`. See the HACK comment below for why this is
+    // necessary. If this isn't possible, then we probably should turn this into
+    // a `NeedsDropMode` so that we can have a variant like `CollectAllSignificantDrops`,
+    // which will more accurately indicate that we want *all* of the *significant*
+    // drops, which are the two important behavioral changes toggled by this bool.
     exhaustive: bool,
 }
 
@@ -131,7 +137,6 @@ impl<'tcx, F> NeedsDropTypes<'tcx, F> {
         Self {
             tcx,
             typing_env,
-            reveal_coroutine_witnesses: exhaustive,
             seen_tys,
             query_ty: ty,
             unchecked_tys: vec![(ty, 0)],
@@ -195,23 +200,27 @@ where
                     // for the coroutine witness and check whether any of the contained types
                     // need to be dropped, and only require the captured types to be live
                     // if they do.
-                    ty::Coroutine(_, args) => {
-                        if self.reveal_coroutine_witnesses {
-                            queue_type(self, args.as_coroutine().witness());
+                    ty::Coroutine(def_id, args) => {
+                        // FIXME: See FIXME on `exhaustive` field above.
+                        if self.exhaustive {
+                            for upvar in args.as_coroutine().upvar_tys() {
+                                queue_type(self, upvar);
+                            }
+                            queue_type(self, args.as_coroutine().resume_ty());
+                            if let Some(witness) = tcx.mir_coroutine_witnesses(def_id) {
+                                for field_ty in &witness.field_tys {
+                                    queue_type(
+                                        self,
+                                        EarlyBinder::bind(field_ty.ty).instantiate(tcx, args),
+                                    );
+                                }
+                            }
                         } else {
                             return Some(self.always_drop_component(ty));
                         }
                     }
-                    ty::CoroutineWitness(def_id, args) => {
-                        if let Some(witness) = tcx.mir_coroutine_witnesses(def_id) {
-                            self.reveal_coroutine_witnesses = true;
-                            for field_ty in &witness.field_tys {
-                                queue_type(
-                                    self,
-                                    EarlyBinder::bind(field_ty.ty).instantiate(tcx, args),
-                                );
-                            }
-                        }
+                    ty::CoroutineWitness(..) => {
+                        unreachable!("witness should be handled in parent");
                     }
 
                     ty::UnsafeBinder(bound_ty) => {
diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs
index d7b9e0ca340..23b7f55fbbe 100644
--- a/compiler/rustc_type_ir/src/flags.rs
+++ b/compiler/rustc_type_ir/src/flags.rs
@@ -131,10 +131,7 @@ bitflags::bitflags! {
         /// Does this have any binders with bound vars (e.g. that need to be anonymized)?
         const HAS_BINDER_VARS             = 1 << 23;
 
-        /// Does this type have any coroutine witnesses in it?
-        // FIXME: This should probably be changed to track whether the type has any
-        // *coroutines* in it, though this will happen if we remove coroutine witnesses
-        // altogether.
+        /// Does this type have any coroutines in it?
         const HAS_TY_CORO                 = 1 << 24;
     }
 }
@@ -246,11 +243,13 @@ impl<I: Interner> FlagComputation<I> {
                 self.add_flags(TypeFlags::HAS_TY_PARAM);
             }
 
-            ty::Closure(_, args) | ty::Coroutine(_, args) | ty::CoroutineClosure(_, args) => {
+            ty::Closure(_, args)
+            | ty::CoroutineClosure(_, args)
+            | ty::CoroutineWitness(_, args) => {
                 self.add_args(args.as_slice());
             }
 
-            ty::CoroutineWitness(_, args) => {
+            ty::Coroutine(_, args) => {
                 self.add_flags(TypeFlags::HAS_TY_CORO);
                 self.add_args(args.as_slice());
             }
diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs
index d1ca9bdb7fb..c32f8339d0b 100644
--- a/compiler/rustc_type_ir/src/ty_kind/closure.rs
+++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs
@@ -101,7 +101,6 @@ use crate::{self as ty, Interner};
 ///   `yield` inside the coroutine.
 /// * `GR`: The "return type", which is the type of value returned upon
 ///   completion of the coroutine.
-/// * `GW`: The "coroutine witness".
 #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
 #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
 pub struct ClosureArgs<I: Interner> {
@@ -239,8 +238,6 @@ pub struct CoroutineClosureArgsParts<I: Interner> {
     /// while the `tupled_upvars_ty`, representing the by-move version of the same
     /// captures, will be `(String,)`.
     pub coroutine_captures_by_ref_ty: I::Ty,
-    /// Witness type returned by the generator produced by this coroutine-closure.
-    pub coroutine_witness_ty: I::Ty,
 }
 
 impl<I: Interner> CoroutineClosureArgs<I> {
@@ -251,7 +248,6 @@ impl<I: Interner> CoroutineClosureArgs<I> {
                 parts.signature_parts_ty.into(),
                 parts.tupled_upvars_ty.into(),
                 parts.coroutine_captures_by_ref_ty.into(),
-                parts.coroutine_witness_ty.into(),
             ])),
         }
     }
@@ -292,7 +288,6 @@ impl<I: Interner> CoroutineClosureArgs<I> {
     }
 
     pub fn coroutine_closure_sig(self) -> ty::Binder<I, CoroutineClosureSignature<I>> {
-        let interior = self.coroutine_witness_ty();
         let ty::FnPtr(sig_tys, hdr) = self.signature_parts_ty().kind() else { panic!() };
         sig_tys.map_bound(|sig_tys| {
             let [resume_ty, tupled_inputs_ty] = *sig_tys.inputs().as_slice() else {
@@ -302,7 +297,6 @@ impl<I: Interner> CoroutineClosureArgs<I> {
                 panic!()
             };
             CoroutineClosureSignature {
-                interior,
                 tupled_inputs_ty,
                 resume_ty,
                 yield_ty,
@@ -318,10 +312,6 @@ impl<I: Interner> CoroutineClosureArgs<I> {
         self.split().coroutine_captures_by_ref_ty
     }
 
-    pub fn coroutine_witness_ty(self) -> I::Ty {
-        self.split().coroutine_witness_ty
-    }
-
     pub fn has_self_borrows(&self) -> bool {
         match self.coroutine_captures_by_ref_ty().kind() {
             ty::FnPtr(sig_tys, _) => sig_tys
@@ -361,7 +351,6 @@ impl<I: Interner> TypeVisitor<I> for HasRegionsBoundAt {
 #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)]
 #[derive(TypeVisitable_Generic, TypeFoldable_Generic)]
 pub struct CoroutineClosureSignature<I: Interner> {
-    pub interior: I::Ty,
     pub tupled_inputs_ty: I::Ty,
     pub resume_ty: I::Ty,
     pub yield_ty: I::Ty,
@@ -407,7 +396,6 @@ impl<I: Interner> CoroutineClosureSignature<I> {
                 resume_ty: self.resume_ty,
                 yield_ty: self.yield_ty,
                 return_ty: self.return_ty,
-                witness: self.interior,
                 tupled_upvars_ty,
             },
         );
@@ -587,11 +575,6 @@ pub struct CoroutineArgsParts<I: Interner> {
     pub yield_ty: I::Ty,
     pub return_ty: I::Ty,
 
-    /// The interior type of the coroutine.
-    /// Represents all types that are stored in locals
-    /// in the coroutine's body.
-    pub witness: I::Ty,
-
     /// The upvars captured by the closure. Remains an inference variable
     /// until the upvar analysis, which happens late in HIR typeck.
     pub tupled_upvars_ty: I::Ty,
@@ -607,7 +590,6 @@ impl<I: Interner> CoroutineArgs<I> {
                 parts.resume_ty.into(),
                 parts.yield_ty.into(),
                 parts.return_ty.into(),
-                parts.witness.into(),
                 parts.tupled_upvars_ty.into(),
             ])),
         }
@@ -629,15 +611,6 @@ impl<I: Interner> CoroutineArgs<I> {
         self.split().kind_ty
     }
 
-    /// This describes the types that can be contained in a coroutine.
-    /// It will be a type variable initially and unified in the last stages of typeck of a body.
-    /// It contains a tuple of all the types that could end up on a coroutine frame.
-    /// The state transformation MIR pass may only produce layouts which mention types
-    /// in this tuple. Upvars are not counted here.
-    pub fn witness(self) -> I::Ty {
-        self.split().witness
-    }
-
     /// Returns an iterator over the list of types of captured paths by the coroutine.
     /// In case there was a type error in figuring out the types of the captured path, an
     /// empty iterator is returned.