From 6b30d834725b3e2c2a44236651d1e4db7ba84208 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 15 Jul 2026 15:38:23 +0200 Subject: [PATCH 01/31] Lower #[no_mangle] to #[symbol_name]/#[link_name] This reduces the amount of special casing #[no_mangle] needs in the rest of the compiler. --- .../rustc_codegen_ssa/src/codegen_attrs.rs | 27 ++++++++++++------- .../src/middle/codegen_fn_attrs.rs | 10 +------ compiler/rustc_symbol_mangling/src/lib.rs | 5 ---- src/tools/miri/src/shims/foreign_items.rs | 1 - 4 files changed, 19 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index c3bace9569dd0..803675dd36e4e 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -91,8 +91,11 @@ fn process_builtin_attrs( AttributeKind::LinkSection { name } => codegen_fn_attrs.link_section = Some(*name), AttributeKind::NoMangle(attr_span) => { interesting_spans.no_mangle = Some(*attr_span); - if tcx.opt_item_name(did.to_def_id()).is_some() { - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE; + if let Some(name) = tcx.opt_item_name(did.to_def_id()) { + // Don't override #[link_name] or #[export_name] + if codegen_fn_attrs.symbol_name.is_none() { + codegen_fn_attrs.symbol_name = Some(name); + } } else { tcx.dcx() .span_delayed_bug(*attr_span, "no_mangle should be on a named function"); @@ -393,7 +396,7 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code // import will *still* be mangled despite this. // // if none of the exceptions apply; apply no_mangle - codegen_fn_attrs.flags |= CodegenFnAttrFlags::NO_MANGLE; + codegen_fn_attrs.symbol_name = Some(tcx.item_name(did)); } } } @@ -492,22 +495,24 @@ fn handle_lang_items( // strippable by the linker. // // Additionally weak lang items have predetermined symbol names. - if let Some(lang_item) = lang_item + let link_name_override = if let Some(lang_item) = lang_item && let Some(link_name) = lang_item.link_name() { codegen_fn_attrs.flags |= CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL; - codegen_fn_attrs.symbol_name = Some(link_name); - } + Some(link_name) + } else { + None + }; - // error when using no_mangle on a lang item item + // error when using no_mangle, or export_name on a lang item item if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) - && codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) + && codegen_fn_attrs.symbol_name.is_some() { let mut err = tcx .dcx() .struct_span_err( interesting_spans.no_mangle.unwrap_or_default(), - "`#[no_mangle]` cannot be used on internal language items", + "`#[no_mangle]` and `#[export_name]` cannot be used on internal language items", ) .with_note("Rustc requires this item to have a specific mangled name.") .with_span_label(tcx.def_span(did), "should be the internal language item"); @@ -523,6 +528,10 @@ fn handle_lang_items( } err.emit(); } + + if let Some(link_name_override) = link_name_override { + codegen_fn_attrs.symbol_name = Some(link_name_override); + } } /// Generate the [`CodegenFnAttrs`] for an item (identified by the [`LocalDefId`]). diff --git a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs index fc5345b0b0b92..b10ce28446c76 100644 --- a/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs +++ b/compiler/rustc_middle/src/middle/codegen_fn_attrs.rs @@ -38,10 +38,6 @@ impl<'tcx> TyCtxt<'tcx> { if let InstanceKind::Shim(ShimKind::Reify(_, _)) = instance_kind && attrs.flags.contains(CodegenFnAttrFlags::TRACK_CALLER) { - if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { - attrs.to_mut().flags.remove(CodegenFnAttrFlags::NO_MANGLE); - } - if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) { attrs.to_mut().flags.remove(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL); } @@ -189,9 +185,6 @@ bitflags::bitflags! { /// `#[naked]`: an indicator to LLVM that no function prologue/epilogue /// should be generated. const NAKED = 1 << 2; - /// `#[no_mangle]`: an indicator that the function's name should be the same - /// as its symbol. - const NO_MANGLE = 1 << 3; /// `#[rustc_std_internal_symbol]`: an indicator that this symbol is a /// "weird symbol" for the standard library in that it has slightly /// different linkage, visibility, and reachability rules. @@ -278,8 +271,7 @@ impl CodegenFnAttrs { return false; } - self.flags.contains(CodegenFnAttrFlags::NO_MANGLE) - || self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) + self.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) // note: for these we do also set a symbol name so technically also handled by the // condition below. However, I think that regardless these should be treated as extern. || self.flags.contains(CodegenFnAttrFlags::EXTERNALLY_IMPLEMENTABLE_ITEM) diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 9c465b409ca85..0e56ad0edab23 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -240,11 +240,6 @@ pub fn symbol_name_from_attrs<'tcx>( // Use provided name return Some(name.to_string()); } - - if attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) { - // Don't mangle - return Some(tcx.item_name(def_id).to_string()); - } } None diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs index e67dbc0e8e87d..6d080dbe60dfe 100644 --- a/src/tools/miri/src/shims/foreign_items.rs +++ b/src/tools/miri/src/shims/foreign_items.rs @@ -139,7 +139,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let attrs = tcx.codegen_fn_attrs(def_id); // Skip over items without an explicitly defined symbol name. if !(attrs.symbol_name.is_some() - || attrs.flags.contains(CodegenFnAttrFlags::NO_MANGLE) || attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)) { return interp_ok(()); From f141419edbe495111b366287e5745b24e3bbbfae Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 16 Jul 2026 15:30:10 +0200 Subject: [PATCH 02/31] Fix clashing_extern_declarations lint --- compiler/rustc_lint/src/foreign_modules.rs | 52 ++++++++-------------- 1 file changed, 18 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs index e6092a1497a0f..3ac25edbc9892 100644 --- a/compiler/rustc_lint/src/foreign_modules.rs +++ b/compiler/rustc_lint/src/foreign_modules.rs @@ -76,23 +76,11 @@ struct ClashingExternDeclarations { seen_decls: UnordMap, } -/// Differentiate between whether the name for an extern decl came from the link_name attribute or -/// just from declaration itself. This is important because we don't want to report clashes on -/// symbol name if they don't actually clash because one or the other links against a symbol with a -/// different name. -enum SymbolName { - /// The name of the symbol + the span of the annotation which introduced the link name. - Link(Symbol, Span), - /// No link name, so just the name of the symbol. - Normal(Symbol), -} - -impl SymbolName { - fn get_name(&self) -> Symbol { - match self { - SymbolName::Link(s, _) | SymbolName::Normal(s) => *s, - } - } +struct SymbolName { + /// The name of the symbol that will be linked against. + link_name: Symbol, + /// The span of the annotation which introduced the link name. + span: Option, } impl ClashingExternDeclarations { @@ -139,7 +127,7 @@ impl ClashingExternDeclarations { // Finally, emit the diagnostic. let this = tcx.item_name(this_fi.owner_id.to_def_id()); - let orig = orig.get_name(); + let orig = orig.link_name; let previous_decl_label = get_relevant_span(tcx, existing_did); let mismatch_label = get_relevant_span(tcx, this_fi.owner_id); let sub = @@ -175,28 +163,24 @@ impl ClashingExternDeclarations { /// the name specified in a #[link_name = ...] attribute if one was specified, else, just the /// symbol's name. fn name_of_extern_decl(tcx: TyCtxt<'_>, fi: hir::OwnerId) -> SymbolName { - if let Some((overridden_link_name, overridden_link_name_span)) = - tcx.codegen_fn_attrs(fi).symbol_name.map(|overridden_link_name| { - // FIXME: Instead of searching through the attributes again to get span - // information, we could have codegen_fn_attrs also give span information back for - // where the attribute was defined. However, until this is found to be a - // bottleneck, this does just fine. - (overridden_link_name, find_attr!(tcx, fi, LinkName {span, ..} => *span).unwrap()) - }) - { - SymbolName::Link(overridden_link_name, overridden_link_name_span) - } else { - SymbolName::Normal(tcx.item_name(fi.to_def_id())) + // FIXME if symbol_name is not set, this is likely a #[rustc_std_internal_symbol] or EII which + // actually have their name mangled and thus should use the mangled name here. + let link_name = + tcx.codegen_fn_attrs(fi).symbol_name.unwrap_or_else(|| tcx.item_name(fi.to_def_id())); + SymbolName { + link_name, + // FIXME: Instead of searching through the attributes again to get span + // information, we could have codegen_fn_attrs also give span information back for + // where the attribute was defined. However, until this is found to be a + // bottleneck, this does just fine. + span: find_attr!(tcx, fi, LinkName {span, ..} => *span), } } /// We want to ensure that we use spans for both decls that include where the /// name was defined, whether that was from the link_name attribute or not. fn get_relevant_span(tcx: TyCtxt<'_>, fi: hir::OwnerId) -> Span { - match name_of_extern_decl(tcx, fi) { - SymbolName::Normal(_) => tcx.def_span(fi), - SymbolName::Link(_, annot_span) => annot_span, - } + if let Some(span) = name_of_extern_decl(tcx, fi).span { span } else { tcx.def_span(fi) } } /// Checks whether two types are structurally the same enough that the declarations shouldn't From 4d5eb5809283c838f910082b41f9dfd8cec0075c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 16 Jul 2026 16:21:10 +0200 Subject: [PATCH 03/31] Bless several tests --- tests/ui/codegen/no-mangle-on-internal-lang-items.rs | 10 +++------- .../ui/codegen/no-mangle-on-internal-lang-items.stderr | 6 +++--- tests/ui/codegen/no-mangle-on-panic-handler.rs | 4 ++-- tests/ui/codegen/no-mangle-on-panic-handler.stderr | 2 +- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/tests/ui/codegen/no-mangle-on-internal-lang-items.rs b/tests/ui/codegen/no-mangle-on-internal-lang-items.rs index 37766936410ed..58a03f04554f6 100644 --- a/tests/ui/codegen/no-mangle-on-internal-lang-items.rs +++ b/tests/ui/codegen/no-mangle-on-internal-lang-items.rs @@ -4,11 +4,7 @@ #![feature(rustc_attrs)] #[rustc_std_internal_symbol] -#[unsafe(no_mangle)] //~ERROR `#[no_mangle]` cannot be used on internal language items -fn internal_lang_function () { +#[unsafe(no_mangle)] //~ERROR `#[no_mangle]` and `#[export_name]` cannot be used on internal language items +fn internal_lang_function() {} -} - -fn main() { - -} +fn main() {} diff --git a/tests/ui/codegen/no-mangle-on-internal-lang-items.stderr b/tests/ui/codegen/no-mangle-on-internal-lang-items.stderr index 12461a6abb964..a02111673309c 100644 --- a/tests/ui/codegen/no-mangle-on-internal-lang-items.stderr +++ b/tests/ui/codegen/no-mangle-on-internal-lang-items.stderr @@ -1,10 +1,10 @@ -error: `#[no_mangle]` cannot be used on internal language items +error: `#[no_mangle]` and `#[export_name]` cannot be used on internal language items --> $DIR/no-mangle-on-internal-lang-items.rs:7:1 | LL | #[unsafe(no_mangle)] | ^^^^^^^^^^^^^^^^^^^^ -LL | fn internal_lang_function () { - | ---------------------------- should be the internal language item +LL | fn internal_lang_function() {} + | --------------------------- should be the internal language item | = note: Rustc requires this item to have a specific mangled name. diff --git a/tests/ui/codegen/no-mangle-on-panic-handler.rs b/tests/ui/codegen/no-mangle-on-panic-handler.rs index 4ef9fd2b8d372..33ec6289b870f 100644 --- a/tests/ui/codegen/no-mangle-on-panic-handler.rs +++ b/tests/ui/codegen/no-mangle-on-panic-handler.rs @@ -1,13 +1,13 @@ // Issue an error when the user uses #[no_mangle] on the panic handler //@ edition:2024 -#![crate_type="lib"] +#![crate_type = "lib"] #![no_std] #![no_main] use core::panic::PanicInfo; -#[unsafe(no_mangle)] //~ ERROR `#[no_mangle]` cannot be used on internal language items +#[unsafe(no_mangle)] //~ ERROR `#[no_mangle]` and `#[export_name]` cannot be used on internal language items #[panic_handler] pub fn panic_fmt(pi: &PanicInfo) -> ! { loop {} diff --git a/tests/ui/codegen/no-mangle-on-panic-handler.stderr b/tests/ui/codegen/no-mangle-on-panic-handler.stderr index 46cf8e8aec5e9..a0036d48f1ee0 100644 --- a/tests/ui/codegen/no-mangle-on-panic-handler.stderr +++ b/tests/ui/codegen/no-mangle-on-panic-handler.stderr @@ -1,4 +1,4 @@ -error: `#[no_mangle]` cannot be used on internal language items +error: `#[no_mangle]` and `#[export_name]` cannot be used on internal language items --> $DIR/no-mangle-on-panic-handler.rs:10:1 | LL | #[unsafe(no_mangle)] From 23a3f188ddfada9b65b7010700a1eae0a9071a20 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 16 Jul 2026 16:29:41 +0200 Subject: [PATCH 04/31] Disable symbol name mangling for #[link_ordinal] #[link_ordinal] is not compatible with #[link_name] and items in extern blocks now have an implicit #[link_name] with the item name. Alternatively it would be possible to suppress the error message for this implicit #[link_name]. --- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 803675dd36e4e..68e8484b13b6c 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -388,6 +388,8 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code // get the same symbol name as the *mangled* foreign item they refer to so that's all good. } else if codegen_fn_attrs.symbol_name.is_some() { // * This can be overridden with the `#[link_name]` attribute + } else if codegen_fn_attrs.link_ordinal.is_some() { + // * `#[link_ordinal]` and `#[link_name]` are incompatible with each other } else { // NOTE: there's one more exception that we cannot apply here. On wasm, // some items cannot be `no_mangle`. From 3bc2932416aa8c8f2aee5005077446c1923ef82d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 20 Aug 2026 13:00:22 +0200 Subject: [PATCH 05/31] Add explanation why #[no_mangle] + #[link_name] matters --- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 68e8484b13b6c..bfe3c93b46c64 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -92,7 +92,15 @@ fn process_builtin_attrs( AttributeKind::NoMangle(attr_span) => { interesting_spans.no_mangle = Some(*attr_span); if let Some(name) = tcx.opt_item_name(did.to_def_id()) { - // Don't override #[link_name] or #[export_name] + // Don't override #[export_name]. + + // Also don't override #[link_name]. All places where #[link_name] is allowed + // shouldn't allow #[no_mangle], so #[link_name] shouldn't be a concern here, + // however currently #[no_mangle] is currently merely a warning on foreign + // items rather than a hard error, so we still need to take #[no_mangle] + + // #[link_name] into account. + // FIXME remove this comment once #[no_mangle] on foreign items is a hard error. + if codegen_fn_attrs.symbol_name.is_none() { codegen_fn_attrs.symbol_name = Some(name); } From 2c2e988c09de7a3bf4c53fda872f2453611b0d61 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 9 Oct 2026 11:49:26 +0200 Subject: [PATCH 06/31] Clarify comment --- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index bfe3c93b46c64..91e2e233d80a0 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -397,7 +397,9 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code } else if codegen_fn_attrs.symbol_name.is_some() { // * This can be overridden with the `#[link_name]` attribute } else if codegen_fn_attrs.link_ordinal.is_some() { - // * `#[link_ordinal]` and `#[link_name]` are incompatible with each other + // * `#[link_ordinal]` and `#[link_name]` are incompatible with each other, so + // disable the implicit `#[link_name]` for foreign items below to avoid a + // error. } else { // NOTE: there's one more exception that we cannot apply here. On wasm, // some items cannot be `no_mangle`. From d79c1097e1e8eef131c993a4b17bb324c850df6d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 9 Oct 2026 15:47:23 +0200 Subject: [PATCH 07/31] Apply comment wording suggestions by Ralf Co-authored-by: Ralf Jung --- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index 91e2e233d80a0..a672d4afe2dd0 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -380,6 +380,8 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code } // Foreign items by default use no mangling for their symbol name. + // Usually, `symbol_name` is controlled by `#[link_name]`/`#[export_name]`. Here we additionally + // set `symbol_name` on most foreign items so that their their symbol name does not get mangled. if tcx.is_foreign_item(did) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::FOREIGN_ITEM; @@ -395,12 +397,13 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code // Implementing an EII does the appropriate name resolution to make sure the implementations // get the same symbol name as the *mangled* foreign item they refer to so that's all good. } else if codegen_fn_attrs.symbol_name.is_some() { - // * This can be overridden with the `#[link_name]` attribute + // * If the name is already set by `#[link_name]`, we don't overwrite it. } else if codegen_fn_attrs.link_ordinal.is_some() { // * `#[link_ordinal]` and `#[link_name]` are incompatible with each other, so - // disable the implicit `#[link_name]` for foreign items below to avoid a + // disable the implicit `#[link_name]` for foreign items below to avoid an // error. } else { + // This effectively adds an implicit `#[link_name = ""]`. // NOTE: there's one more exception that we cannot apply here. On wasm, // some items cannot be `no_mangle`. // However, we don't have enough information here to determine that. From 11a8eaf3783b835e874529c9d0db17c27f2da7b7 Mon Sep 17 00:00:00 2001 From: lapla Date: Tue, 3 Nov 2026 16:24:26 +0900 Subject: [PATCH 08/31] Accept variadic SysV64, Win64, and Aapcs FnAbis in rustc_public --- .../src/unstable/convert/stable/abi.rs | 10 +++++- tests/ui-fulldeps/rustc_public/check_abi.rs | 31 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_public/src/unstable/convert/stable/abi.rs b/compiler/rustc_public/src/unstable/convert/stable/abi.rs index a5e7302e9a4c7..c3512bb69730d 100644 --- a/compiler/rustc_public/src/unstable/convert/stable/abi.rs +++ b/compiler/rustc_public/src/unstable/convert/stable/abi.rs @@ -90,7 +90,15 @@ impl<'tcx> Stable<'tcx> for callconv::FnAbi<'tcx, ty::Ty<'tcx>> { cx: &CompilerCtxt<'cx, BridgeTys>, ) -> Self::T { assert!(self.args.len() >= self.fixed_count as usize); - assert!(!self.c_variadic || matches!(self.conv, CanonAbi::C)); + assert!( + !self.c_variadic + || matches!( + self.conv, + CanonAbi::C + | CanonAbi::X86(X86Call::SysV64 | X86Call::Win64) + | CanonAbi::Arm(ArmCall::Aapcs) + ) + ); FnAbi { args: self.args.as_ref().stable(tables, cx), ret: self.ret.stable(tables, cx), diff --git a/tests/ui-fulldeps/rustc_public/check_abi.rs b/tests/ui-fulldeps/rustc_public/check_abi.rs index c394e05e76fbb..0b2a741c3731a 100644 --- a/tests/ui-fulldeps/rustc_public/check_abi.rs +++ b/tests/ui-fulldeps/rustc_public/check_abi.rs @@ -58,6 +58,12 @@ fn test_stable_mir() -> ControlFlow<()> { .expect("Expected variadic_fn function"); check_variadic(variadic_fn); + #[cfg(target_arch = "x86_64")] + { + check_variadic_conv(&items, "input::sysv64_variadic", CallConvention::X86_64SysV); + check_variadic_conv(&items, "input::win64_variadic", CallConvention::X86_64Win64); + } + // Extract function pointers. let fn_ptr_holder = *get_item(&items, (ItemKind::Fn, "input::fn_ptr_holder")) .expect("Expected fn_ptr_holder function"); @@ -286,9 +292,22 @@ fn check_variadic(variadic_fn: CrateItem) { let instance = Instance::try_from(variadic_fn).expect("Expected variadic_fn instance"); let abi = instance.fn_abi().expect("Expected function ABI"); assert!(abi.c_variadic, "Expected C variadic function"); + assert_eq!(abi.conv, CallConvention::C, "Expected C calling convention"); assert_eq!(abi.args.len(), 1, "Expected one fixed variadic argument"); } +/// Check a variadic definition whose calling convention is not `extern "C"`. +#[cfg(target_arch = "x86_64")] +fn check_variadic_conv(items: &CrateItems, name: &str, conv: CallConvention) { + let item = *get_item(items, (ItemKind::Fn, name)).expect(name); + let instance = Instance::try_from(item).expect(name); + let abi = instance.fn_abi().expect(name); + assert!(abi.c_variadic, "{}", name); + assert_eq!(abi.conv, conv, "{}", name); + assert_eq!(abi.args.len(), 1, "{}", name); + assert_eq!(abi.fixed_count, 1, "{}", name); +} + /// Check the argument to be ignored: `ignore: [u8; 0]`. fn check_ignore(abi: &ArgAbi) { assert!(abi.ty.kind().is_array(), "Expected array argument"); @@ -450,6 +469,18 @@ fn generate_input(path: &str) -> std::io::Result<()> { 0 }} + #[cfg(target_arch = "x86_64")] + #[unsafe(naked)] + pub unsafe extern "sysv64" fn sysv64_variadic(_: u32, _: ...) -> u32 {{ + core::arch::naked_asm!("ret") + }} + + #[cfg(target_arch = "x86_64")] + #[unsafe(naked)] + pub unsafe extern "win64" fn win64_variadic(_: u32, _: ...) -> u32 {{ + core::arch::naked_asm!("ret") + }} + pub type ComplexFn = fn([u8; 0], char, NonZero) -> Result; pub type VariadicFn = unsafe extern "C" fn(usize, ...) -> usize; From 460bb55b4e96ed767bed433799078a0492526016 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 3 Nov 2026 18:00:00 +0100 Subject: [PATCH 09/31] Review comments --- compiler/rustc_codegen_ssa/src/codegen_attrs.rs | 2 +- compiler/rustc_symbol_mangling/src/lib.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs index a672d4afe2dd0..ff18ce34c52f3 100644 --- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs +++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs @@ -410,7 +410,7 @@ fn apply_overrides(tcx: TyCtxt<'_>, did: LocalDefId, codegen_fn_attrs: &mut Code // As such, no_mangle foreign items on wasm that have the same defid as some // import will *still* be mangled despite this. // - // if none of the exceptions apply; apply no_mangle + // if none of the exceptions apply; do not mangle the symbol name codegen_fn_attrs.symbol_name = Some(tcx.item_name(did)); } } diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs index 0e56ad0edab23..82732ef7f43b4 100644 --- a/compiler/rustc_symbol_mangling/src/lib.rs +++ b/compiler/rustc_symbol_mangling/src/lib.rs @@ -182,7 +182,6 @@ pub fn symbol_name_from_attrs<'tcx>( } } - // FIXME(eddyb) Precompute a custom symbol name based on attributes. let attrs = if tcx.def_kind(def_id).has_codegen_attrs() { &tcx.codegen_instance_attrs(instance_kind) } else { From b4b982c32fcc070131910d286d9efc3b7a6744ca Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 5 Nov 2026 13:33:48 +0100 Subject: [PATCH 10/31] Use symbol name in build_dll_import This ensures the name it is referenced with from object files matches the name that it is imported as in an import library. --- compiler/rustc_metadata/src/native_libs.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs index 6cb6ad0015f92..e2a024e4834e5 100644 --- a/compiler/rustc_metadata/src/native_libs.rs +++ b/compiler/rustc_metadata/src/native_libs.rs @@ -293,10 +293,9 @@ impl<'tcx> Collector<'tcx> { .link_ordinal .map_or(import_name_type, |ord| Some(PeImportNameType::Ordinal(ord))); - let name = codegen_fn_attrs.symbol_name.unwrap_or_else(|| self.tcx.item_name(item)); + let name = self.tcx.symbol_name(ty::Instance::mono(self.tcx, item)).name; if self.tcx.sess.target.binary_format == BinaryFormat::Elf { - let name = name.as_str(); if name.contains('\0') { self.tcx.dcx().emit_err(diagnostics::RawDylibMalformed { span }); } else if let Some((left, right)) = name.split_once('@') @@ -334,6 +333,13 @@ impl<'tcx> Collector<'tcx> { } }; - Some(DllImport { name, import_name_type, calling_convention, span, symbol_type, size }) + Some(DllImport { + name: Symbol::intern(name), + import_name_type, + calling_convention, + span, + symbol_type, + size, + }) } } From 4400802c4e7ad1fe5d1efd2aa5687b45dea03a0b Mon Sep 17 00:00:00 2001 From: Nia Deckers Date: Mon, 15 Jun 2026 16:08:39 +0200 Subject: [PATCH 11/31] fallible type ops --- .../src/type_check/canonical.rs | 36 ++++++ compiler/rustc_borrowck/src/type_check/mod.rs | 16 ++- compiler/rustc_infer/src/traits/engine.rs | 14 ++- compiler/rustc_infer/src/traits/mod.rs | 4 +- .../rustc_middle/src/ty/typeck_results.rs | 2 +- .../src/traits/engine.rs | 6 +- .../rustc_trait_selection/src/traits/mod.rs | 7 ++ .../src/traits/query/type_op/custom.rs | 109 ++++++++++++++---- .../src/traits/query/type_op/mod.rs | 82 ++++++++----- 9 files changed, 216 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_borrowck/src/type_check/canonical.rs b/compiler/rustc_borrowck/src/type_check/canonical.rs index b295a66ee74ee..f435b08a2aa8a 100644 --- a/compiler/rustc_borrowck/src/type_check/canonical.rs +++ b/compiler/rustc_borrowck/src/type_check/canonical.rs @@ -3,11 +3,13 @@ use std::fmt; use rustc_errors::ErrorGuaranteed; use rustc_infer::infer::canonical::Canonical; use rustc_infer::infer::outlives::env::RegionBoundPairs; +use rustc_infer::traits::Obligation; use rustc_middle::mir::{Body, ConstraintCategory}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, Unnormalized, Upcast}; use rustc_span::def_id::DefId; use rustc_span::{Span, bug}; use rustc_trait_selection::traits::ObligationCause; +use rustc_trait_selection::traits::query::type_op::custom::FallibleCustomTypeOp; use rustc_trait_selection::traits::query::type_op::{self, TypeOpOutput}; use tracing::{debug, instrument}; @@ -165,6 +167,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { } } + /// Proves and asserts that a predicate holds. + /// Errors may be emitted that are only dependent on region constraints. + /// However, errors that are not dependent on region constraints are emitted as a delayed bug, + /// since those should have already been emitted earlier in the compiler. + /// If this is undesirable and errors should be emitted properly, + /// use [`prove_fallible_predicate`](Self::prove_fallible_predicate). #[instrument(skip(self), level = "debug")] pub(super) fn prove_clause( &mut self, @@ -182,6 +190,34 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { ); } + /// Certain proofs (e.g. `Move`) may error during MIR typeck for reasons that + /// are unrelated to regions. Unlike [`prove_clause`](Self::prove_clause), + /// this API reports those errors properly. + #[allow(unused)] + pub(super) fn prove_fallible_predicate( + &mut self, + predicate: impl Upcast, ty::Predicate<'tcx>> + std::fmt::Debug, + locations: Locations, + category: ConstraintCategory<'tcx>, + ) { + let span = self.last_span; + let predicate = predicate.upcast(self.tcx()); + let op = FallibleCustomTypeOp::new( + |ocx| { + ocx.register_obligation(Obligation::new( + ocx.infcx.tcx, + ObligationCause::dummy_with_span(span), + self.infcx.param_env, + predicate, + )); + Ok(()) + }, + "fallible type op", + ); + + let _: Result<_, ErrorGuaranteed> = self.fully_perform_op(locations, category, op); + } + pub(super) fn normalize( &mut self, value: Unnormalized<'tcx, T>, diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs index 900b417f8626f..feadba1b7221e 100644 --- a/compiler/rustc_borrowck/src/type_check/mod.rs +++ b/compiler/rustc_borrowck/src/type_check/mod.rs @@ -18,7 +18,7 @@ use rustc_infer::infer::region_constraints::RegionConstraintData; use rustc_infer::infer::{ BoundRegionConversionTime, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, }; -use rustc_infer::traits::{Obligation, ObligationCause, PredicateObligations}; +use rustc_infer::traits::{Obligation, ObligationCause, PredicateObligations, ScrubbedTraitError}; use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::traits::query::NoSolution; @@ -2800,10 +2800,16 @@ impl<'tcx> TypeOp<'tcx> for InstantiateOpaqueType<'tcx> { span: Span, ) -> Result, ErrorGuaranteed> { let (mut output, region_constraints) = - scrape_region_constraints(infcx, root_def_id, "InstantiateOpaqueType", span, |ocx| { - ocx.register_obligations(self.obligations.clone()); - Ok(()) - })?; + scrape_region_constraints::<_, _, ScrubbedTraitError<'tcx>>( + infcx, + root_def_id, + "InstantiateOpaqueType", + span, + |ocx| { + ocx.register_obligations(self.obligations.clone()); + Ok(()) + }, + )?; self.region_constraints = Some(region_constraints); output.error_info = Some(self); Ok(output) diff --git a/compiler/rustc_infer/src/traits/engine.rs b/compiler/rustc_infer/src/traits/engine.rs index 5ee2d8992b773..a43470f61b586 100644 --- a/compiler/rustc_infer/src/traits/engine.rs +++ b/compiler/rustc_infer/src/traits/engine.rs @@ -34,6 +34,14 @@ impl<'tcx> ScrubbedTraitError<'tcx> { } } +impl<'tcx> EngineError<'tcx> for ScrubbedTraitError<'tcx> { + fn try_report_errors(_infcx: &InferCtxt<'tcx>, _errors: ThinVec) { + // Since `ScrubbedtraitError`s don't actually care about *what* error occurred, + // there's nothing to report. This function is used in the results of fallible + // queries to the trait solver such as `impl EngineError for FulfillmentError {}` + } +} + #[derive(Debug, Clone)] #[must_use] pub enum TraitErrors { @@ -228,6 +236,10 @@ pub trait TraitEngine<'tcx, E: 'tcx>: 'tcx { ) -> PredicateObligations<'tcx>; } -pub trait FromSolverError<'tcx, E>: Debug + 'tcx { +pub trait EngineError<'tcx>: Sized + 'tcx { + fn try_report_errors(infcx: &InferCtxt<'tcx>, errors: ThinVec); +} + +pub trait FromSolverError<'tcx, E>: EngineError<'tcx> + Debug { fn from_solver_error(infcx: &InferCtxt<'tcx>, error: E) -> Self; } diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs index b3552bc68d517..b49b58d122422 100644 --- a/compiler/rustc_infer/src/traits/mod.rs +++ b/compiler/rustc_infer/src/traits/mod.rs @@ -20,7 +20,9 @@ use rustc_middle::ty::{self, Ty, TyCtxt, Upcast}; use rustc_span::Span; use thin_vec::ThinVec; -pub use self::engine::{FromSolverError, ScrubbedTraitError, TraitEngine, TraitErrors}; +pub use self::engine::{ + EngineError, FromSolverError, ScrubbedTraitError, TraitEngine, TraitErrors, +}; pub(crate) use self::project::UndoLog; pub use self::project::{ MismatchedProjectionTypes, Normalized, NormalizedTerm, ProjectionCache, ProjectionCacheEntry, diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs index dcb3f1010d299..d2c724ffc06da 100644 --- a/compiler/rustc_middle/src/ty/typeck_results.rs +++ b/compiler/rustc_middle/src/ty/typeck_results.rs @@ -206,7 +206,7 @@ pub struct TypeckResults<'tcx> { /// Goals proven during HIR typeck which may be potentially region dependent. /// - /// Borrowck *uniquifies* regions which may cause these goal to be ambiguous in MIR + /// Borrowck *uniquifies* regions which may cause these goals to be ambiguous in MIR /// type check. We ICE if goals fail in borrowck to detect bugs during MIR building or /// missed checks in HIR typeck. To avoid ICE due to region dependence we store all /// goals which may be region dependent and reprove them in case borrowck encounters diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs index a2afa9faea97f..26d35e5bf4f6e 100644 --- a/compiler/rustc_trait_selection/src/traits/engine.rs +++ b/compiler/rustc_trait_selection/src/traits/engine.rs @@ -400,10 +400,14 @@ impl<'tcx> ObligationCtxt<'_, 'tcx, ScrubbedTraitError<'tcx>> { } } -impl<'tcx, E> ObligationCtxt<'_, 'tcx, E> +impl<'a, 'tcx, E> ObligationCtxt<'a, 'tcx, E> where E: FromSolverError<'tcx, NextSolverError<'tcx>> + FromSolverError<'tcx, OldSolverError<'tcx>>, { + pub fn new_raw(infcx: &'a InferCtxt<'tcx>) -> Self { + Self { infcx, engine: RefCell::new(FulfillmentEngine::new(infcx)) } + } + pub fn assumed_wf_types( &self, param_env: ty::ParamEnv<'tcx>, diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 326710007564c..decb2bcd6dd11 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -38,6 +38,7 @@ use rustc_middle::ty::{ }; use rustc_span::Span; use rustc_span::def_id::DefId; +use thin_vec::ThinVec; use tracing::{debug, instrument}; pub use self::coherence::{ @@ -108,6 +109,12 @@ impl<'tcx> FulfillmentError<'tcx> { } } +impl<'tcx> EngineError<'tcx> for FulfillmentError<'tcx> { + fn try_report_errors(infcx: &InferCtxt<'tcx>, errors: ThinVec) { + infcx.err_ctxt().report_fulfillment_errors(errors); + } +} + #[derive(Clone, TypeVisitable)] pub enum FulfillmentErrorCode<'tcx> { /// Inherently impossible to fulfill; this trait is implemented if and only diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs index 651c872cd9072..2a139f43bbd96 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/custom.rs @@ -3,6 +3,7 @@ use std::fmt; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::LocalDefId; use rustc_infer::infer::region_constraints::RegionConstraintData; +use rustc_infer::traits::{FromSolverError, ScrubbedTraitError, TraitErrors}; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{TyCtxt, TypeFoldable}; use rustc_span::Span; @@ -10,8 +11,9 @@ use tracing::info; use crate::infer::InferCtxt; use crate::infer::canonical::query_response; -use crate::traits::ObligationCtxt; +use crate::solve::NextSolverError; use crate::traits::query::type_op::TypeOpOutput; +use crate::traits::{FulfillmentError, ObligationCtxt, OldSolverError}; pub struct CustomTypeOp { closure: F, @@ -50,7 +52,14 @@ where info!("fully_perform({:?})", self); } - Ok(scrape_region_constraints(infcx, root_def_id, self.description, span, self.closure)?.0) + Ok(scrape_region_constraints::<_, _, ScrubbedTraitError<'_>>( + infcx, + root_def_id, + self.description, + span, + self.closure, + )? + .0) } } @@ -60,18 +69,67 @@ impl fmt::Debug for CustomTypeOp { } } +pub struct FallibleCustomTypeOp { + closure: F, + description: &'static str, +} + +impl FallibleCustomTypeOp { + pub fn new<'tcx, R>(closure: F, description: &'static str) -> Self + where + F: FnOnce(&ObligationCtxt<'_, 'tcx, FulfillmentError<'tcx>>) -> Result, + { + FallibleCustomTypeOp { closure, description } + } +} + +impl<'tcx, F, R> super::TypeOp<'tcx> for FallibleCustomTypeOp +where + F: FnOnce(&ObligationCtxt<'_, 'tcx, FulfillmentError<'tcx>>) -> Result, + R: fmt::Debug + TypeFoldable>, +{ + type Output = R; + type ErrorInfo = !; + + /// Processes the operation and all resulting obligations, + /// returning the final result along with any region constraints + /// (they will be given over to the NLL region solver). + fn fully_perform( + self, + infcx: &InferCtxt<'tcx>, + root_def_id: LocalDefId, + span: Span, + ) -> Result, ErrorGuaranteed> { + Ok(scrape_region_constraints::<_, _, FulfillmentError<'tcx>>( + infcx, + root_def_id, + self.description, + span, + self.closure, + )? + .0) + } +} + +impl fmt::Debug for FallibleCustomTypeOp { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.description.fmt(f) + } +} + /// Executes `op` and then scrapes out all the "old style" region /// constraints that result, creating query-region-constraints. -pub fn scrape_region_constraints<'tcx, Op, R>( +pub fn scrape_region_constraints<'tcx, Op, R, E>( infcx: &InferCtxt<'tcx>, root_def_id: LocalDefId, name: &'static str, span: Span, - op: impl FnOnce(&ObligationCtxt<'_, 'tcx>) -> Result, + op: impl FnOnce(&ObligationCtxt<'_, 'tcx, E>) -> Result, ) -> Result<(TypeOpOutput<'tcx, Op>, RegionConstraintData<'tcx>), ErrorGuaranteed> where R: TypeFoldable>, Op: super::TypeOp<'tcx, Output = R>, + E: FromSolverError<'tcx, NextSolverError<'tcx>> + FromSolverError<'tcx, OldSolverError<'tcx>>, { // During NLL, we expect that nobody will register region // obligations **except** as part of a custom type op (and, at the @@ -90,9 +148,24 @@ where ); let value = infcx.commit_if_ok(|_| { - let ocx = ObligationCtxt::new(infcx); - let value = op(&ocx).map_err(|_| { - infcx.tcx.check_potentially_region_dependent_goals(root_def_id).err().unwrap_or_else( + let ocx = ObligationCtxt::::new_raw(infcx); + op(&ocx) + .and_then(|v| { + // This is specifically to report non region-dependent errors. + // Those can happen, for example, for the `Move` trait, which checks + // trait bounds (not lifetime bounds) in borrowck. In general, + // this can happen if `prove_fallible_predicate` is used, which + // invokes `FallableCustomTypeOp`. + let errors = ocx.evaluate_obligations_error_on_ambiguity(); + match errors { + TraitErrors::HasErrors(errors) => { + E::try_report_errors(infcx, errors); + Err(NoSolution) + } + TraitErrors::NoErrors => Ok(v), + } + }) + .map_err(|NoSolution| { // FIXME: In this region-dependent context, `type_op` should only fail due to // region-dependent goals. Any other kind of failure indicates a bug and we // should ICE. @@ -120,23 +193,13 @@ where // // If we ICE here on any non-region-dependent failure, we would trigger ICEs // too often for such cases. For now, we emit a delayed bug instead. - || { - infcx + match infcx.tcx.check_potentially_region_dependent_goals(root_def_id) { + Ok(_) => infcx .dcx() - .span_delayed_bug(span, format!("error performing operation: {name}")) - }, - ) - })?; - let errors = ocx.evaluate_obligations_error_on_ambiguity(); - if errors.no_errors() { - Ok(value) - } else if let Err(guar) = infcx.tcx.check_potentially_region_dependent_goals(root_def_id) { - Err(guar) - } else { - Err(infcx.dcx().delayed_bug(format!( - "errors selecting obligation during MIR typeck: {name} {root_def_id:?} {errors:?}" - ))) - } + .span_delayed_bug(span, format!("error performing operation: {name}")), + Err(e) => e, + } + }) })?; // Next trait solver performs operations locally, and normalize goals should resolve vars. diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs index a7f42fc446598..cf986b5635163 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/mod.rs @@ -2,12 +2,14 @@ use std::fmt; use rustc_errors::ErrorGuaranteed; use rustc_hir::def_id::LocalDefId; +use rustc_infer::traits::{PredicateObligations, ScrubbedTraitError}; use rustc_middle::traits::query::NoSolution; use rustc_middle::ty::{ParamEnvAnd, TyCtxt, TypeFoldable}; use rustc_span::Span; use crate::infer::canonical::{ - CanonicalQueryInput, CanonicalQueryResponse, OriginalQueryValues, QueryRegionConstraints, + CanonicalQueryInput, CanonicalQueryResponse, Certainty, OriginalQueryValues, + QueryRegionConstraints, }; use crate::infer::{InferCtxt, InferOk}; use crate::traits::ObligationCause; @@ -80,6 +82,44 @@ pub trait QueryTypeOp<'tcx>: fmt::Debug + Copy + TypeFoldable> + 't tcx: TyCtxt<'tcx>, canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>, ) -> Result, NoSolution>; + + fn fully_perform_into( + query_key: ParamEnvAnd<'tcx, Self>, + infcx: &InferCtxt<'tcx>, + output_query_region_constraints: &mut QueryRegionConstraints<'tcx>, + span: Span, + ) -> Result< + ( + Self::QueryResponse, + Option>>, + PredicateObligations<'tcx>, + Certainty, + ), + NoSolution, + > { + if !infcx.disable_trait_solver_fast_paths() + && let Some(result) = QueryTypeOp::try_fast_path(infcx, &query_key) + { + debug_assert_eq!(result, infcx.deeply_resolve_ignoring_regions(result.clone())); + return Ok((result, None, PredicateObligations::new(), Certainty::Proven)); + } + + let mut canonical_var_values = OriginalQueryValues::default(); + let old_param_env = query_key.param_env; + let canonical_self = infcx.canonicalize_query(query_key, &mut canonical_var_values); + let canonical_result = Self::perform_query(infcx.tcx, canonical_self)?; + + let InferOk { value, obligations } = infcx + .instantiate_nll_query_response_and_region_obligations( + &ObligationCause::dummy_with_span(span), + old_param_env, + &canonical_var_values, + canonical_result, + output_query_region_constraints, + )?; + + Ok((value, Some(canonical_self), obligations, canonical_result.value.certainty)) + } } impl<'tcx, Q> TypeOp<'tcx> for ParamEnvAnd<'tcx, Q> @@ -95,14 +135,6 @@ where root_def_id: LocalDefId, span: Span, ) -> Result, ErrorGuaranteed> { - if !infcx.disable_trait_solver_fast_paths() - && let Some(value) = QueryTypeOp::try_fast_path(infcx, &self) - { - debug_assert_eq!(value, infcx.deeply_resolve_ignoring_regions(value.clone())); - - return Ok(TypeOpOutput { output: value, constraints: None, error_info: None }); - } - let mut error_info = None; let mut region_constraints = QueryRegionConstraints::default(); @@ -111,26 +143,20 @@ where // instead of an actual hidden type. In that case we don't register a hidden type but just // equate the lifetimes. Thus we need to scrape the region constraints even though we're // also manually collecting region constraints via `region_constraints`. - let (mut output, _) = - scrape_region_constraints(infcx, root_def_id, "fully_perform", span, |ocx| { - let mut canonical_var_values = OriginalQueryValues::default(); - let old_param_env = self.param_env; - let canonical_self = infcx.canonicalize_query(self, &mut canonical_var_values); - let canonical_result = Q::perform_query(infcx.tcx, canonical_self)?; - - let InferOk { value, obligations } = infcx - .instantiate_nll_query_response_and_region_obligations( - &ObligationCause::dummy_with_span(span), - old_param_env, - &canonical_var_values, - canonical_result, - &mut region_constraints, - )?; - - error_info = Some(canonical_self); + let (mut output, _) = scrape_region_constraints::<_, _, ScrubbedTraitError<'_>>( + infcx, + root_def_id, + "fully_perform", + span, + |ocx| { + let (output, ei, obligations, _) = + Q::fully_perform_into(self, infcx, &mut region_constraints, span)?; + error_info = ei; + ocx.register_obligations(obligations); - Ok(value) - })?; + Ok(output) + }, + )?; output.error_info = error_info; if let Some(QueryRegionConstraints { constraints, assumptions }) = output.constraints { From a51b14af6219998514472199e9bcb57726a6f3e4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 28 Oct 2026 14:02:21 +0100 Subject: [PATCH 12/31] Use the `2.38` binutils version in CI --- src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh | 2 +- src/ci/docker/scripts/build-gcc.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh index 4935870dd8d65..21fc7c2a9cd77 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh @@ -16,7 +16,7 @@ python3 ../x.py build --set rust.debug=true opt-dist # Use GCC for building GCC components, as it seems to behave badly when built with Clang # Only build GCC on full builds, not try builds if [ "${DIST_TRY_BUILD:-0}" == "0" ]; then - # We add the binutils binary path to ensure that it uses the 2.47 version of binutils, + # We add the binutils binary path to ensure that it uses the 2.38 version of binutils, # which is needed for the `retain` attribute feature. export PATH="/tmp/binutils-install/bin:$PATH" diff --git a/src/ci/docker/scripts/build-gcc.sh b/src/ci/docker/scripts/build-gcc.sh index 1a32433f54278..60443744455d9 100755 --- a/src/ci/docker/scripts/build-gcc.sh +++ b/src/ci/docker/scripts/build-gcc.sh @@ -6,7 +6,7 @@ source shared.sh # We have to build our own binutils for the GCC build, because the default CentOS 7 binutils are # too old, and they do not support `SHF_GNU_RETAIN`. -BINUTILS="2.47" +BINUTILS="2.38" BINUTILS_ROOT_PATH="$(pwd)/binutils-install" BINUTILS_PATH="$BINUTILS_ROOT_PATH/bin" curl https://ci-mirrors.rust-lang.org/rustc/gcc/binutils-$BINUTILS.tar.xz | xzcat | tar xf - From 70ed0432c97ac13f02980ca163052fb17a51b862 Mon Sep 17 00:00:00 2001 From: Manuel Drehwald Date: Thu, 5 Nov 2026 10:20:32 -0500 Subject: [PATCH 13/31] update Enzyem submodule --- src/tools/enzyme | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/enzyme b/src/tools/enzyme index 7a55d0364ca1e..ffd1ec24186c9 160000 --- a/src/tools/enzyme +++ b/src/tools/enzyme @@ -1 +1 @@ -Subproject commit 7a55d0364ca1e7cb3c797a9d38a6c52061edf02e +Subproject commit ffd1ec24186c9fd7029c6c9925066a1ae2763d6b From 1dd187d8514f31afc4f71bc69db17873aa94a46f Mon Sep 17 00:00:00 2001 From: Mahdi Ali-Raihan Date: Wed, 4 Nov 2026 00:24:37 -0500 Subject: [PATCH 14/31] Update Vec::retain_unstable docs to say that this method is generally faster than Vec::retain_mut --- library/alloc/src/vec/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index e2be7941cf94d..f9a9a3f23e257 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2545,6 +2545,8 @@ impl Vec { /// consider using [`Vec::retain_mut`] instead. However, if no items are removed, then all items /// are left in their original positions. /// + /// Generally, this method is faster than [`Vec::retain_mut`] due to its weak ordering guarantees. + /// /// [`Vec::retain_mut`]: crate::vec::Vec::retain_mut /// /// Time complexity: *O*(*n*) From d40c05ae62d02111499f30d7fe53028ae902dea1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Le=C3=B3n=20Orell=20Valerian=20Liehr?= Date: Thu, 5 Nov 2026 16:58:26 +0100 Subject: [PATCH 15/31] DFV: Reject `#[non_exhaustive]` on enum variants with default field values --- .../src/attributes/non_exhaustive.rs | 7 ++-- .../rustc_attr_parsing/src/diagnostics.rs | 2 +- .../default-field-values-non_exhaustive.rs | 23 ++++++++--- ...default-field-values-non_exhaustive.stderr | 39 +++++++++++++++---- 4 files changed, 52 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs b/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs index c2f8875e440e7..b363675d5932f 100644 --- a/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs +++ b/compiler/rustc_attr_parsing/src/attributes/non_exhaustive.rs @@ -23,10 +23,9 @@ impl NoArgsAttributeParser for NonExhaustiveParser { const CREATE: fn(Span) -> AttributeKind = AttributeKind::NonExhaustive; fn finalize_check(cx: &mut FinalizeCheckContext<'_, '_>, attr_span: Span) { - let AstTarget::Struct(_, _, data) = cx.ast_target else { - return; - }; - if let VariantData::Struct { fields, .. } = data + if let AstTarget::Struct(_, _, data) | AstTarget::Variant(rustc_ast::Variant { data, .. }) = + cx.ast_target + && let VariantData::Struct { fields, .. } = data && fields.iter().any(|f| f.default_value().is_some()) { cx.emit_err(NonExhaustiveWithDefaultFieldValues { diff --git a/compiler/rustc_attr_parsing/src/diagnostics.rs b/compiler/rustc_attr_parsing/src/diagnostics.rs index d16d38344d03c..250a2a56be293 100644 --- a/compiler/rustc_attr_parsing/src/diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/diagnostics.rs @@ -1281,7 +1281,7 @@ pub(crate) struct DeprecatedAnnotationHasNoEffect { } #[derive(Diagnostic)] -#[diag("`#[non_exhaustive]` can't be used to annotate items with default field values")] +#[diag("`#[non_exhaustive]` can't be used to annotate structs with default field values")] pub(crate) struct NonExhaustiveWithDefaultFieldValues { #[primary_span] pub attr_span: Span, diff --git a/tests/ui/structs/default-field-values-non_exhaustive.rs b/tests/ui/structs/default-field-values-non_exhaustive.rs index 0ad2b0766a772..32631de4e359f 100644 --- a/tests/ui/structs/default-field-values-non_exhaustive.rs +++ b/tests/ui/structs/default-field-values-non_exhaustive.rs @@ -1,18 +1,29 @@ #![feature(default_field_values)] #[derive(Default)] -#[non_exhaustive] //~ ERROR `#[non_exhaustive]` can't be used to annotate items with default field values -struct Foo { - x: i32 = 42 + 3, +#[non_exhaustive] +//~^ ERROR `#[non_exhaustive]` can't be used to annotate structs with default field values +struct Struct { + field: i32 = 42 + 3, +} + +enum Enum { + #[non_exhaustive] + //~^ ERROR `#[non_exhaustive]` can't be used to annotate structs with default field values + Variant { + field: i32 = 24, + } } #[derive(Default)] -enum Bar { +enum EnumWithDefault { #[non_exhaustive] + //~^ ERROR `#[non_exhaustive]` can't be used to annotate structs with default field values #[default] - Baz { //~ ERROR default variant must be exhaustive - x: i32 = 42 + 3, + Variant { //~ ERROR default variant must be exhaustive + field: i32 = 42 + 3, } } + fn main () {} diff --git a/tests/ui/structs/default-field-values-non_exhaustive.stderr b/tests/ui/structs/default-field-values-non_exhaustive.stderr index 13013bebe83d9..c7736f5bbafbf 100644 --- a/tests/ui/structs/default-field-values-non_exhaustive.stderr +++ b/tests/ui/structs/default-field-values-non_exhaustive.stderr @@ -1,23 +1,46 @@ error: default variant must be exhaustive - --> $DIR/default-field-values-non_exhaustive.rs:13:5 + --> $DIR/default-field-values-non_exhaustive.rs:23:5 | LL | #[non_exhaustive] | ----------------- declared `#[non_exhaustive]` here -LL | #[default] -LL | Baz { - | ^^^ +... +LL | Variant { + | ^^^^^^^ | = help: consider a manual implementation of `Default` -error: `#[non_exhaustive]` can't be used to annotate items with default field values +error: `#[non_exhaustive]` can't be used to annotate structs with default field values --> $DIR/default-field-values-non_exhaustive.rs:4:1 | LL | #[non_exhaustive] | ^^^^^^^^^^^^^^^^^ -LL | / struct Foo { -LL | | x: i32 = 42 + 3, +LL | +LL | / struct Struct { +LL | | field: i32 = 42 + 3, LL | | } | |_- this struct has default field values -error: aborting due to 2 previous errors +error: `#[non_exhaustive]` can't be used to annotate structs with default field values + --> $DIR/default-field-values-non_exhaustive.rs:11:5 + | +LL | #[non_exhaustive] + | ^^^^^^^^^^^^^^^^^ +LL | +LL | / Variant { +LL | | field: i32 = 24, +LL | | } + | |_____- this struct has default field values + +error: `#[non_exhaustive]` can't be used to annotate structs with default field values + --> $DIR/default-field-values-non_exhaustive.rs:20:5 + | +LL | #[non_exhaustive] + | ^^^^^^^^^^^^^^^^^ +... +LL | / Variant { +LL | | field: i32 = 42 + 3, +LL | | } + | |_____- this struct has default field values + +error: aborting due to 4 previous errors From 869600323f065f76f634bc1ee56a62532675407d Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Fri, 6 Nov 2026 02:21:25 +0900 Subject: [PATCH 16/31] remove unused WhereEqPredicate and ScopeId types --- compiler/rustc_ast/src/ast.rs | 9 --------- compiler/rustc_ast/src/visit.rs | 1 - compiler/rustc_hir/src/hir.rs | 7 ------- compiler/rustc_mir_build/src/builder/mod.rs | 4 ---- 4 files changed, 21 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 20d60887e2d5f..ba3d337fe0173 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -550,15 +550,6 @@ pub struct WhereRegionPredicate { pub bounds: GenericBounds, } -/// An equality predicate (unsupported). -/// -/// E.g., `T = int`. -#[derive(Clone, Encodable, Decodable, Debug, Walkable)] -pub struct WhereEqPredicate { - pub lhs_ty: Box, - pub rhs_ty: Box, -} - #[derive(Clone, Encodable, Decodable, Debug, Walkable)] pub struct Crate { /// Must be equal to `CRATE_NODE_ID` after the crate root is expanded, but may hold diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index 92f418b48bebf..9dc55686c7494 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -576,7 +576,6 @@ macro_rules! common_visitor_and_walkers { VisibilityKind, WhereBoundPredicate, WhereClause, - WhereEqPredicate, WhereRegionPredicate, YieldKind, // tidy-alphabetical-end diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index cc4fea22b819a..4ce8f5e793bc9 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1280,13 +1280,6 @@ impl<'hir> WhereRegionPredicate<'hir> { } } -/// An equality predicate (e.g., `T = int`); currently unsupported. -#[derive(Debug, Clone, Copy, StableHash)] -pub struct WhereEqPredicate<'hir> { - pub lhs_ty: &'hir Ty<'hir>, - pub rhs_ty: &'hir Ty<'hir>, -} - /// HIR node coupled with its parent's id in the same HIR owner. /// /// The parent is trash when the node is a HIR owner. diff --git a/compiler/rustc_mir_build/src/builder/mod.rs b/compiler/rustc_mir_build/src/builder/mod.rs index 077cca785a2cc..4e97ddd991e2d 100644 --- a/compiler/rustc_mir_build/src/builder/mod.rs +++ b/compiler/rustc_mir_build/src/builder/mod.rs @@ -396,10 +396,6 @@ struct CFG<'tcx> { basic_blocks: IndexVec>, } -rustc_index::newtype_index! { - struct ScopeId {} -} - #[derive(Debug)] enum NeedsTemporary { /// Use this variant when whatever you are converting with `as_operand` From 7f4b36ef6c4f94c95efd7ad374ede2936296a245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 23 Oct 2026 00:25:55 +0000 Subject: [PATCH 17/31] When missing const param in `impl`, provide complete suggestion ``` error[E0107]: missing generics for struct `a::Foo` --> $DIR/impl-block-missing-const-generics.rs:6:10 | LL | impl Foo {} | ^^^ expected 1 generic argument | note: struct defined here, with 1 generic parameter: `AHA` --> $DIR/impl-block-missing-const-generics.rs:4:12 | LL | struct Foo{} | ^^^ ---------------- help: add missing generic argument | LL | impl Foo {} | ++++++++++++++++++ +++++ ``` Previously we only suggested `Foo` without the `impl`. --- .../wrong_number_of_generic_args.rs | 77 ++++++--- .../issue-109768.stderr | 4 +- .../associated-types-eq-2.stderr | 28 ++-- .../impl-block-missing-const-generics.rs | 75 +++++++++ .../impl-block-missing-const-generics.stderr | 147 ++++++++++++++++++ ...t-arg-coherence-conflicting-methods.stderr | 4 +- tests/ui/delegation/ice-issue-150673.stderr | 4 +- .../recursive-delegation-ice-150152.stderr | 4 +- ...declared-in-wrong-spot-issue-113073.stderr | 4 +- ...ame-with-lacking-generic-arg-148121.stderr | 8 +- 10 files changed, 307 insertions(+), 48 deletions(-) create mode 100644 tests/ui/const-generics/impl-block-missing-const-generics.rs create mode 100644 tests/ui/const-generics/impl-block-missing-const-generics.stderr diff --git a/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs index d76e7d4dc7bf3..bd95fa57ff553 100644 --- a/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs @@ -2,8 +2,10 @@ use GenericArgsInfo::*; use rustc_errors::codes::*; use rustc_errors::{Applicability, Diag, Diagnostic, MultiSpan, pluralize}; use rustc_hir as hir; -use rustc_middle::ty::{self as ty, AssocItem, AssocItems, TyCtxt}; +use rustc_hir::def::DefKind; +use rustc_middle::ty::{self as ty, AssocItem, AssocItems, Ty, TyCtxt}; use rustc_span::def_id::{DefId, LocalDefId}; +use rustc_span::{Symbol, kw}; use tracing::debug; /// Handles the `wrong number of type / lifetime / ... arguments` family of error messages. @@ -442,6 +444,17 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { &self, num_params_to_take: usize, ) -> String { + self.get_type_or_const_arg_names(num_params_to_take) + .map(|(n, _)| n.to_string()) + .intersperse(", ".to_string()) + .collect() + } + + // Lists type or constant names from the provided parameter names + fn get_type_or_const_arg_names( + &self, + num_params_to_take: usize, + ) -> impl Iterator>)> { let is_in_a_method_call = self .tcx .hir_parent_iter(self.path_segment.hir_id) @@ -458,7 +471,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { }); let fn_sig = self.tcx.hir_get_if_local(self.def_id).and_then(hir::Node::fn_sig); - let is_used_in_input = |def_id| { + let is_used_in_input = move |def_id| { fn_sig.is_some_and(|fn_sig| { fn_sig.decl.inputs.iter().any(|ty| match ty.kind { hir::TyKind::Path(hir::QPath::Resolved( @@ -474,18 +487,21 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { .iter() .skip(self.params_offset + self.num_provided_type_or_const_args()) .take(num_params_to_take) - .map(|param| match param.kind { + .map(move |param| match param.kind { // If it's in method call (turbofish), it might be inferred from the expression (e.g. `.collect::>()`) // If it is being inferred from the item's inputs, no need to set it. ty::GenericParamDefKind::Type { .. } if is_in_a_method_call || is_used_in_input(param.def_id) => { - "_" + (kw::Underscore, None) } - _ => param.name.as_str(), + // FIXME: tcx.type_of(param.def_id) for consts + ty::GenericParamDefKind::Const { .. } => ( + param.name, + Some(self.tcx.type_of(param.def_id).instantiate_identity().skip_norm_wip()), + ), + _ => (param.name, None), }) - .intersperse(", ") - .collect() } fn get_unbound_associated_item(&self) -> Vec<&AssocItem> { @@ -715,22 +731,39 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let suggested_args = self.get_type_or_const_args_suggestions_from_param_names(num_missing_args); + let arg_names: Vec<_> = self.get_type_or_const_arg_names(num_missing_args).collect(); debug!("suggested_args: {:?}", suggested_args); + let mut impl_sugg = None; + if let DefKind::Impl { .. } = self.tcx.def_kind(self.cx_def_id) { + let mut impl_args = vec![]; + let i = self.tcx.hir_node_by_def_id(self.cx_def_id).expect_item().expect_impl(); + for (arg, const_ty) in arg_names { + if i.generics.get_named(arg).is_none() { + impl_args.push(match const_ty { + Some(ty) => format!("const {arg}: {ty}"), + None => arg.to_string(), + }) + } + } + if !impl_args.is_empty() { + impl_sugg = Some(match i.generics.span_for_lifetime_suggestion() { + Some(span) => (span, format!("{}, ", impl_args.join(", "))), + None => (i.generics.span, format!("<{}>", impl_args.join(", "))), + }); + } + } match self.angle_brackets { AngleBrackets::Missing | AngleBrackets::Implied => { let span = self.path_segment.ident.span; // insert a suggestion of the form "Y" - let sugg = format!("<{suggested_args}>"); - debug!("sugg: {:?}", sugg); - - err.span_suggestion_verbose( - span.shrink_to_hi(), - msg, - sugg, - Applicability::HasPlaceholders, - ); + let mut sugg = vec![(span.shrink_to_hi(), format!("<{suggested_args}>"))]; + if let Some(impl_sugg) = impl_sugg { + sugg.insert(0, impl_sugg); + } + debug!(?sugg); + err.multipart_suggestion(msg, sugg, Applicability::HasPlaceholders); } AngleBrackets::Available => { let gen_args_span = self.gen_args.span().unwrap(); @@ -755,10 +788,14 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { let sugg_suffix = if is_first && !self.gen_args.constraints.is_empty() { ", " } else { "" }; - let sugg = format!("{sugg_prefix}{suggested_args}{sugg_suffix}"); - debug!("sugg: {:?}", sugg); - - err.span_suggestion_verbose(sugg_span, msg, sugg, Applicability::HasPlaceholders); + let mut sugg = + vec![(sugg_span, format!("{sugg_prefix}{suggested_args}{sugg_suffix}"))]; + if let Some(impl_sugg) = impl_sugg { + sugg.insert(0, impl_sugg); + } + debug!(?sugg); + err.multipart_suggestion(msg, sugg, Applicability::HasPlaceholders); + // err.note(format!("{:?}", self.cx_def_id)); } } } diff --git a/tests/ui/associated-inherent-types/issue-109768.stderr b/tests/ui/associated-inherent-types/issue-109768.stderr index 59f8526a73e59..75396199c2b8b 100644 --- a/tests/ui/associated-inherent-types/issue-109768.stderr +++ b/tests/ui/associated-inherent-types/issue-109768.stderr @@ -17,8 +17,8 @@ LL | struct Local(T, U); | ^^^^^ - - help: add missing generic arguments | -LL | impl Local { - | ++++++ +LL | impl Local { + | ++ ++++++ error[E0658]: inherent associated types are unstable --> $DIR/issue-109768.rs:8:5 diff --git a/tests/ui/associated-types/associated-types-eq-2.stderr b/tests/ui/associated-types/associated-types-eq-2.stderr index fdcfb8cd53f98..8c9d5100bd6a6 100644 --- a/tests/ui/associated-types/associated-types-eq-2.stderr +++ b/tests/ui/associated-types/associated-types-eq-2.stderr @@ -89,8 +89,8 @@ LL | trait Tr2 { | ^^^ -- -- -- help: add missing generic arguments | -LL | impl Tr2 for Bar { - | ++++++++ +LL | impl Tr2 for Bar { + | ++++++++ ++++++++ error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:40:15 @@ -119,8 +119,8 @@ LL | trait Tr2 { | ^^^ -- -- -- help: add missing generic arguments | -LL | impl Tr2 for Qux { - | ++++++++ +LL | impl Tr2 for Qux { + | ++++++++ ++++++++ error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:47:15 @@ -149,8 +149,8 @@ LL | trait Tr2 { | ^^^ -- -- -- help: add missing generic arguments | -LL | impl Tr2 for Bar { - | ++++++++ +LL | impl Tr2 for Bar { + | ++++++++ ++++++++ error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:54:15 @@ -179,8 +179,8 @@ LL | trait Tr2 { | ^^^ -- -- -- help: add missing generic argument | -LL | impl Tr2> for Bar { - | ++++ +LL | impl Tr2> for Bar { + | ++++ ++++ error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:61:20 @@ -225,8 +225,8 @@ LL | trait Tr3 { | ^^^ ------------ -- -- help: add missing generic arguments | -LL | impl Tr3 for Qux { - | ++++++++++ +LL | impl Tr3 for Qux { + | ++++++++++++++++++++++ ++++++++++ error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:84:10 @@ -267,8 +267,8 @@ LL | trait Tr3 { | ^^^ ------------ -- -- help: add missing generic arguments | -LL | impl Tr3<42, T2, T3, T2 = 42, T3 = usize> for Bar { - | ++++++++ +LL | impl Tr3<42, T2, T3, T2 = 42, T3 = usize> for Bar { + | ++++++++ ++++++++ error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:98:14 @@ -295,8 +295,8 @@ LL | trait Tr3 { | ^^^ ------------ -- -- help: add missing generic arguments | -LL | impl Tr3 for Bar { - | ++++++++++ +LL | impl Tr3 for Bar { + | ++++++++++++++++++++++ ++++++++++ error[E0229]: associated item constraints are not allowed here --> $DIR/associated-types-eq-2.rs:106:10 diff --git a/tests/ui/const-generics/impl-block-missing-const-generics.rs b/tests/ui/const-generics/impl-block-missing-const-generics.rs new file mode 100644 index 0000000000000..1f370d9c0136b --- /dev/null +++ b/tests/ui/const-generics/impl-block-missing-const-generics.rs @@ -0,0 +1,75 @@ +// Ensure that `impl` blocks with different mistakes regarding const parameters are properly +// handled. Issue #91119. +mod a { + struct Foo{} + + impl Foo {} //~ ERROR: missing generics for struct `a::Foo` +} + +mod b { + struct Foo{} + + impl Foo {} //~ ERROR: cannot find const `AHA` in this scope +} + +mod c { + struct Foo{} + + impl Foo {} //~ ERROR: type provided when a constant was expected +} + +mod d { + struct Foo{} + + impl Foo<{ AHA }> {} //~ ERROR: cannot find value `AHA` in this scope +} + +mod e { + struct Foo{} + + impl Foo {} //~ ERROR: the constant `AHA` is not of type `usize` +} + +mod f { + struct Foo{} + trait T {} + + impl T for Foo {} //~ ERROR: missing generics for struct `f::Foo` +} + +mod g { + struct Foo {} + trait T {} + + impl T for Foo {} //~ ERROR: missing generics for trait `g::T` +} + +mod h { + struct Foo {} + trait T {} + + impl T for Foo {} //~ ERROR: cannot find type `AHA` in this scope +} + +mod i { + struct Foo {} + trait T {} + + impl T for Foo {} //~ ERROR: type provided when a constant was expected +} + +mod j { + struct Foo {} + trait T {} + + impl T<{ AHA }> for Foo {} //~ ERROR: cannot find value `AHA` in this scope +} + +mod k { + struct Foo {} + trait T {} + + impl T for Foo {} //~ ERROR: the constant `AHA` is not of type `usize` +} + +fn main() {} diff --git a/tests/ui/const-generics/impl-block-missing-const-generics.stderr b/tests/ui/const-generics/impl-block-missing-const-generics.stderr new file mode 100644 index 0000000000000..2f504ddadda30 --- /dev/null +++ b/tests/ui/const-generics/impl-block-missing-const-generics.stderr @@ -0,0 +1,147 @@ +error[E0425]: cannot find const `AHA` in this scope + --> $DIR/impl-block-missing-const-generics.rs:12:14 + | +LL | struct Foo{} + | ---------------- corresponding const parameter on the type defined here +LL | +LL | impl Foo {} + | ^^^ not found in this scope + | +help: you might have meant to introduce a const parameter `AHA` on the impl + | +LL | impl Foo {} + | ++++++++++++++++++ + +error[E0425]: cannot find value `AHA` in this scope + --> $DIR/impl-block-missing-const-generics.rs:24:16 + | +LL | impl Foo<{ AHA }> {} + | ^^^ not found in this scope + | +help: you might be missing a const parameter + | +LL | impl Foo<{ AHA }> {} + | +++++++++++++++++++++++ + +error[E0425]: cannot find type `AHA` in this scope + --> $DIR/impl-block-missing-const-generics.rs:51:12 + | +LL | impl T for Foo {} + | ^^^ not found in this scope + | +help: you might be missing a type parameter + | +LL | impl T for Foo {} + | +++++ + +error[E0425]: cannot find value `AHA` in this scope + --> $DIR/impl-block-missing-const-generics.rs:65:14 + | +LL | impl T<{ AHA }> for Foo {} + | ^^^ not found in this scope + | +help: you might be missing a const parameter + | +LL | impl T<{ AHA }> for Foo {} + | +++++++++++++++++++++++ + +error[E0107]: missing generics for struct `a::Foo` + --> $DIR/impl-block-missing-const-generics.rs:6:10 + | +LL | impl Foo {} + | ^^^ expected 1 generic argument + | +note: struct defined here, with 1 generic parameter: `AHA` + --> $DIR/impl-block-missing-const-generics.rs:4:12 + | +LL | struct Foo{} + | ^^^ ---------------- +help: add missing generic argument + | +LL | impl Foo {} + | ++++++++++++++++++ +++++ + +error[E0747]: type provided when a constant was expected + --> $DIR/impl-block-missing-const-generics.rs:18:19 + | +LL | impl Foo {} + | ^^^ + | +help: consider changing this type parameter to a const parameter + | +LL - impl Foo {} +LL + impl Foo {} + | + +error: the constant `AHA` is not of type `usize` + --> $DIR/impl-block-missing-const-generics.rs:30:26 + | +LL | impl Foo {} + | ^^^^^^^^ expected `usize`, found `u32` + | +note: required by a const generic parameter in `e::Foo` + --> $DIR/impl-block-missing-const-generics.rs:28:16 + | +LL | struct Foo{} + | ^^^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` + +error[E0107]: missing generics for struct `f::Foo` + --> $DIR/impl-block-missing-const-generics.rs:37:16 + | +LL | impl T for Foo {} + | ^^^ expected 1 generic argument + | +note: struct defined here, with 1 generic parameter: `AHA` + --> $DIR/impl-block-missing-const-generics.rs:34:12 + | +LL | struct Foo{} + | ^^^ ---------------- +help: add missing generic argument + | +LL | impl T for Foo {} + | ++++++++++++++++++ +++++ + +error[E0107]: missing generics for trait `g::T` + --> $DIR/impl-block-missing-const-generics.rs:44:10 + | +LL | impl T for Foo {} + | ^ expected 1 generic argument + | +note: trait defined here, with 1 generic parameter: `AHA` + --> $DIR/impl-block-missing-const-generics.rs:42:11 + | +LL | trait T {} + | ^ ---------------- +help: add missing generic argument + | +LL | impl T for Foo {} + | ++++++++++++++++++ +++++ + +error[E0747]: type provided when a constant was expected + --> $DIR/impl-block-missing-const-generics.rs:58:17 + | +LL | impl T for Foo {} + | ^^^ + | +help: consider changing this type parameter to a const parameter + | +LL - impl T for Foo {} +LL + impl T for Foo {} + | + +error: the constant `AHA` is not of type `usize` + --> $DIR/impl-block-missing-const-generics.rs:72:26 + | +LL | impl T for Foo {} + | ^^^^^^ expected `usize`, found `u32` + | +note: required by a const generic parameter in `k::T` + --> $DIR/impl-block-missing-const-generics.rs:70:13 + | +LL | trait T {} + | ^^^^^^^^^^^^^^^^ required by this const generic parameter in `T` + +error: aborting due to 11 previous errors + +Some errors have detailed explanations: E0107, E0425, E0747. +For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr index c82f8a96167ba..6911933cd005e 100644 --- a/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr +++ b/tests/ui/const-generics/mgca/const-arg-coherence-conflicting-methods.stderr @@ -11,8 +11,8 @@ LL | pub struct A {} | ^ -------------- help: add missing generic argument | -LL | impl A { - | +++ +LL | impl A { + | ++++++++++++++++ +++ error[E0592]: duplicate definitions with name `fun1` --> $DIR/const-arg-coherence-conflicting-methods.rs:11:5 diff --git a/tests/ui/delegation/ice-issue-150673.stderr b/tests/ui/delegation/ice-issue-150673.stderr index 808e8e84a61e0..0a2992792083a 100644 --- a/tests/ui/delegation/ice-issue-150673.stderr +++ b/tests/ui/delegation/ice-issue-150673.stderr @@ -11,8 +11,8 @@ LL | struct S(T); | ^ - help: add missing generic argument | -LL | impl Trait for S { - | +++ +LL | impl Trait for S { + | +++ +++ error: aborting due to 1 previous error diff --git a/tests/ui/delegation/recursive-delegation-ice-150152.stderr b/tests/ui/delegation/recursive-delegation-ice-150152.stderr index b59b588f4968a..fe887f4af5082 100644 --- a/tests/ui/delegation/recursive-delegation-ice-150152.stderr +++ b/tests/ui/delegation/recursive-delegation-ice-150152.stderr @@ -65,8 +65,8 @@ LL | struct S< S >; | ^ - help: add missing generic argument | -LL | impl Item for S> { - | +++ +LL | impl Item for S> { + | +++ +++ error: aborting due to 6 previous errors diff --git a/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr b/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr index 33d0c9c970795..62395b619fc92 100644 --- a/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr +++ b/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr @@ -84,8 +84,8 @@ LL | trait Bar {} | ^^^ - - help: add missing generic argument | -LL | impl Bar for u8 {} - | +++ +LL | impl Bar for u8 {} + | ++ +++ error[E0229]: associated item constraints are not allowed here --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:27:16 diff --git a/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.stderr b/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.stderr index 5a7969193b553..f6ed222512d17 100644 --- a/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.stderr +++ b/tests/ui/traits/associated_type_bound/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.stderr @@ -11,8 +11,8 @@ LL | pub trait Super { | ^^^^^ - help: add missing generic argument | -LL | impl A for dyn Super {} - | ++ +LL | impl A for dyn Super {} + | +++ ++ error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied --> $DIR/assoc-type-bounds-with-the-same-name-with-lacking-generic-arg-148121.rs:14:16 @@ -27,8 +27,8 @@ LL | pub trait Zelf: Super {} | ^^^^ - help: add missing generic argument | -LL | impl A for dyn Zelf {} - | ++ +LL | impl A for dyn Zelf {} + | +++ ++ error: aborting due to 2 previous errors From 8718bb4accdf235475c678e99f7e81943d4c1ac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 23 Oct 2026 00:42:38 +0000 Subject: [PATCH 18/31] Point at const param declaration when constant is not expected type ``` error: the constant `N` is not of type `usize` --> $DIR/const-in-impl-fn-return-type.rs:12:32 | LL | fn func() -> [(); N]; | ------------ ^^^^^^^ expected `usize`, found `u32` | | | found this const parameter | = note: the length of array `[(); N]` must be type `usize` ``` --- .../traits/fulfillment_errors.rs | 23 ++++++++++-- ...ismatched-types-with-generic-in-ace.stderr | 4 ++- .../wf-mismatch-1.stderr | 4 ++- .../wf-mismatch-2.stderr | 2 ++ .../bad-subst-const-kind.stderr | 4 ++- ...onst_arg_type_in_free_alias.checked.stderr | 35 +++++++++++++++---- ...st_arg_type_in_free_alias.unchecked.stderr | 30 ++++++++++++---- ...heck_const_arg_type_in_trait_object.stderr | 8 ++++- .../defaults/concrete-const-param-type.stderr | 4 ++- .../const-generics/dyn-trait-ill-typed.stderr | 4 ++- .../generic_const_exprs/type_mismatch.stderr | 4 ++- .../impl-block-missing-const-generics.stderr | 8 +++-- .../issues/index_array_bad_type.stderr | 4 ++- .../mgca/adt_expr_arg_tuple_expr_fail.stderr | 11 ++++++ .../mgca/adt_expr_fields_type_check.stderr | 16 +++++++++ tests/ui/const-generics/transmute-fail.stderr | 7 +++- ...ype-mismatch-in-nested-goal.current.stderr | 4 ++- .../type-mismatch-in-nested-goal.next.stderr | 4 ++- tests/ui/const-generics/type_mismatch.stderr | 6 +++- .../consts/bad-array-size-in-type-err.stderr | 6 +++- ...oj-ty-as-type-of-const-issue-125757.stderr | 4 ++- .../wrong-adt-assume.stderr | 3 ++ ...onst-in-impl-fn-return-type.current.stderr | 4 ++- .../const-in-impl-fn-return-type.next.stderr | 4 ++- ...wf-dyn-in-hrtb-bound-const-mismatch.stderr | 4 ++- 25 files changed, 173 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 10e2ba18f3d7c..376789ee13194 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -32,8 +32,8 @@ use rustc_middle::ty::print::{ }; use rustc_middle::ty::transmute::{Answer, Reason}; use rustc_middle::ty::{ - self, GenericArgKind, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable, TypeFolder, - TypeSuperFoldable, TypeVisitableExt, Unnormalized, Upcast, + self, ConstKind, GenericArgKind, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable, + TypeFolder, TypeSuperFoldable, TypeVisitableExt, Unnormalized, Upcast, }; use rustc_span::def_id::CrateNum; use rustc_span::{BytePos, DUMMY_SP, STDLIB_STABLE_CRATES, Span, Symbol, bug, span_bug, sym}; @@ -872,6 +872,25 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { format!("the constant `{ct_str}` is not of type `{expected_ty_str}`"), ); diag.long_ty_path = long_ty_file; + if let ConstKind::Param(param_const) = ct.kind() { + for param in self + .tcx + .generics_of(obligation.cause.body_def_id.to_def_id()) + .own_params + .iter() + { + match param.kind { + GenericParamDefKind::Const { .. } + if param.index == param_const.index + && param.name == param_const.name => + { + let span = self.tcx.def_span(param.def_id); + diag.span_label(span, "found this const parameter"); + } + _ => {} + } + } + } self.note_type_err( &mut diag, diff --git a/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr index 1eaa635e13532..086953e3c4fac 100644 --- a/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr +++ b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr @@ -2,7 +2,9 @@ error: the constant `N` is not of type `u32` --> $DIR/mismatched-types-with-generic-in-ace.rs:15:29 | LL | fn bar = { N }>>() {} - | ^^^^^^^^^^^^^^^^ expected `u32`, found `u64` + | ------------ ^^^^^^^^^^^^^^^^ expected `u32`, found `u64` + | | + | found this const parameter | note: required by a const generic parameter in `Foo::ASSOC` --> $DIR/mismatched-types-with-generic-in-ace.rs:8:17 diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.stderr b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.stderr index f75f4a08969c8..d72a957a61b8f 100644 --- a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.stderr +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.stderr @@ -2,7 +2,9 @@ error: the constant `N` is not of type `bool` --> $DIR/wf-mismatch-1.rs:12:34 | LL | fn f(_: impl Trait) {} - | ^^^^^^^^^^ expected `bool`, found `i32` + | ------------ ^^^^^^^^^^ expected `bool`, found `i32` + | | + | found this const parameter | note: required by a const generic parameter in `f` --> $DIR/wf-mismatch-1.rs:12:34 diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.stderr b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.stderr index c12b9fe78c049..16168d2a85fe6 100644 --- a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.stderr +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.stderr @@ -1,6 +1,8 @@ error: the constant `N` is not of type `bool` --> $DIR/wf-mismatch-2.rs:13:12 | +LL | fn f() { + | ------------ found this const parameter LL | let _: dyn Trait; | ^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `i32` diff --git a/tests/ui/const-generics/bad-subst-const-kind.stderr b/tests/ui/const-generics/bad-subst-const-kind.stderr index b360526964255..331ad62e761ce 100644 --- a/tests/ui/const-generics/bad-subst-const-kind.stderr +++ b/tests/ui/const-generics/bad-subst-const-kind.stderr @@ -2,7 +2,9 @@ error: the constant `N` is not of type `usize` --> $DIR/bad-subst-const-kind.rs:8:26 | LL | impl Q for [u8; N] { - | ^^^^^^^ expected `usize`, found `u64` + | ------------ ^^^^^^^ expected `usize`, found `u64` + | | + | found this const parameter | = note: the length of array `[u8; N]` must be type `usize` diff --git a/tests/ui/const-generics/check_const_arg_type_in_free_alias.checked.stderr b/tests/ui/const-generics/check_const_arg_type_in_free_alias.checked.stderr index 371657baa5e6f..087eb0a41a80b 100644 --- a/tests/ui/const-generics/check_const_arg_type_in_free_alias.checked.stderr +++ b/tests/ui/const-generics/check_const_arg_type_in_free_alias.checked.stderr @@ -2,7 +2,10 @@ error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_free_alias.rs:14:1 | LL | type ArrLen = [(); B]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | ^^^^^^^^^^^^-------------^ + | | | + | | found this const parameter + | expected `usize`, found `bool` | = note: the length of array `[(); B]` must be type `usize` @@ -18,7 +21,10 @@ error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_free_alias.rs:18:1 | LL | type ConstArg = Foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | ^^^^^^^^^^^^^^-------------^ + | | | + | | found this const parameter + | expected `usize`, found `bool` | note: required by a const generic parameter in `Foo` --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 @@ -42,7 +48,10 @@ error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_free_alias.rs:31:1 | LL | type Alias = <() as IdentityWithUnused>::This; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | ^^^^^^^^^^^-------------^ + | | | + | | found this const parameter + | expected `usize`, found `bool` | note: required for `()` to implement `IdentityWithUnused` --> $DIR/check_const_arg_type_in_free_alias.rs:27:25 @@ -62,7 +71,10 @@ error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_free_alias.rs:37:1 | LL | type UseFree = Free; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | ^^^^^^^^^^^^^-------------^ + | | | + | | found this const parameter + | expected `usize`, found `bool` | note: required by a bound on the type alias `Free` --> $DIR/check_const_arg_type_in_free_alias.rs:36:11 @@ -86,7 +98,10 @@ error: the constant `N` is not of type `bool` --> $DIR/check_const_arg_type_in_free_alias.rs:50:1 | LL | type UseFreeIndirectlyCorrect = UseFree; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `usize` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------^ + | | | + | | found this const parameter + | expected `bool`, found `usize` | note: required by a bound on the type alias `UseFree` --> $DIR/check_const_arg_type_in_free_alias.rs:37:14 @@ -110,7 +125,10 @@ error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_free_alias.rs:57:1 | LL | type IndirectArr = Wrap>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | ^^^^^^^^^^^^^^^^^-------------^ + | | | + | | found this const parameter + | expected `usize`, found `bool` | = note: the length of array `[(); B]` must be type `usize` @@ -126,7 +144,10 @@ error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_free_alias.rs:61:1 | LL | type IndirectConstArg = Wrap>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | ^^^^^^^^^^^^^^^^^^^^^^-------------^ + | | | + | | found this const parameter + | expected `usize`, found `bool` | note: required by a const generic parameter in `Foo` --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 diff --git a/tests/ui/const-generics/check_const_arg_type_in_free_alias.unchecked.stderr b/tests/ui/const-generics/check_const_arg_type_in_free_alias.unchecked.stderr index 2e12050cbd777..0f69f9c659f6b 100644 --- a/tests/ui/const-generics/check_const_arg_type_in_free_alias.unchecked.stderr +++ b/tests/ui/const-generics/check_const_arg_type_in_free_alias.unchecked.stderr @@ -2,7 +2,10 @@ error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_free_alias.rs:14:1 | LL | type ArrLen = [(); B]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | ^^^^^^^^^^^^-------------^ + | | | + | | found this const parameter + | expected `usize`, found `bool` | = note: the length of array `[(); B]` must be type `usize` @@ -10,7 +13,10 @@ error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_free_alias.rs:18:1 | LL | type ConstArg = Foo; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | ^^^^^^^^^^^^^^-------------^ + | | | + | | found this const parameter + | expected `usize`, found `bool` | note: required by a const generic parameter in `Foo` --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 @@ -22,7 +28,10 @@ error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_free_alias.rs:31:1 | LL | type Alias = <() as IdentityWithUnused>::This; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | ^^^^^^^^^^^-------------^ + | | | + | | found this const parameter + | expected `usize`, found `bool` | note: required by a const generic parameter in `IdentityWithUnused` --> $DIR/check_const_arg_type_in_free_alias.rs:23:26 @@ -34,7 +43,10 @@ error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_free_alias.rs:37:1 | LL | type UseFree = Free; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | ^^^^^^^^^^^^^-------------^ + | | | + | | found this const parameter + | expected `usize`, found `bool` | = note: the length of array `[(); B]` must be type `usize` @@ -42,7 +54,10 @@ error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_free_alias.rs:57:1 | LL | type IndirectArr = Wrap>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | ^^^^^^^^^^^^^^^^^-------------^ + | | | + | | found this const parameter + | expected `usize`, found `bool` | = note: the length of array `[(); B]` must be type `usize` @@ -50,7 +65,10 @@ error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_free_alias.rs:61:1 | LL | type IndirectConstArg = Wrap>>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | ^^^^^^^^^^^^^^^^^^^^^^-------------^ + | | | + | | found this const parameter + | expected `usize`, found `bool` | note: required by a const generic parameter in `Foo` --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 diff --git a/tests/ui/const-generics/check_const_arg_type_in_trait_object.stderr b/tests/ui/const-generics/check_const_arg_type_in_trait_object.stderr index 4e228f65ab6df..2b17effbae916 100644 --- a/tests/ui/const-generics/check_const_arg_type_in_trait_object.stderr +++ b/tests/ui/const-generics/check_const_arg_type_in_trait_object.stderr @@ -7,6 +7,8 @@ LL | anon: &dyn Object, error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_trait_object.rs:16:12 | +LL | fn arg( + | ------------- found this const parameter LL | param: &dyn Object, | ^^^^^^^^^^^^^^ expected `usize`, found `bool` | @@ -27,6 +29,8 @@ LL | anon: &dyn Object2>, error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_trait_object.rs:24:12 | +LL | fn indirect( + | ------------- found this const parameter LL | param: &dyn Object2>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | @@ -36,7 +40,9 @@ error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_trait_object.rs:33:33 | LL | fn binder(param: &dyn for<'a> Object3<'a, B>) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | | + | found this const parameter | note: required by a const generic parameter in `Object3` --> $DIR/check_const_arg_type_in_trait_object.rs:11:28 diff --git a/tests/ui/const-generics/defaults/concrete-const-param-type.stderr b/tests/ui/const-generics/defaults/concrete-const-param-type.stderr index 805d5a1e91fb4..bebddb23e8543 100644 --- a/tests/ui/const-generics/defaults/concrete-const-param-type.stderr +++ b/tests/ui/const-generics/defaults/concrete-const-param-type.stderr @@ -2,7 +2,9 @@ error: the constant `N` is not of type `u64` --> $DIR/concrete-const-param-type.rs:7:26 | LL | struct Foo; - | ^^^^^^^^^^^^^^^^ expected `u64`, found `u32` + | ------------ ^^^^^^^^^^^^^^^^ expected `u64`, found `u32` + | | + | found this const parameter error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/dyn-trait-ill-typed.stderr b/tests/ui/const-generics/dyn-trait-ill-typed.stderr index 8917b53d4d826..073789957af9d 100644 --- a/tests/ui/const-generics/dyn-trait-ill-typed.stderr +++ b/tests/ui/const-generics/dyn-trait-ill-typed.stderr @@ -2,7 +2,9 @@ error: the constant `M` is not of type `usize` --> $DIR/dyn-trait-ill-typed.rs:9:27 | LL | fn foo() -> Box> { - | ^^^^^^^^^^^^^^ expected `usize`, found `u32` + | ------------ ^^^^^^^^^^^^^^ expected `usize`, found `u32` + | | + | found this const parameter | note: required by a const generic parameter in `Tr` --> $DIR/dyn-trait-ill-typed.rs:13:10 diff --git a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr index 3b4b5798c805e..0799f4b829495 100644 --- a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr +++ b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr @@ -11,7 +11,9 @@ error: the constant `N` is not of type `usize` --> $DIR/type_mismatch.rs:8:26 | LL | impl Q for [u8; N] {} - | ^^^^^^^ expected `usize`, found `u64` + | ------------ ^^^^^^^ expected `usize`, found `u64` + | | + | found this const parameter | = note: the length of array `[u8; N]` must be type `usize` diff --git a/tests/ui/const-generics/impl-block-missing-const-generics.stderr b/tests/ui/const-generics/impl-block-missing-const-generics.stderr index 2f504ddadda30..b0c6033d8b82f 100644 --- a/tests/ui/const-generics/impl-block-missing-const-generics.stderr +++ b/tests/ui/const-generics/impl-block-missing-const-generics.stderr @@ -77,7 +77,9 @@ error: the constant `AHA` is not of type `usize` --> $DIR/impl-block-missing-const-generics.rs:30:26 | LL | impl Foo {} - | ^^^^^^^^ expected `usize`, found `u32` + | -------------- ^^^^^^^^ expected `usize`, found `u32` + | | + | found this const parameter | note: required by a const generic parameter in `e::Foo` --> $DIR/impl-block-missing-const-generics.rs:28:16 @@ -133,7 +135,9 @@ error: the constant `AHA` is not of type `usize` --> $DIR/impl-block-missing-const-generics.rs:72:26 | LL | impl T for Foo {} - | ^^^^^^ expected `usize`, found `u32` + | -------------- ^^^^^^ expected `usize`, found `u32` + | | + | found this const parameter | note: required by a const generic parameter in `k::T` --> $DIR/impl-block-missing-const-generics.rs:70:13 diff --git a/tests/ui/const-generics/issues/index_array_bad_type.stderr b/tests/ui/const-generics/issues/index_array_bad_type.stderr index ceea097337764..a877cdecc7b24 100644 --- a/tests/ui/const-generics/issues/index_array_bad_type.stderr +++ b/tests/ui/const-generics/issues/index_array_bad_type.stderr @@ -2,7 +2,9 @@ error: the constant `N` is not of type `usize` --> $DIR/index_array_bad_type.rs:1:34 | LL | struct Struct(pub [u8; N]); - | ^^^^^^^ expected `usize`, found `i128` + | ------------- ^^^^^^^ expected `usize`, found `i128` + | | + | found this const parameter | = note: the length of array `[u8; N]` must be type `usize` diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.stderr b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.stderr index 2e06d4f2ce058..a976cdb576c7f 100644 --- a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.stderr +++ b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.stderr @@ -1,12 +1,17 @@ error: the constant `N` is not of type `u32` --> $DIR/adt_expr_arg_tuple_expr_fail.rs:18:21 | +LL | fn generic_caller() { + | -------------- found this const parameter LL | takes_tuple::<{ (N, N2) }>(); | ^^^^^^^ expected `u32`, found `usize` error: the constant `N` is not of type `u32` --> $DIR/adt_expr_arg_tuple_expr_fail.rs:20:21 | +LL | fn generic_caller() { + | -------------- found this const parameter +... LL | takes_tuple::<{ (N, T::ASSOC) }>(); | ^^^^^^^^^^^^^ expected `u32`, found `usize` @@ -19,12 +24,18 @@ LL | takes_tuple::<{ (N, T::ASSOC) }>(); error: the constant `N` is not of type `u32` --> $DIR/adt_expr_arg_tuple_expr_fail.rs:24:28 | +LL | fn generic_caller() { + | -------------- found this const parameter +... LL | takes_nested_tuple::<{ (N, (N, N2)) }>(); | ^^^^^^^^^^^^ expected `u32`, found `usize` error: the constant `N` is not of type `u32` --> $DIR/adt_expr_arg_tuple_expr_fail.rs:26:28 | +LL | fn generic_caller() { + | -------------- found this const parameter +... LL | takes_nested_tuple::<{ (N, (N, T::ASSOC)) }>(); | ^^^^^^^^^^^^^^^^^^ expected `u32`, found `usize` diff --git a/tests/ui/const-generics/mgca/adt_expr_fields_type_check.stderr b/tests/ui/const-generics/mgca/adt_expr_fields_type_check.stderr index dea156db19c14..0f7f6e86baf1d 100644 --- a/tests/ui/const-generics/mgca/adt_expr_fields_type_check.stderr +++ b/tests/ui/const-generics/mgca/adt_expr_fields_type_check.stderr @@ -1,36 +1,52 @@ error: the constant `N` is not of type `u8` --> $DIR/adt_expr_fields_type_check.rs:23:19 | +LL | fn bar() { + | ------------- found this const parameter LL | accepts_1::<{ S1:: { f1: N, f2: N } }>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `bool` error: the constant `N` is not of type `isize` --> $DIR/adt_expr_fields_type_check.rs:23:19 | +LL | fn bar() { + | ------------- found this const parameter LL | accepts_1::<{ S1:: { f1: N, f2: N } }>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `bool` error: the constant `N` is not of type `u8` --> $DIR/adt_expr_fields_type_check.rs:26:19 | +LL | fn bar() { + | ------------- found this const parameter +... LL | accepts_2::<{ S2::(N, N) }>(); | ^^^^^^^^^^^^^^ expected `u8`, found `bool` error: the constant `N` is not of type `isize` --> $DIR/adt_expr_fields_type_check.rs:26:19 | +LL | fn bar() { + | ------------- found this const parameter +... LL | accepts_2::<{ S2::(N, N) }>(); | ^^^^^^^^^^^^^^ expected `isize`, found `bool` error: the constant `N` is not of type `u8` --> $DIR/adt_expr_fields_type_check.rs:29:19 | +LL | fn bar() { + | ------------- found this const parameter +... LL | accepts_3::<{ En::Var1::(N, N) }>(); | ^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `bool` error: the constant `N` is not of type `i64` --> $DIR/adt_expr_fields_type_check.rs:31:19 | +LL | fn bar() { + | ------------- found this const parameter +... LL | accepts_3::<{ En::Var2:: { field: N } }>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i64`, found `bool` diff --git a/tests/ui/const-generics/transmute-fail.stderr b/tests/ui/const-generics/transmute-fail.stderr index 953119a8c3413..2008843f5d401 100644 --- a/tests/ui/const-generics/transmute-fail.stderr +++ b/tests/ui/const-generics/transmute-fail.stderr @@ -2,13 +2,18 @@ error: the constant `W` is not of type `usize` --> $DIR/transmute-fail.rs:16:42 | LL | fn bar(v: [[u32; H]; W]) -> [[u32; W]; H] { - | ^^^^^^^^^^^^^ expected `usize`, found `bool` + | ------------- ^^^^^^^^^^^^^ expected `usize`, found `bool` + | | + | found this const parameter | = note: the length of array `[[u32; H]; W]` must be type `usize` error: the constant `W` is not of type `usize` --> $DIR/transmute-fail.rs:19:9 | +LL | fn bar(v: [[u32; H]; W]) -> [[u32; W]; H] { + | ------------- found this const parameter +... LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | diff --git a/tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr b/tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr index c6fb07926c802..bacd670672d77 100644 --- a/tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr +++ b/tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr @@ -2,7 +2,9 @@ error: the constant `N` is not of type `bool` --> $DIR/type-mismatch-in-nested-goal.rs:9:50 | LL | fn needs_a(_: [u8; N]) where (): A {} - | ^^^^ expected `bool`, found `usize` + | -------------- ^^^^ expected `bool`, found `usize` + | | + | found this const parameter | note: required by a const generic parameter in `A` --> $DIR/type-mismatch-in-nested-goal.rs:5:9 diff --git a/tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr b/tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr index c6fb07926c802..bacd670672d77 100644 --- a/tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr +++ b/tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr @@ -2,7 +2,9 @@ error: the constant `N` is not of type `bool` --> $DIR/type-mismatch-in-nested-goal.rs:9:50 | LL | fn needs_a(_: [u8; N]) where (): A {} - | ^^^^ expected `bool`, found `usize` + | -------------- ^^^^ expected `bool`, found `usize` + | | + | found this const parameter | note: required by a const generic parameter in `A` --> $DIR/type-mismatch-in-nested-goal.rs:5:9 diff --git a/tests/ui/const-generics/type_mismatch.stderr b/tests/ui/const-generics/type_mismatch.stderr index bd169ed2ec8f5..d45365e1a32d5 100644 --- a/tests/ui/const-generics/type_mismatch.stderr +++ b/tests/ui/const-generics/type_mismatch.stderr @@ -2,13 +2,17 @@ error: the constant `N` is not of type `usize` --> $DIR/type_mismatch.rs:6:26 | LL | fn bar() -> [u8; N] {} - | ^^^^^^^ expected `usize`, found `u8` + | ----------- ^^^^^^^ expected `usize`, found `u8` + | | + | found this const parameter | = note: the length of array `[u8; N]` must be type `usize` error: the constant `N` is not of type `u8` --> $DIR/type_mismatch.rs:2:11 | +LL | fn foo() -> [u8; N] { + | -------------- found this const parameter LL | bar::() | ^ expected `u8`, found `usize` | diff --git a/tests/ui/consts/bad-array-size-in-type-err.stderr b/tests/ui/consts/bad-array-size-in-type-err.stderr index 13b0b6c4f4a65..094e837c0e5c1 100644 --- a/tests/ui/consts/bad-array-size-in-type-err.stderr +++ b/tests/ui/consts/bad-array-size-in-type-err.stderr @@ -1,6 +1,8 @@ error: the constant `N` is not of type `usize` --> $DIR/bad-array-size-in-type-err.rs:2:10 | +LL | struct BadArraySize { + | ----------- found this const parameter LL | arr: [i32; N], | ^^^^^^^^ expected `usize`, found `u8` | @@ -10,7 +12,9 @@ error: the constant `N` is not of type `usize` --> $DIR/bad-array-size-in-type-err.rs:19:32 | LL | pub struct Blorb([String; N]); - | ^^^^^^^^^^^ expected `usize`, found `u16` + | ------------ ^^^^^^^^^^^ expected `usize`, found `u16` + | | + | found this const parameter | = note: the length of array `[String; N]` must be type `usize` diff --git a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr index 8df76b296acd6..976c9eb6baa55 100644 --- a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr +++ b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr @@ -10,7 +10,9 @@ error: the constant `C` is not of type `::Type` --> $DIR/default-proj-ty-as-type-of-const-issue-125757.rs:15:22 | LL | impl Wrapper {} - | ^^^^^^^^^^ expected associated type, found `usize` + | -------------- ^^^^^^^^^^ expected associated type, found `usize` + | | + | found this const parameter | = help: consider constraining the associated type `::Type` to `usize` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html diff --git a/tests/ui/transmutability/malformed-program-gracefulness/wrong-adt-assume.stderr b/tests/ui/transmutability/malformed-program-gracefulness/wrong-adt-assume.stderr index cae700ecfdc77..b5cf6c92374c7 100644 --- a/tests/ui/transmutability/malformed-program-gracefulness/wrong-adt-assume.stderr +++ b/tests/ui/transmutability/malformed-program-gracefulness/wrong-adt-assume.stderr @@ -1,6 +1,9 @@ error: the constant `ASSUME` is not of type `Assume` --> $DIR/wrong-adt-assume.rs:14:9 | +LL | fn foo() + | ----------------------- found this const parameter +LL | where LL | u8: TransmuteFrom, | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Assume`, found `NotAssume` | diff --git a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.current.stderr b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.current.stderr index 92ad83c330000..e6f72b9b55fa7 100644 --- a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.current.stderr +++ b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.current.stderr @@ -8,7 +8,9 @@ error: the constant `N` is not of type `usize` --> $DIR/const-in-impl-fn-return-type.rs:12:32 | LL | fn func() -> [(); N]; - | ^^^^^^^ expected `usize`, found `u32` + | ------------ ^^^^^^^ expected `usize`, found `u32` + | | + | found this const parameter | = note: the length of array `[(); N]` must be type `usize` diff --git a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.next.stderr b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.next.stderr index 92ad83c330000..e6f72b9b55fa7 100644 --- a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.next.stderr +++ b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.next.stderr @@ -8,7 +8,9 @@ error: the constant `N` is not of type `usize` --> $DIR/const-in-impl-fn-return-type.rs:12:32 | LL | fn func() -> [(); N]; - | ^^^^^^^ expected `usize`, found `u32` + | ------------ ^^^^^^^ expected `usize`, found `u32` + | | + | found this const parameter | = note: the length of array `[(); N]` must be type `usize` diff --git a/tests/ui/wf/wf-dyn-in-hrtb-bound-const-mismatch.stderr b/tests/ui/wf/wf-dyn-in-hrtb-bound-const-mismatch.stderr index 317fbb5dcafe1..704e45bc1ac89 100644 --- a/tests/ui/wf/wf-dyn-in-hrtb-bound-const-mismatch.stderr +++ b/tests/ui/wf/wf-dyn-in-hrtb-bound-const-mismatch.stderr @@ -2,7 +2,9 @@ error: the constant `B` is not of type `usize` --> $DIR/wf-dyn-in-hrtb-bound-const-mismatch.rs:16:30 | LL | fn nested(_f: &dyn for<'a> Fn(&'a (), &'a dyn HasConst<'a, B>)) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | | + | found this const parameter | note: required by a const generic parameter in `HasConst` --> $DIR/wf-dyn-in-hrtb-bound-const-mismatch.rs:14:20 From 37d16423a75ae65764990f225c9af4ea9ddbd8fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 23 Oct 2026 02:19:58 +0000 Subject: [PATCH 19/31] Point at type alias type on failed obligations ``` error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_free_alias.rs:15:30 | LL | type ArrLen = [(); B]; | ------------- ^^^^^^^ expected `usize`, found `bool` | | | found this const parameter | = note: the length of array `[(); B]` must be type `usize` ``` --- .../rustc_hir_analysis/src/check/check.rs | 7 ++- ...st_arg_type_in_free_alias.unchecked.stderr | 54 +++++++++---------- .../invalid-coerce-shared-next-solver.stderr | 4 +- ...ow-impl-phantom-data-wrong-generics.stderr | 4 +- 4 files changed, 34 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index ea0840ff1e893..f51201603c7bf 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -989,6 +989,11 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), tcx.ensure_ok().clauses_of(def_id); let ty = tcx.type_of(def_id).instantiate_identity(); let span = tcx.def_span(def_id); + let ty_span = match tcx.hir_node_by_def_id(def_id).alias_ty() { + Some(ty) => ty.span, + _ => span, + }; + if tcx.type_alias_is_checked(def_id) { res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| { let item_ty = wfcx.deeply_normalize(span, WellFormedLoc::Ty(def_id), ty); @@ -1009,7 +1014,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), // // Changing this to normalized obligations is a breaking change: // `type Bar = [(); panic!()];` would become an error - if let Some(unnormalized_obligations) = wfcx.unnormalized_obligations(span, ty.skip_norm_wip()) + if let Some(unnormalized_obligations) = wfcx.unnormalized_obligations(ty_span, ty.skip_norm_wip()) { let filtered_obligations = unnormalized_obligations.into_iter().filter(|o| { diff --git a/tests/ui/const-generics/check_const_arg_type_in_free_alias.unchecked.stderr b/tests/ui/const-generics/check_const_arg_type_in_free_alias.unchecked.stderr index 0f69f9c659f6b..ebf27e6eac603 100644 --- a/tests/ui/const-generics/check_const_arg_type_in_free_alias.unchecked.stderr +++ b/tests/ui/const-generics/check_const_arg_type_in_free_alias.unchecked.stderr @@ -1,22 +1,20 @@ error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:14:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:14:30 | LL | type ArrLen = [(); B]; - | ^^^^^^^^^^^^-------------^ - | | | - | | found this const parameter - | expected `usize`, found `bool` + | ------------- ^^^^^^^ expected `usize`, found `bool` + | | + | found this const parameter | = note: the length of array `[(); B]` must be type `usize` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:18:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:18:32 | LL | type ConstArg = Foo; - | ^^^^^^^^^^^^^^-------------^ - | | | - | | found this const parameter - | expected `usize`, found `bool` + | ------------- ^^^^^^ expected `usize`, found `bool` + | | + | found this const parameter | note: required by a const generic parameter in `Foo` --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 @@ -25,13 +23,12 @@ LL | struct Foo; | ^^^^^^^^^^^^^^ required by this const generic parameter in `Foo` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:31:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:31:29 | LL | type Alias = <() as IdentityWithUnused>::This; - | ^^^^^^^^^^^-------------^ - | | | - | | found this const parameter - | expected `usize`, found `bool` + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | | + | found this const parameter | note: required by a const generic parameter in `IdentityWithUnused` --> $DIR/check_const_arg_type_in_free_alias.rs:23:26 @@ -40,35 +37,32 @@ LL | trait IdentityWithUnused { | ^^^^^^^^^^^^^^ required by this const generic parameter in `IdentityWithUnused` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:37:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:37:31 | LL | type UseFree = Free; - | ^^^^^^^^^^^^^-------------^ - | | | - | | found this const parameter - | expected `usize`, found `bool` + | ------------- ^^^^^^^ expected `usize`, found `bool` + | | + | found this const parameter | = note: the length of array `[(); B]` must be type `usize` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:57:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:57:35 | LL | type IndirectArr = Wrap>; - | ^^^^^^^^^^^^^^^^^-------------^ - | | | - | | found this const parameter - | expected `usize`, found `bool` + | ------------- ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | | + | found this const parameter | = note: the length of array `[(); B]` must be type `usize` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:61:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:61:40 | LL | type IndirectConstArg = Wrap>>; - | ^^^^^^^^^^^^^^^^^^^^^^-------------^ - | | | - | | found this const parameter - | expected `usize`, found `bool` + | ------------- ^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | | + | found this const parameter | note: required by a const generic parameter in `Foo` --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 diff --git a/tests/ui/reborrow/invalid-coerce-shared-next-solver.stderr b/tests/ui/reborrow/invalid-coerce-shared-next-solver.stderr index cec4602ecc37f..044abed91ec0a 100644 --- a/tests/ui/reborrow/invalid-coerce-shared-next-solver.stderr +++ b/tests/ui/reborrow/invalid-coerce-shared-next-solver.stderr @@ -28,8 +28,8 @@ LL | impl<'a, T> CoerceShared for CustomMut<'reborrow, T> {} | help: add missing generic argument | -LL | impl<'a, T> CoerceShared for CustomMut<'reborrow, T> {} - | ++++++++ +LL | impl CoerceShared for CustomMut<'reborrow, T> {} + | +++++++ ++++++++ error[E0377]: the trait `CoerceShared` may only be implemented for a coercion between structures --> $DIR/invalid-coerce-shared-next-solver.rs:11:1 diff --git a/tests/ui/reborrow/invalid-reborrow-impl-phantom-data-wrong-generics.stderr b/tests/ui/reborrow/invalid-reborrow-impl-phantom-data-wrong-generics.stderr index 9f9bd5008c81e..aaf80330687c0 100644 --- a/tests/ui/reborrow/invalid-reborrow-impl-phantom-data-wrong-generics.stderr +++ b/tests/ui/reborrow/invalid-reborrow-impl-phantom-data-wrong-generics.stderr @@ -14,8 +14,8 @@ LL | impl<'a> Reborrow for PhantomData<'a> {} | help: add missing generic argument | -LL | impl<'a> Reborrow for PhantomData<'a, T> {} - | +++ +LL | impl Reborrow for PhantomData<'a, T> {} + | ++ +++ error: implementing `Reborrow` requires exactly one lifetime argument in the reborrowed type --> $DIR/invalid-reborrow-impl-phantom-data-wrong-generics.rs:9:1 From 1be208ec841a0afe9971c697e0d71da5446fd96e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 23 Oct 2026 17:40:14 +0000 Subject: [PATCH 20/31] Tweak span of WF errors in type aliases --- .../rustc_hir_analysis/src/check/check.rs | 7 +-- .../def-site-body-wf.stderr | 4 +- .../inherent-impls-overflow.current.stderr | 12 ++-- .../inherent-impls-overflow.next.stderr | 12 ++-- .../opaq-ty-collection-infinite-recur.stderr | 4 +- ...sive-type-alias-in-const-projection.stderr | 4 +- ...ined-params-in-impl-due-to-overflow.stderr | 4 +- .../variance-overflow.stderr | 8 +-- ...onst_arg_type_in_free_alias.checked.stderr | 63 +++++++++---------- ...-alias-mutual-recursion.feature_new.stderr | 12 ++-- ...-alias-mutual-recursion.feature_old.stderr | 12 ++-- ...infinite-vec-type-recursion.feature.stderr | 4 +- .../issue-118950-root-region.stderr | 4 +- 13 files changed, 71 insertions(+), 79 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs index f51201603c7bf..495e8e5590eed 100644 --- a/compiler/rustc_hir_analysis/src/check/check.rs +++ b/compiler/rustc_hir_analysis/src/check/check.rs @@ -988,10 +988,9 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), tcx.ensure_ok().type_of(def_id); tcx.ensure_ok().clauses_of(def_id); let ty = tcx.type_of(def_id).instantiate_identity(); - let span = tcx.def_span(def_id); - let ty_span = match tcx.hir_node_by_def_id(def_id).alias_ty() { + let span = match tcx.hir_node_by_def_id(def_id).alias_ty() { Some(ty) => ty.span, - _ => span, + _ => tcx.def_span(def_id), }; if tcx.type_alias_is_checked(def_id) { @@ -1014,7 +1013,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), // // Changing this to normalized obligations is a breaking change: // `type Bar = [(); panic!()];` would become an error - if let Some(unnormalized_obligations) = wfcx.unnormalized_obligations(ty_span, ty.skip_norm_wip()) + if let Some(unnormalized_obligations) = wfcx.unnormalized_obligations(span, ty.skip_norm_wip()) { let filtered_obligations = unnormalized_obligations.into_iter().filter(|o| { diff --git a/tests/ui/checked-type-aliases/def-site-body-wf.stderr b/tests/ui/checked-type-aliases/def-site-body-wf.stderr index 99ebc95616816..bef47b92e9d17 100644 --- a/tests/ui/checked-type-aliases/def-site-body-wf.stderr +++ b/tests/ui/checked-type-aliases/def-site-body-wf.stderr @@ -20,10 +20,10 @@ note: required by an implicit `Sized` bound in `Vec` --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL error[E0491]: in type `&'static &'a ()`, reference has a longer lifetime than the data it references - --> $DIR/def-site-body-wf.rs:11:1 + --> $DIR/def-site-body-wf.rs:11:15 | LL | type _C<'a> = &'static &'a (); - | ^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ | = note: the pointer is valid for the static lifetime note: but the referenced data is only valid for the lifetime `'a` as defined here diff --git a/tests/ui/checked-type-aliases/inherent-impls-overflow.current.stderr b/tests/ui/checked-type-aliases/inherent-impls-overflow.current.stderr index a4d208a8fc24c..28a62b39c7fdc 100644 --- a/tests/ui/checked-type-aliases/inherent-impls-overflow.current.stderr +++ b/tests/ui/checked-type-aliases/inherent-impls-overflow.current.stderr @@ -1,8 +1,8 @@ error[E0275]: overflow normalizing the type alias `Loop` - --> $DIR/inherent-impls-overflow.rs:8:1 + --> $DIR/inherent-impls-overflow.rs:8:13 | LL | type Loop = Loop; - | ^^^^^^^^^ + | ^^^^ | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead @@ -15,18 +15,18 @@ LL | impl Loop {} = note: in case this is a recursive type alias, consider using a struct, enum, or union instead error[E0275]: overflow normalizing the type alias `Poly0<(((((((_,),),),),),),)>` - --> $DIR/inherent-impls-overflow.rs:17:1 + --> $DIR/inherent-impls-overflow.rs:17:17 | LL | type Poly0 = Poly1<(T,)>; - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^ | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead error[E0275]: overflow normalizing the type alias `Poly1<(((((((_,),),),),),),)>` - --> $DIR/inherent-impls-overflow.rs:20:1 + --> $DIR/inherent-impls-overflow.rs:20:17 | LL | type Poly1 = Poly0<(T,)>; - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^ | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead diff --git a/tests/ui/checked-type-aliases/inherent-impls-overflow.next.stderr b/tests/ui/checked-type-aliases/inherent-impls-overflow.next.stderr index dbd982ea94c36..31875a47a9b7d 100644 --- a/tests/ui/checked-type-aliases/inherent-impls-overflow.next.stderr +++ b/tests/ui/checked-type-aliases/inherent-impls-overflow.next.stderr @@ -1,8 +1,8 @@ error[E0275]: overflow evaluating the requirement `Loop == _` - --> $DIR/inherent-impls-overflow.rs:8:1 + --> $DIR/inherent-impls-overflow.rs:8:13 | LL | type Loop = Loop; - | ^^^^^^^^^ + | ^^^^ error[E0275]: overflow evaluating the requirement `Loop == _` --> $DIR/inherent-impls-overflow.rs:12:1 @@ -17,18 +17,18 @@ LL | impl Loop {} | ^^^^ error[E0275]: overflow evaluating the requirement `Poly1<(T,)> == _` - --> $DIR/inherent-impls-overflow.rs:17:1 + --> $DIR/inherent-impls-overflow.rs:17:17 | LL | type Poly0 = Poly1<(T,)>; - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`) error[E0275]: overflow evaluating the requirement `Poly0<(T,)> == _` - --> $DIR/inherent-impls-overflow.rs:20:1 + --> $DIR/inherent-impls-overflow.rs:20:17 | LL | type Poly1 = Poly0<(T,)>; - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^ | = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_impls_overflow`) diff --git a/tests/ui/checked-type-aliases/opaq-ty-collection-infinite-recur.stderr b/tests/ui/checked-type-aliases/opaq-ty-collection-infinite-recur.stderr index e93fcd03a9662..17f57d9778349 100644 --- a/tests/ui/checked-type-aliases/opaq-ty-collection-infinite-recur.stderr +++ b/tests/ui/checked-type-aliases/opaq-ty-collection-infinite-recur.stderr @@ -1,8 +1,8 @@ error[E0275]: overflow normalizing the type alias `Recur` - --> $DIR/opaq-ty-collection-infinite-recur.rs:16:20 + --> $DIR/opaq-ty-collection-infinite-recur.rs:16:33 | LL | struct Hold([(); { type Recur = Recur; 0 }]); - | ^^^^^^^^^^ + | ^^^^^ | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead diff --git a/tests/ui/checked-type-aliases/recursive-type-alias-in-const-projection.stderr b/tests/ui/checked-type-aliases/recursive-type-alias-in-const-projection.stderr index 471fa8eb1fd67..1f21ad286f723 100644 --- a/tests/ui/checked-type-aliases/recursive-type-alias-in-const-projection.stderr +++ b/tests/ui/checked-type-aliases/recursive-type-alias-in-const-projection.stderr @@ -1,8 +1,8 @@ error[E0275]: overflow normalizing the type alias `Arr2` - --> $DIR/recursive-type-alias-in-const-projection.rs:12:1 + --> $DIR/recursive-type-alias-in-const-projection.rs:12:13 | LL | type Arr2 = [usize; ::ASSOC]; - | ^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead diff --git a/tests/ui/checked-type-aliases/unconstrained-params-in-impl-due-to-overflow.stderr b/tests/ui/checked-type-aliases/unconstrained-params-in-impl-due-to-overflow.stderr index d8270a0abddcd..bcffa02ddd424 100644 --- a/tests/ui/checked-type-aliases/unconstrained-params-in-impl-due-to-overflow.stderr +++ b/tests/ui/checked-type-aliases/unconstrained-params-in-impl-due-to-overflow.stderr @@ -5,10 +5,10 @@ LL | impl Loop {} | ^ unconstrained type parameter error[E0275]: overflow normalizing the type alias `Loop` - --> $DIR/unconstrained-params-in-impl-due-to-overflow.rs:6:1 + --> $DIR/unconstrained-params-in-impl-due-to-overflow.rs:6:16 | LL | type Loop = Loop; - | ^^^^^^^^^^^^ + | ^^^^^^^ | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead diff --git a/tests/ui/checked-type-aliases/variance-overflow.stderr b/tests/ui/checked-type-aliases/variance-overflow.stderr index 3ea61d9ade9f3..a17d7e7119b60 100644 --- a/tests/ui/checked-type-aliases/variance-overflow.stderr +++ b/tests/ui/checked-type-aliases/variance-overflow.stderr @@ -16,18 +16,18 @@ LL | struct First(Second); = note: in case this is a recursive type alias, consider using a struct, enum, or union instead error[E0275]: overflow normalizing the type alias `Second` - --> $DIR/variance-overflow.rs:19:1 + --> $DIR/variance-overflow.rs:19:15 | LL | type Second = Second; // diverging free alias type - | ^^^^^^^^^^^ + | ^^^^^^ | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead error[E0275]: overflow normalizing the type alias `Diverging<(((((((_,),),),),),),)>` - --> $DIR/variance-overflow.rs:26:1 + --> $DIR/variance-overflow.rs:26:21 | LL | type Diverging = Diverging<(T,)>; - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^ | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead diff --git a/tests/ui/const-generics/check_const_arg_type_in_free_alias.checked.stderr b/tests/ui/const-generics/check_const_arg_type_in_free_alias.checked.stderr index 087eb0a41a80b..f7bfe0a1daf1a 100644 --- a/tests/ui/const-generics/check_const_arg_type_in_free_alias.checked.stderr +++ b/tests/ui/const-generics/check_const_arg_type_in_free_alias.checked.stderr @@ -1,11 +1,10 @@ error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:14:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:14:30 | LL | type ArrLen = [(); B]; - | ^^^^^^^^^^^^-------------^ - | | | - | | found this const parameter - | expected `usize`, found `bool` + | ------------- ^^^^^^^ expected `usize`, found `bool` + | | + | found this const parameter | = note: the length of array `[(); B]` must be type `usize` @@ -18,13 +17,12 @@ LL | type AnonArrLen = [(); true]; = note: array length can only be `usize` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:18:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:18:32 | LL | type ConstArg = Foo; - | ^^^^^^^^^^^^^^-------------^ - | | | - | | found this const parameter - | expected `usize`, found `bool` + | ------------- ^^^^^^ expected `usize`, found `bool` + | | + | found this const parameter | note: required by a const generic parameter in `Foo` --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 @@ -45,13 +43,12 @@ LL | struct Foo; | ^^^^^^^^^^^^^^ error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:31:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:31:29 | LL | type Alias = <() as IdentityWithUnused>::This; - | ^^^^^^^^^^^-------------^ - | | | - | | found this const parameter - | expected `usize`, found `bool` + | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | | + | found this const parameter | note: required for `()` to implement `IdentityWithUnused` --> $DIR/check_const_arg_type_in_free_alias.rs:27:25 @@ -68,13 +65,12 @@ LL | type AnonAlias = <() as IdentityWithUnused>::This; | ^^^^ expected `usize`, found `bool` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:37:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:37:31 | LL | type UseFree = Free; - | ^^^^^^^^^^^^^-------------^ - | | | - | | found this const parameter - | expected `usize`, found `bool` + | ------------- ^^^^^^^ expected `usize`, found `bool` + | | + | found this const parameter | note: required by a bound on the type alias `Free` --> $DIR/check_const_arg_type_in_free_alias.rs:36:11 @@ -95,13 +91,12 @@ LL | type Free = [(); N]; | ^^^^^^^^^^^^^^ error: the constant `N` is not of type `bool` - --> $DIR/check_const_arg_type_in_free_alias.rs:50:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:50:49 | LL | type UseFreeIndirectlyCorrect = UseFree; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--------------^ - | | | - | | found this const parameter - | expected `bool`, found `usize` + | -------------- ^^^^^^^^^^ expected `bool`, found `usize` + | | + | found this const parameter | note: required by a bound on the type alias `UseFree` --> $DIR/check_const_arg_type_in_free_alias.rs:37:14 @@ -122,13 +117,12 @@ LL | type UseFree = Free; | ^^^^^^^^^^^^^ error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:57:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:57:35 | LL | type IndirectArr = Wrap>; - | ^^^^^^^^^^^^^^^^^-------------^ - | | | - | | found this const parameter - | expected `usize`, found `bool` + | ------------- ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | | + | found this const parameter | = note: the length of array `[(); B]` must be type `usize` @@ -141,13 +135,12 @@ LL | type AnonIndirectArr = Wrap>; = note: array length can only be `usize` error: the constant `B` is not of type `usize` - --> $DIR/check_const_arg_type_in_free_alias.rs:61:1 + --> $DIR/check_const_arg_type_in_free_alias.rs:61:40 | LL | type IndirectConstArg = Wrap>>; - | ^^^^^^^^^^^^^^^^^^^^^^-------------^ - | | | - | | found this const parameter - | expected `usize`, found `bool` + | ------------- ^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` + | | + | found this const parameter | note: required by a const generic parameter in `Foo` --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 diff --git a/tests/ui/infinite/infinite-type-alias-mutual-recursion.feature_new.stderr b/tests/ui/infinite/infinite-type-alias-mutual-recursion.feature_new.stderr index 8375055929ce8..2b3d28cbdcab0 100644 --- a/tests/ui/infinite/infinite-type-alias-mutual-recursion.feature_new.stderr +++ b/tests/ui/infinite/infinite-type-alias-mutual-recursion.feature_new.stderr @@ -1,20 +1,20 @@ error[E0275]: overflow evaluating the requirement `X2 == _` - --> $DIR/infinite-type-alias-mutual-recursion.rs:12:1 + --> $DIR/infinite-type-alias-mutual-recursion.rs:12:11 | LL | type X1 = X2; - | ^^^^^^^ + | ^^ error[E0275]: overflow evaluating the requirement `X3 == _` - --> $DIR/infinite-type-alias-mutual-recursion.rs:16:1 + --> $DIR/infinite-type-alias-mutual-recursion.rs:16:11 | LL | type X2 = X3; - | ^^^^^^^ + | ^^ error[E0275]: overflow evaluating the requirement `X1 == _` - --> $DIR/infinite-type-alias-mutual-recursion.rs:19:1 + --> $DIR/infinite-type-alias-mutual-recursion.rs:19:11 | LL | type X3 = X1; - | ^^^^^^^ + | ^^ error: aborting due to 3 previous errors diff --git a/tests/ui/infinite/infinite-type-alias-mutual-recursion.feature_old.stderr b/tests/ui/infinite/infinite-type-alias-mutual-recursion.feature_old.stderr index c7adc3af02fab..717b13aa1a85a 100644 --- a/tests/ui/infinite/infinite-type-alias-mutual-recursion.feature_old.stderr +++ b/tests/ui/infinite/infinite-type-alias-mutual-recursion.feature_old.stderr @@ -1,24 +1,24 @@ error[E0275]: overflow normalizing the type alias `X2` - --> $DIR/infinite-type-alias-mutual-recursion.rs:12:1 + --> $DIR/infinite-type-alias-mutual-recursion.rs:12:11 | LL | type X1 = X2; - | ^^^^^^^ + | ^^ | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead error[E0275]: overflow normalizing the type alias `X3` - --> $DIR/infinite-type-alias-mutual-recursion.rs:16:1 + --> $DIR/infinite-type-alias-mutual-recursion.rs:16:11 | LL | type X2 = X3; - | ^^^^^^^ + | ^^ | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead error[E0275]: overflow normalizing the type alias `X1` - --> $DIR/infinite-type-alias-mutual-recursion.rs:19:1 + --> $DIR/infinite-type-alias-mutual-recursion.rs:19:11 | LL | type X3 = X1; - | ^^^^^^^ + | ^^ | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead diff --git a/tests/ui/infinite/infinite-vec-type-recursion.feature.stderr b/tests/ui/infinite/infinite-vec-type-recursion.feature.stderr index 3e07a46ea2684..5c8d50341c164 100644 --- a/tests/ui/infinite/infinite-vec-type-recursion.feature.stderr +++ b/tests/ui/infinite/infinite-vec-type-recursion.feature.stderr @@ -1,8 +1,8 @@ error[E0275]: overflow normalizing the type alias `X` - --> $DIR/infinite-vec-type-recursion.rs:6:1 + --> $DIR/infinite-vec-type-recursion.rs:6:10 | LL | type X = Vec; - | ^^^^^^ + | ^^^^^^ | = note: in case this is a recursive type alias, consider using a struct, enum, or union instead diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr index eac8b6e11bf1b..37086347bbae1 100644 --- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr +++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr @@ -5,10 +5,10 @@ LL | impl Overlap fn(Assoc<'a, T>)> for T where Missing: Overlap { | ^^^^^^^ not found in this scope error[E0277]: the trait bound `*const T: ToUnit<'a>` is not satisfied - --> $DIR/issue-118950-root-region.rs:13:1 + --> $DIR/issue-118950-root-region.rs:13:21 | LL | type Assoc<'a, T> = <*const T as ToUnit<'a>>::Unit; - | ^^^^^^^^^^^^^^^^^ the trait `ToUnit<'a>` is not implemented for `*const T` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `ToUnit<'a>` is not implemented for `*const T` | help: this trait has no implementations, consider adding one --> $DIR/issue-118950-root-region.rs:7:1 From 3fceff383fec6e8b8738d0e8ca5604622af8c1bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 4 Nov 2026 19:07:47 +0000 Subject: [PATCH 21/31] Reword label ``` error: the constant `N` is not of type `usize` --> $DIR/bad-subst-const-kind.rs:8:26 | LL | impl Q for [u8; N] { | ------------ ^^^^^^^ expected `usize`, found `u64` | | | `N` defined here | = note: the length of array `[u8; N]` must be type `usize` ``` --- .../diagnostics/wrong_number_of_generic_args.rs | 1 - .../error_reporting/traits/fulfillment_errors.rs | 15 ++++++--------- .../mismatched-types-with-generic-in-ace.stderr | 2 +- .../wf-mismatch-1.stderr | 2 +- .../wf-mismatch-2.stderr | 2 +- .../ui/const-generics/bad-subst-const-kind.stderr | 2 +- ...ck_const_arg_type_in_free_alias.checked.stderr | 14 +++++++------- ..._const_arg_type_in_free_alias.unchecked.stderr | 12 ++++++------ .../check_const_arg_type_in_trait_object.stderr | 6 +++--- .../defaults/concrete-const-param-type.stderr | 2 +- .../ui/const-generics/dyn-trait-ill-typed.stderr | 2 +- .../generic_const_exprs/type_mismatch.stderr | 2 +- .../impl-block-missing-const-generics.stderr | 4 ++-- .../issues/index_array_bad_type.stderr | 2 +- .../mgca/adt_expr_arg_tuple_expr_fail.stderr | 8 ++++---- .../mgca/adt_expr_fields_type_check.stderr | 12 ++++++------ tests/ui/const-generics/transmute-fail.stderr | 6 ++---- .../type-mismatch-in-nested-goal.current.stderr | 4 +--- .../type-mismatch-in-nested-goal.next.stderr | 4 +--- tests/ui/const-generics/type_mismatch.stderr | 4 ++-- tests/ui/consts/bad-array-size-in-type-err.stderr | 4 ++-- ...t-proj-ty-as-type-of-const-issue-125757.stderr | 2 +- .../wrong-adt-assume.stderr | 2 +- .../const-in-impl-fn-return-type.current.stderr | 2 +- .../const-in-impl-fn-return-type.next.stderr | 2 +- .../wf/wf-dyn-in-hrtb-bound-const-mismatch.stderr | 2 +- 26 files changed, 55 insertions(+), 65 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs index bd95fa57ff553..3bf7112a45fbb 100644 --- a/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs @@ -795,7 +795,6 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { } debug!(?sugg); err.multipart_suggestion(msg, sugg, Applicability::HasPlaceholders); - // err.note(format!("{:?}", self.cx_def_id)); } } } diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs index 376789ee13194..86fd7ede4a170 100644 --- a/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs +++ b/compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs @@ -879,15 +879,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> { .own_params .iter() { - match param.kind { - GenericParamDefKind::Const { .. } - if param.index == param_const.index - && param.name == param_const.name => - { - let span = self.tcx.def_span(param.def_id); - diag.span_label(span, "found this const parameter"); - } - _ => {} + if let GenericParamDefKind::Const { .. } = param.kind + && param.index == param_const.index + && param.name == param_const.name + { + let span = self.tcx.def_span(param.def_id); + diag.span_label(span, format!("`{}` defined here", param.name)); } } } diff --git a/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr index 086953e3c4fac..8d49782e9645e 100644 --- a/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr +++ b/tests/ui/const-generics/associated-const-bindings/mismatched-types-with-generic-in-ace.stderr @@ -4,7 +4,7 @@ error: the constant `N` is not of type `u32` LL | fn bar = { N }>>() {} | ------------ ^^^^^^^^^^^^^^^^ expected `u32`, found `u64` | | - | found this const parameter + | `N` defined here | note: required by a const generic parameter in `Foo::ASSOC` --> $DIR/mismatched-types-with-generic-in-ace.rs:8:17 diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.stderr b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.stderr index d72a957a61b8f..a378f9bc5de68 100644 --- a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.stderr +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-1.stderr @@ -4,7 +4,7 @@ error: the constant `N` is not of type `bool` LL | fn f(_: impl Trait) {} | ------------ ^^^^^^^^^^ expected `bool`, found `i32` | | - | found this const parameter + | `N` defined here | note: required by a const generic parameter in `f` --> $DIR/wf-mismatch-1.rs:12:34 diff --git a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.stderr b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.stderr index 16168d2a85fe6..14de0154a882b 100644 --- a/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.stderr +++ b/tests/ui/const-generics/associated-const-bindings/wf-mismatch-2.stderr @@ -2,7 +2,7 @@ error: the constant `N` is not of type `bool` --> $DIR/wf-mismatch-2.rs:13:12 | LL | fn f() { - | ------------ found this const parameter + | ------------ `N` defined here LL | let _: dyn Trait; | ^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `i32` diff --git a/tests/ui/const-generics/bad-subst-const-kind.stderr b/tests/ui/const-generics/bad-subst-const-kind.stderr index 331ad62e761ce..e0053a18b0d84 100644 --- a/tests/ui/const-generics/bad-subst-const-kind.stderr +++ b/tests/ui/const-generics/bad-subst-const-kind.stderr @@ -4,7 +4,7 @@ error: the constant `N` is not of type `usize` LL | impl Q for [u8; N] { | ------------ ^^^^^^^ expected `usize`, found `u64` | | - | found this const parameter + | `N` defined here | = note: the length of array `[u8; N]` must be type `usize` diff --git a/tests/ui/const-generics/check_const_arg_type_in_free_alias.checked.stderr b/tests/ui/const-generics/check_const_arg_type_in_free_alias.checked.stderr index f7bfe0a1daf1a..37aae88388ab0 100644 --- a/tests/ui/const-generics/check_const_arg_type_in_free_alias.checked.stderr +++ b/tests/ui/const-generics/check_const_arg_type_in_free_alias.checked.stderr @@ -4,7 +4,7 @@ error: the constant `B` is not of type `usize` LL | type ArrLen = [(); B]; | ------------- ^^^^^^^ expected `usize`, found `bool` | | - | found this const parameter + | `B` defined here | = note: the length of array `[(); B]` must be type `usize` @@ -22,7 +22,7 @@ error: the constant `B` is not of type `usize` LL | type ConstArg = Foo; | ------------- ^^^^^^ expected `usize`, found `bool` | | - | found this const parameter + | `B` defined here | note: required by a const generic parameter in `Foo` --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 @@ -48,7 +48,7 @@ error: the constant `B` is not of type `usize` LL | type Alias = <() as IdentityWithUnused>::This; | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | | - | found this const parameter + | `B` defined here | note: required for `()` to implement `IdentityWithUnused` --> $DIR/check_const_arg_type_in_free_alias.rs:27:25 @@ -70,7 +70,7 @@ error: the constant `B` is not of type `usize` LL | type UseFree = Free; | ------------- ^^^^^^^ expected `usize`, found `bool` | | - | found this const parameter + | `B` defined here | note: required by a bound on the type alias `Free` --> $DIR/check_const_arg_type_in_free_alias.rs:36:11 @@ -96,7 +96,7 @@ error: the constant `N` is not of type `bool` LL | type UseFreeIndirectlyCorrect = UseFree; | -------------- ^^^^^^^^^^ expected `bool`, found `usize` | | - | found this const parameter + | `N` defined here | note: required by a bound on the type alias `UseFree` --> $DIR/check_const_arg_type_in_free_alias.rs:37:14 @@ -122,7 +122,7 @@ error: the constant `B` is not of type `usize` LL | type IndirectArr = Wrap>; | ------------- ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | | - | found this const parameter + | `B` defined here | = note: the length of array `[(); B]` must be type `usize` @@ -140,7 +140,7 @@ error: the constant `B` is not of type `usize` LL | type IndirectConstArg = Wrap>>; | ------------- ^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | | - | found this const parameter + | `B` defined here | note: required by a const generic parameter in `Foo` --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 diff --git a/tests/ui/const-generics/check_const_arg_type_in_free_alias.unchecked.stderr b/tests/ui/const-generics/check_const_arg_type_in_free_alias.unchecked.stderr index ebf27e6eac603..f6c8a06c4d416 100644 --- a/tests/ui/const-generics/check_const_arg_type_in_free_alias.unchecked.stderr +++ b/tests/ui/const-generics/check_const_arg_type_in_free_alias.unchecked.stderr @@ -4,7 +4,7 @@ error: the constant `B` is not of type `usize` LL | type ArrLen = [(); B]; | ------------- ^^^^^^^ expected `usize`, found `bool` | | - | found this const parameter + | `B` defined here | = note: the length of array `[(); B]` must be type `usize` @@ -14,7 +14,7 @@ error: the constant `B` is not of type `usize` LL | type ConstArg = Foo; | ------------- ^^^^^^ expected `usize`, found `bool` | | - | found this const parameter + | `B` defined here | note: required by a const generic parameter in `Foo` --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 @@ -28,7 +28,7 @@ error: the constant `B` is not of type `usize` LL | type Alias = <() as IdentityWithUnused>::This; | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | | - | found this const parameter + | `B` defined here | note: required by a const generic parameter in `IdentityWithUnused` --> $DIR/check_const_arg_type_in_free_alias.rs:23:26 @@ -42,7 +42,7 @@ error: the constant `B` is not of type `usize` LL | type UseFree = Free; | ------------- ^^^^^^^ expected `usize`, found `bool` | | - | found this const parameter + | `B` defined here | = note: the length of array `[(); B]` must be type `usize` @@ -52,7 +52,7 @@ error: the constant `B` is not of type `usize` LL | type IndirectArr = Wrap>; | ------------- ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | | - | found this const parameter + | `B` defined here | = note: the length of array `[(); B]` must be type `usize` @@ -62,7 +62,7 @@ error: the constant `B` is not of type `usize` LL | type IndirectConstArg = Wrap>>; | ------------- ^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | | - | found this const parameter + | `B` defined here | note: required by a const generic parameter in `Foo` --> $DIR/check_const_arg_type_in_free_alias.rs:12:12 diff --git a/tests/ui/const-generics/check_const_arg_type_in_trait_object.stderr b/tests/ui/const-generics/check_const_arg_type_in_trait_object.stderr index 2b17effbae916..272f5a0dd4541 100644 --- a/tests/ui/const-generics/check_const_arg_type_in_trait_object.stderr +++ b/tests/ui/const-generics/check_const_arg_type_in_trait_object.stderr @@ -8,7 +8,7 @@ error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_trait_object.rs:16:12 | LL | fn arg( - | ------------- found this const parameter + | ------------- `B` defined here LL | param: &dyn Object, | ^^^^^^^^^^^^^^ expected `usize`, found `bool` | @@ -30,7 +30,7 @@ error: the constant `B` is not of type `usize` --> $DIR/check_const_arg_type_in_trait_object.rs:24:12 | LL | fn indirect( - | ------------- found this const parameter + | ------------- `B` defined here LL | param: &dyn Object2>, | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | @@ -42,7 +42,7 @@ error: the constant `B` is not of type `usize` LL | fn binder(param: &dyn for<'a> Object3<'a, B>) {} | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | | - | found this const parameter + | `B` defined here | note: required by a const generic parameter in `Object3` --> $DIR/check_const_arg_type_in_trait_object.rs:11:28 diff --git a/tests/ui/const-generics/defaults/concrete-const-param-type.stderr b/tests/ui/const-generics/defaults/concrete-const-param-type.stderr index bebddb23e8543..71d07980d948d 100644 --- a/tests/ui/const-generics/defaults/concrete-const-param-type.stderr +++ b/tests/ui/const-generics/defaults/concrete-const-param-type.stderr @@ -4,7 +4,7 @@ error: the constant `N` is not of type `u64` LL | struct Foo; | ------------ ^^^^^^^^^^^^^^^^ expected `u64`, found `u32` | | - | found this const parameter + | `N` defined here error: aborting due to 1 previous error diff --git a/tests/ui/const-generics/dyn-trait-ill-typed.stderr b/tests/ui/const-generics/dyn-trait-ill-typed.stderr index 073789957af9d..94a6ebc981049 100644 --- a/tests/ui/const-generics/dyn-trait-ill-typed.stderr +++ b/tests/ui/const-generics/dyn-trait-ill-typed.stderr @@ -4,7 +4,7 @@ error: the constant `M` is not of type `usize` LL | fn foo() -> Box> { | ------------ ^^^^^^^^^^^^^^ expected `usize`, found `u32` | | - | found this const parameter + | `M` defined here | note: required by a const generic parameter in `Tr` --> $DIR/dyn-trait-ill-typed.rs:13:10 diff --git a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr index 0799f4b829495..5d6c06f3474be 100644 --- a/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr +++ b/tests/ui/const-generics/generic_const_exprs/type_mismatch.stderr @@ -13,7 +13,7 @@ error: the constant `N` is not of type `usize` LL | impl Q for [u8; N] {} | ------------ ^^^^^^^ expected `usize`, found `u64` | | - | found this const parameter + | `N` defined here | = note: the length of array `[u8; N]` must be type `usize` diff --git a/tests/ui/const-generics/impl-block-missing-const-generics.stderr b/tests/ui/const-generics/impl-block-missing-const-generics.stderr index b0c6033d8b82f..5b5e93d1229e4 100644 --- a/tests/ui/const-generics/impl-block-missing-const-generics.stderr +++ b/tests/ui/const-generics/impl-block-missing-const-generics.stderr @@ -79,7 +79,7 @@ error: the constant `AHA` is not of type `usize` LL | impl Foo {} | -------------- ^^^^^^^^ expected `usize`, found `u32` | | - | found this const parameter + | `AHA` defined here | note: required by a const generic parameter in `e::Foo` --> $DIR/impl-block-missing-const-generics.rs:28:16 @@ -137,7 +137,7 @@ error: the constant `AHA` is not of type `usize` LL | impl T for Foo {} | -------------- ^^^^^^ expected `usize`, found `u32` | | - | found this const parameter + | `AHA` defined here | note: required by a const generic parameter in `k::T` --> $DIR/impl-block-missing-const-generics.rs:70:13 diff --git a/tests/ui/const-generics/issues/index_array_bad_type.stderr b/tests/ui/const-generics/issues/index_array_bad_type.stderr index a877cdecc7b24..3c6dd4e456a1b 100644 --- a/tests/ui/const-generics/issues/index_array_bad_type.stderr +++ b/tests/ui/const-generics/issues/index_array_bad_type.stderr @@ -4,7 +4,7 @@ error: the constant `N` is not of type `usize` LL | struct Struct(pub [u8; N]); | ------------- ^^^^^^^ expected `usize`, found `i128` | | - | found this const parameter + | `N` defined here | = note: the length of array `[u8; N]` must be type `usize` diff --git a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.stderr b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.stderr index a976cdb576c7f..f9284614aaedd 100644 --- a/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.stderr +++ b/tests/ui/const-generics/mgca/adt_expr_arg_tuple_expr_fail.stderr @@ -2,7 +2,7 @@ error: the constant `N` is not of type `u32` --> $DIR/adt_expr_arg_tuple_expr_fail.rs:18:21 | LL | fn generic_caller() { - | -------------- found this const parameter + | -------------- `N` defined here LL | takes_tuple::<{ (N, N2) }>(); | ^^^^^^^ expected `u32`, found `usize` @@ -10,7 +10,7 @@ error: the constant `N` is not of type `u32` --> $DIR/adt_expr_arg_tuple_expr_fail.rs:20:21 | LL | fn generic_caller() { - | -------------- found this const parameter + | -------------- `N` defined here ... LL | takes_tuple::<{ (N, T::ASSOC) }>(); | ^^^^^^^^^^^^^ expected `u32`, found `usize` @@ -25,7 +25,7 @@ error: the constant `N` is not of type `u32` --> $DIR/adt_expr_arg_tuple_expr_fail.rs:24:28 | LL | fn generic_caller() { - | -------------- found this const parameter + | -------------- `N` defined here ... LL | takes_nested_tuple::<{ (N, (N, N2)) }>(); | ^^^^^^^^^^^^ expected `u32`, found `usize` @@ -34,7 +34,7 @@ error: the constant `N` is not of type `u32` --> $DIR/adt_expr_arg_tuple_expr_fail.rs:26:28 | LL | fn generic_caller() { - | -------------- found this const parameter + | -------------- `N` defined here ... LL | takes_nested_tuple::<{ (N, (N, T::ASSOC)) }>(); | ^^^^^^^^^^^^^^^^^^ expected `u32`, found `usize` diff --git a/tests/ui/const-generics/mgca/adt_expr_fields_type_check.stderr b/tests/ui/const-generics/mgca/adt_expr_fields_type_check.stderr index 0f7f6e86baf1d..619c735c64dcc 100644 --- a/tests/ui/const-generics/mgca/adt_expr_fields_type_check.stderr +++ b/tests/ui/const-generics/mgca/adt_expr_fields_type_check.stderr @@ -2,7 +2,7 @@ error: the constant `N` is not of type `u8` --> $DIR/adt_expr_fields_type_check.rs:23:19 | LL | fn bar() { - | ------------- found this const parameter + | ------------- `N` defined here LL | accepts_1::<{ S1:: { f1: N, f2: N } }>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `bool` @@ -10,7 +10,7 @@ error: the constant `N` is not of type `isize` --> $DIR/adt_expr_fields_type_check.rs:23:19 | LL | fn bar() { - | ------------- found this const parameter + | ------------- `N` defined here LL | accepts_1::<{ S1:: { f1: N, f2: N } }>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `isize`, found `bool` @@ -18,7 +18,7 @@ error: the constant `N` is not of type `u8` --> $DIR/adt_expr_fields_type_check.rs:26:19 | LL | fn bar() { - | ------------- found this const parameter + | ------------- `N` defined here ... LL | accepts_2::<{ S2::(N, N) }>(); | ^^^^^^^^^^^^^^ expected `u8`, found `bool` @@ -27,7 +27,7 @@ error: the constant `N` is not of type `isize` --> $DIR/adt_expr_fields_type_check.rs:26:19 | LL | fn bar() { - | ------------- found this const parameter + | ------------- `N` defined here ... LL | accepts_2::<{ S2::(N, N) }>(); | ^^^^^^^^^^^^^^ expected `isize`, found `bool` @@ -36,7 +36,7 @@ error: the constant `N` is not of type `u8` --> $DIR/adt_expr_fields_type_check.rs:29:19 | LL | fn bar() { - | ------------- found this const parameter + | ------------- `N` defined here ... LL | accepts_3::<{ En::Var1::(N, N) }>(); | ^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `bool` @@ -45,7 +45,7 @@ error: the constant `N` is not of type `i64` --> $DIR/adt_expr_fields_type_check.rs:31:19 | LL | fn bar() { - | ------------- found this const parameter + | ------------- `N` defined here ... LL | accepts_3::<{ En::Var2:: { field: N } }>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `i64`, found `bool` diff --git a/tests/ui/const-generics/transmute-fail.stderr b/tests/ui/const-generics/transmute-fail.stderr index 2008843f5d401..31e4fea37e76b 100644 --- a/tests/ui/const-generics/transmute-fail.stderr +++ b/tests/ui/const-generics/transmute-fail.stderr @@ -2,9 +2,7 @@ error: the constant `W` is not of type `usize` --> $DIR/transmute-fail.rs:16:42 | LL | fn bar(v: [[u32; H]; W]) -> [[u32; W]; H] { - | ------------- ^^^^^^^^^^^^^ expected `usize`, found `bool` - | | - | found this const parameter + | ------------- `W` defined here ^^^^^^^^^^^^^ expected `usize`, found `bool` | = note: the length of array `[[u32; H]; W]` must be type `usize` @@ -12,7 +10,7 @@ error: the constant `W` is not of type `usize` --> $DIR/transmute-fail.rs:19:9 | LL | fn bar(v: [[u32; H]; W]) -> [[u32; W]; H] { - | ------------- found this const parameter + | ------------- `W` defined here ... LL | std::mem::transmute(v) | ^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` diff --git a/tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr b/tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr index bacd670672d77..4202ed35383f6 100644 --- a/tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr +++ b/tests/ui/const-generics/type-mismatch-in-nested-goal.current.stderr @@ -2,9 +2,7 @@ error: the constant `N` is not of type `bool` --> $DIR/type-mismatch-in-nested-goal.rs:9:50 | LL | fn needs_a(_: [u8; N]) where (): A {} - | -------------- ^^^^ expected `bool`, found `usize` - | | - | found this const parameter + | -------------- `N` defined here ^^^^ expected `bool`, found `usize` | note: required by a const generic parameter in `A` --> $DIR/type-mismatch-in-nested-goal.rs:5:9 diff --git a/tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr b/tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr index bacd670672d77..4202ed35383f6 100644 --- a/tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr +++ b/tests/ui/const-generics/type-mismatch-in-nested-goal.next.stderr @@ -2,9 +2,7 @@ error: the constant `N` is not of type `bool` --> $DIR/type-mismatch-in-nested-goal.rs:9:50 | LL | fn needs_a(_: [u8; N]) where (): A {} - | -------------- ^^^^ expected `bool`, found `usize` - | | - | found this const parameter + | -------------- `N` defined here ^^^^ expected `bool`, found `usize` | note: required by a const generic parameter in `A` --> $DIR/type-mismatch-in-nested-goal.rs:5:9 diff --git a/tests/ui/const-generics/type_mismatch.stderr b/tests/ui/const-generics/type_mismatch.stderr index d45365e1a32d5..ee10c2075c39a 100644 --- a/tests/ui/const-generics/type_mismatch.stderr +++ b/tests/ui/const-generics/type_mismatch.stderr @@ -4,7 +4,7 @@ error: the constant `N` is not of type `usize` LL | fn bar() -> [u8; N] {} | ----------- ^^^^^^^ expected `usize`, found `u8` | | - | found this const parameter + | `N` defined here | = note: the length of array `[u8; N]` must be type `usize` @@ -12,7 +12,7 @@ error: the constant `N` is not of type `u8` --> $DIR/type_mismatch.rs:2:11 | LL | fn foo() -> [u8; N] { - | -------------- found this const parameter + | -------------- `N` defined here LL | bar::() | ^ expected `u8`, found `usize` | diff --git a/tests/ui/consts/bad-array-size-in-type-err.stderr b/tests/ui/consts/bad-array-size-in-type-err.stderr index 094e837c0e5c1..a5782306bf610 100644 --- a/tests/ui/consts/bad-array-size-in-type-err.stderr +++ b/tests/ui/consts/bad-array-size-in-type-err.stderr @@ -2,7 +2,7 @@ error: the constant `N` is not of type `usize` --> $DIR/bad-array-size-in-type-err.rs:2:10 | LL | struct BadArraySize { - | ----------- found this const parameter + | ----------- `N` defined here LL | arr: [i32; N], | ^^^^^^^^ expected `usize`, found `u8` | @@ -14,7 +14,7 @@ error: the constant `N` is not of type `usize` LL | pub struct Blorb([String; N]); | ------------ ^^^^^^^^^^^ expected `usize`, found `u16` | | - | found this const parameter + | `N` defined here | = note: the length of array `[String; N]` must be type `usize` diff --git a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr index 976c9eb6baa55..12008e0c1bc16 100644 --- a/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr +++ b/tests/ui/specialization/default-proj-ty-as-type-of-const-issue-125757.stderr @@ -12,7 +12,7 @@ error: the constant `C` is not of type `::Type` LL | impl Wrapper {} | -------------- ^^^^^^^^^^ expected associated type, found `usize` | | - | found this const parameter + | `C` defined here | = help: consider constraining the associated type `::Type` to `usize` = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html diff --git a/tests/ui/transmutability/malformed-program-gracefulness/wrong-adt-assume.stderr b/tests/ui/transmutability/malformed-program-gracefulness/wrong-adt-assume.stderr index b5cf6c92374c7..b4ad88289fd85 100644 --- a/tests/ui/transmutability/malformed-program-gracefulness/wrong-adt-assume.stderr +++ b/tests/ui/transmutability/malformed-program-gracefulness/wrong-adt-assume.stderr @@ -2,7 +2,7 @@ error: the constant `ASSUME` is not of type `Assume` --> $DIR/wrong-adt-assume.rs:14:9 | LL | fn foo() - | ----------------------- found this const parameter + | ----------------------- `ASSUME` defined here LL | where LL | u8: TransmuteFrom, | ^^^^^^^^^^^^^^^^^^^^^^^^^ expected `Assume`, found `NotAssume` diff --git a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.current.stderr b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.current.stderr index e6f72b9b55fa7..b6657de919090 100644 --- a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.current.stderr +++ b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.current.stderr @@ -10,7 +10,7 @@ error: the constant `N` is not of type `usize` LL | fn func() -> [(); N]; | ------------ ^^^^^^^ expected `usize`, found `u32` | | - | found this const parameter + | `N` defined here | = note: the length of array `[(); N]` must be type `usize` diff --git a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.next.stderr b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.next.stderr index e6f72b9b55fa7..b6657de919090 100644 --- a/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.next.stderr +++ b/tests/ui/typeck/issue-114918/const-in-impl-fn-return-type.next.stderr @@ -10,7 +10,7 @@ error: the constant `N` is not of type `usize` LL | fn func() -> [(); N]; | ------------ ^^^^^^^ expected `usize`, found `u32` | | - | found this const parameter + | `N` defined here | = note: the length of array `[(); N]` must be type `usize` diff --git a/tests/ui/wf/wf-dyn-in-hrtb-bound-const-mismatch.stderr b/tests/ui/wf/wf-dyn-in-hrtb-bound-const-mismatch.stderr index 704e45bc1ac89..c3fb2e6fd84f1 100644 --- a/tests/ui/wf/wf-dyn-in-hrtb-bound-const-mismatch.stderr +++ b/tests/ui/wf/wf-dyn-in-hrtb-bound-const-mismatch.stderr @@ -4,7 +4,7 @@ error: the constant `B` is not of type `usize` LL | fn nested(_f: &dyn for<'a> Fn(&'a (), &'a dyn HasConst<'a, B>)) {} | ------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `usize`, found `bool` | | - | found this const parameter + | `B` defined here | note: required by a const generic parameter in `HasConst` --> $DIR/wf-dyn-in-hrtb-bound-const-mismatch.rs:14:20 From dc7eb415b81a62459fc2943ffa3d197cc491d9ff Mon Sep 17 00:00:00 2001 From: Selby Mashiki Date: Thu, 5 Nov 2026 20:17:47 +0200 Subject: [PATCH 22/31] style-guide: Remove ABI explicitness prescription for extern items Per the style team FCP in #152760, remove the prescription requiring an explicit ABI on extern items so formatters preserve the ABI as written in the AST and defer missing-ABI diagnostics to language lints. --- src/doc/style-guide/src/items.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 090dc00844802..54bc59e896e07 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -424,12 +424,6 @@ bound, put a space after the colon but not before: pub type Foo: Bar; ``` -## extern items - -When writing extern items (such as `extern "C" fn`), always specify the ABI. -For example, write `extern "C" fn foo ...` or `unsafe extern "C" { ...}` -and avoid `extern fn foo ...` and `unsafe extern { ... }`. - ## Imports (`use` statements) Format imports on one line where possible. Don't put spaces around braces. From 64fe27116b86a93932a1065610decf3bda51b2c2 Mon Sep 17 00:00:00 2001 From: rustbot <47979223+rustbot@users.noreply.github.com> Date: Thu, 5 Nov 2026 19:27:04 +0100 Subject: [PATCH 23/31] Update books --- src/doc/reference | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/reference b/src/doc/reference index 3989fe91f1a60..a2ae66d7037cb 160000 --- a/src/doc/reference +++ b/src/doc/reference @@ -1 +1 @@ -Subproject commit 3989fe91f1a601b51684a582ad17b2503f221787 +Subproject commit a2ae66d7037cbedac68746b9510b24cc34b96d69 From 39cd593627d09e4ca747fa2ab59188bfccdbf757 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 28 Oct 2026 18:16:58 +0100 Subject: [PATCH 24/31] Disable MAKEINFO when building binutils --- src/ci/docker/scripts/build-gcc.sh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ci/docker/scripts/build-gcc.sh b/src/ci/docker/scripts/build-gcc.sh index 60443744455d9..e26684b75fac6 100755 --- a/src/ci/docker/scripts/build-gcc.sh +++ b/src/ci/docker/scripts/build-gcc.sh @@ -14,9 +14,10 @@ mkdir binutils-build mkdir "$BINUTILS_ROOT_PATH" cd binutils-build -hide_output ../binutils-$BINUTILS/configure --prefix="$BINUTILS_ROOT_PATH" --disable-werror -hide_output make -j$(nproc) -hide_output make install +hide_output ../binutils-$BINUTILS/configure \ + --prefix="$BINUTILS_ROOT_PATH" --disable-werror MAKEINFO=true +hide_output make -j$(nproc) MAKEINFO=true +hide_output make install MAKEINFO=true cd .. rm -rf binutils-build binutils-$BINUTILS From 266b16ca75d6d7f916cd6e574835062028c6c75f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 5 Nov 2026 16:10:40 +0100 Subject: [PATCH 25/31] Bump SCCACHE_C_CUSTOM_CACHE_BUSTER to force sccache refresh --- src/ci/run.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/run.sh b/src/ci/run.sh index 8607b294eb1e0..549f85f35e061 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -244,7 +244,7 @@ trap datecheck EXIT # Bump this value if you need to invalidate sccache's cache, if some wrong # builds go into it -export SCCACHE_C_CUSTOM_CACHE_BUSTER=1 +export SCCACHE_C_CUSTOM_CACHE_BUSTER=2 # We've had problems in the past of shell scripts leaking fds into the sccache # server (#48192) which causes Cargo to erroneously think that a build script From b4f8df11586d8a55fb06565e05366b8b52483800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 5 Nov 2026 18:51:37 +0000 Subject: [PATCH 26/31] Fix suggestion span --- .../src/diagnostics/wrong_number_of_generic_args.rs | 4 ++-- tests/ui/associated-inherent-types/issue-109768.stderr | 4 ++-- ...pl-block-params-declared-in-wrong-spot-issue-113073.stderr | 4 ++-- tests/ui/reborrow/invalid-coerce-shared-next-solver.stderr | 4 ++-- .../invalid-reborrow-impl-phantom-data-wrong-generics.stderr | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs index 3bf7112a45fbb..a0c4f3f9e559a 100644 --- a/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs +++ b/compiler/rustc_hir_analysis/src/diagnostics/wrong_number_of_generic_args.rs @@ -746,8 +746,8 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { } } if !impl_args.is_empty() { - impl_sugg = Some(match i.generics.span_for_lifetime_suggestion() { - Some(span) => (span, format!("{}, ", impl_args.join(", "))), + impl_sugg = Some(match i.generics.span_for_param_suggestion() { + Some(span) => (span, format!(", {}", impl_args.join(", "))), None => (i.generics.span, format!("<{}>", impl_args.join(", "))), }); } diff --git a/tests/ui/associated-inherent-types/issue-109768.stderr b/tests/ui/associated-inherent-types/issue-109768.stderr index 75396199c2b8b..a41eb8ce4bc4d 100644 --- a/tests/ui/associated-inherent-types/issue-109768.stderr +++ b/tests/ui/associated-inherent-types/issue-109768.stderr @@ -17,8 +17,8 @@ LL | struct Local(T, U); | ^^^^^ - - help: add missing generic arguments | -LL | impl Local { - | ++ ++++++ +LL | impl Local { + | +++ ++++++ error[E0658]: inherent associated types are unstable --> $DIR/issue-109768.rs:8:5 diff --git a/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr b/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr index 62395b619fc92..253d7c1226a48 100644 --- a/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr +++ b/tests/ui/generics/impl-block-params-declared-in-wrong-spot-issue-113073.stderr @@ -84,8 +84,8 @@ LL | trait Bar {} | ^^^ - - help: add missing generic argument | -LL | impl Bar for u8 {} - | ++ +++ +LL | impl Bar for u8 {} + | +++ +++ error[E0229]: associated item constraints are not allowed here --> $DIR/impl-block-params-declared-in-wrong-spot-issue-113073.rs:27:16 diff --git a/tests/ui/reborrow/invalid-coerce-shared-next-solver.stderr b/tests/ui/reborrow/invalid-coerce-shared-next-solver.stderr index 044abed91ec0a..e6be2b474573c 100644 --- a/tests/ui/reborrow/invalid-coerce-shared-next-solver.stderr +++ b/tests/ui/reborrow/invalid-coerce-shared-next-solver.stderr @@ -28,8 +28,8 @@ LL | impl<'a, T> CoerceShared for CustomMut<'reborrow, T> {} | help: add missing generic argument | -LL | impl CoerceShared for CustomMut<'reborrow, T> {} - | +++++++ ++++++++ +LL | impl<'a, T, Target> CoerceShared for CustomMut<'reborrow, T> {} + | ++++++++ ++++++++ error[E0377]: the trait `CoerceShared` may only be implemented for a coercion between structures --> $DIR/invalid-coerce-shared-next-solver.rs:11:1 diff --git a/tests/ui/reborrow/invalid-reborrow-impl-phantom-data-wrong-generics.stderr b/tests/ui/reborrow/invalid-reborrow-impl-phantom-data-wrong-generics.stderr index aaf80330687c0..eafb7341ea712 100644 --- a/tests/ui/reborrow/invalid-reborrow-impl-phantom-data-wrong-generics.stderr +++ b/tests/ui/reborrow/invalid-reborrow-impl-phantom-data-wrong-generics.stderr @@ -14,8 +14,8 @@ LL | impl<'a> Reborrow for PhantomData<'a> {} | help: add missing generic argument | -LL | impl Reborrow for PhantomData<'a, T> {} - | ++ +++ +LL | impl<'a, T> Reborrow for PhantomData<'a, T> {} + | +++ +++ error: implementing `Reborrow` requires exactly one lifetime argument in the reborrowed type --> $DIR/invalid-reborrow-impl-phantom-data-wrong-generics.rs:9:1 From ca9e03561c43015eae0c7b9df9a6ae2679ef509e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 5 Nov 2026 18:51:47 +0000 Subject: [PATCH 27/31] Fix rebase --- ...cked-alias-variant-pattern-unsized-arg-issue-152990.stderr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/traits/next-solver/normalize/checked-alias-variant-pattern-unsized-arg-issue-152990.stderr b/tests/ui/traits/next-solver/normalize/checked-alias-variant-pattern-unsized-arg-issue-152990.stderr index e44b35692ea8c..efc6fc0ef2462 100644 --- a/tests/ui/traits/next-solver/normalize/checked-alias-variant-pattern-unsized-arg-issue-152990.stderr +++ b/tests/ui/traits/next-solver/normalize/checked-alias-variant-pattern-unsized-arg-issue-152990.stderr @@ -1,8 +1,8 @@ error[E0277]: the size for values of type `(dyn Fn() + 'static)` cannot be known at compilation time - --> $DIR/checked-alias-variant-pattern-unsized-arg-issue-152990.rs:11:1 + --> $DIR/checked-alias-variant-pattern-unsized-arg-issue-152990.rs:11:18 | LL | type Supertype = Foo; - | ^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | ^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Fn() + 'static)` note: required by an implicit `Sized` bound in `Foo` From af6c6bc609b4258f21ca6f8a97bf5439442fc923 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 5 Nov 2026 22:25:07 +0100 Subject: [PATCH 28/31] Update CI GCC stamp --- src/bootstrap/download-ci-gcc-stamp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/download-ci-gcc-stamp b/src/bootstrap/download-ci-gcc-stamp index ec8d0fa3135d1..5bda219304547 100644 --- a/src/bootstrap/download-ci-gcc-stamp +++ b/src/bootstrap/download-ci-gcc-stamp @@ -1,4 +1,4 @@ Change this file to make users of the `download-ci-gcc` configuration download a new version of GCC from CI, even if the GCC submodule hasn’t changed. -Last change is for: https://github.com/rust-lang/rust/pull/150873 +Last change is for: https://github.com/rust-lang/rust/pull/165078 From 2aa9a63eb422fb11efc0fdab317ecd11b5611aa4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 5 Nov 2026 22:31:11 +0100 Subject: [PATCH 29/31] Improve comment --- src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh index 21fc7c2a9cd77..f55fede851765 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/dist.sh @@ -16,8 +16,10 @@ python3 ../x.py build --set rust.debug=true opt-dist # Use GCC for building GCC components, as it seems to behave badly when built with Clang # Only build GCC on full builds, not try builds if [ "${DIST_TRY_BUILD:-0}" == "0" ]; then - # We add the binutils binary path to ensure that it uses the 2.38 version of binutils, - # which is needed for the `retain` attribute feature. + # We add the binutils binary path to ensure that it uses the 2.38 version of binutils. + # We need the 2.36 version for the `retain` attribute feature but we're stuck with an + # old assembler in another CI image so we cannot go above 2.38, otherwise it doesn't + # work anymore. Fun times. export PATH="/tmp/binutils-install/bin:$PATH" CC=/rustroot/bin/cc CXX=/rustroot/bin/c++ \ From db777f224bd5e56ecf66eddfa8ea245b84c5db2e Mon Sep 17 00:00:00 2001 From: Marius Melzer Date: Thu, 5 Nov 2026 17:42:42 +0100 Subject: [PATCH 30/31] Fix warnings for the L4Re targets Mostly configures out unused code but also reenabled DirEntry::file_type which now builds for the L4Re targets. --- library/std/src/sys/fd/unix.rs | 16 ++++------------ library/std/src/sys/fs/unix.rs | 1 - library/std/src/sys/pal/unix/mod.rs | 2 ++ 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/library/std/src/sys/fd/unix.rs b/library/std/src/sys/fd/unix.rs index 6ebbc6afc1661..c46ca0cd4d591 100644 --- a/library/std/src/sys/fd/unix.rs +++ b/library/std/src/sys/fd/unix.rs @@ -3,19 +3,9 @@ #[cfg(test)] mod tests; -#[cfg(not(any( - target_os = "linux", - target_os = "l4re", - target_os = "android", - target_os = "hurd", -)))] +#[cfg(not(any(target_os = "linux", target_os = "android", target_os = "hurd")))] use libc::off_t as off64_t; -#[cfg(any( - target_os = "android", - target_os = "linux", - target_os = "l4re", - target_os = "hurd", -))] +#[cfg(any(target_os = "android", target_os = "linux", target_os = "hurd"))] use libc::off64_t; cfg_select! { @@ -246,6 +236,7 @@ impl FileDesc { target_os = "linux", target_os = "netbsd", target_os = "openbsd", // OpenBSD 2.7 + target_os = "l4re", all(target_os = "macos", target_arch = "aarch64"), ))] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { @@ -273,6 +264,7 @@ impl FileDesc { target_os = "netbsd", target_os = "openbsd", target_vendor = "apple", + target_os = "l4re", )))] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { io::default_read_vectored(|b| self.read_at(b, offset), bufs) diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index 4bd22082ed439..76b2e82b75c61 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -1086,7 +1086,6 @@ impl DirEntry { target_os = "nto", target_os = "qnx", target_os = "vita", - target_os = "l4re", )))] match self.entry.d_type { libc::DT_CHR => return Ok(FileType { mode: libc::S_IFCHR }), diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 292c02f3d1f3e..53bbdfc988a8f 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -193,6 +193,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { target_os = "horizon", target_os = "vxworks", target_os = "vita", + target_os = "l4re", )))] static ON_BROKEN_PIPE_USED: crate::sync::atomic::Atomic = crate::sync::atomic::AtomicBool::new(false); @@ -205,6 +206,7 @@ static ON_BROKEN_PIPE_USED: crate::sync::atomic::Atomic = target_os = "vxworks", target_os = "vita", target_os = "nuttx", + target_os = "l4re", )))] pub(crate) fn on_broken_pipe_used() -> bool { ON_BROKEN_PIPE_USED.load(crate::sync::atomic::Ordering::Relaxed) From c08c7c64c71d3b814c2a27ce5dcce7b9da9198fb Mon Sep 17 00:00:00 2001 From: Roland Xu Date: Sat, 31 Oct 2026 15:15:51 +0800 Subject: [PATCH 31/31] Anonymize all binders and bound vars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: León Orell Valerian Liehr --- .../src/check/compare_impl_item/refine.rs | 57 ++++++++++++++++--- .../nesting-fn-inside-impl-future.rs | 14 +++++ 2 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 tests/ui/impl-trait/nesting-fn-inside-impl-future.rs diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs index e8dae9c016fc6..969a6ae8c3079 100644 --- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs +++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs @@ -9,8 +9,8 @@ use rustc_lint_defs::builtin::{REFINING_IMPL_TRAIT_INTERNAL, REFINING_IMPL_TRAIT use rustc_middle::traits::ObligationCause; use rustc_middle::ty::print::{with_no_trimmed_paths, with_types_for_signature}; use rustc_middle::ty::{ - self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, - TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized, + self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeSuperVisitable, + TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode, Unnormalized, }; use rustc_span::def_id::ModId; use rustc_span::{Span, span_bug}; @@ -210,8 +210,8 @@ pub(crate) fn check_refining_return_position_impl_trait_in_trait<'tcx>( // Also, We have to anonymize binders in these types because they may contain // `BrNamed` bound vars, which contain unique `DefId`s which correspond to syntax // locations that we don't care about when checking bound equality. - let trait_bounds = FxIndexSet::from_iter(trait_bounds.fold_with(&mut Anonymize { tcx })); - let impl_bounds = impl_bounds.fold_with(&mut Anonymize { tcx }); + let trait_bounds = FxIndexSet::from_iter(trait_bounds.fold_with(&mut FullyAnonymize { tcx })); + let impl_bounds = impl_bounds.fold_with(&mut FullyAnonymize { tcx }); // Find any clauses that are present in the impl's RPITITs that are not // present in the trait's RPITITs. This will trigger on trivial predicates, @@ -415,11 +415,13 @@ fn type_visibility<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option { +/// Contrary to [`TyCtxt::anonymize_bound_vars`] this anonymizes *all* binders and bound vars, +/// not just the `Binder` and its bound vars that was provided as an argument. +struct FullyAnonymize<'tcx> { tcx: TyCtxt<'tcx>, } -impl<'tcx> TypeFolder> for Anonymize<'tcx> { +impl<'tcx> TypeFolder> for FullyAnonymize<'tcx> { fn cx(&self) -> TyCtxt<'tcx> { self.tcx } @@ -428,7 +430,48 @@ impl<'tcx> TypeFolder> for Anonymize<'tcx> { where T: TypeFoldable>, { - self.tcx.anonymize_bound_vars(t) + let bound_vars = self.tcx.mk_bound_variable_kinds_from_iter(t.bound_vars().iter().map( + |kind| match kind { + ty::BoundVariableKind::Ty(_) => ty::BoundVariableKind::Ty(ty::BoundTyKind::Anon), + ty::BoundVariableKind::Region(_) => { + ty::BoundVariableKind::Region(ty::BoundRegionKind::Anon) + } + ty::BoundVariableKind::Const => ty::BoundVariableKind::Const, + }, + )); + ty::Binder::bind_with_vars(t.skip_binder().fold_with(self), bound_vars) + } + + fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { + if let ty::RegionKind::ReBound(ty::BoundVarIndexKind::Bound(debruijn), bound_re) = r.kind() + { + ty::Region::new_anon_bound(self.tcx, debruijn, bound_re.var) + } else { + r + } + } + + fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> { + if !t.has_bound_vars() { + return t; + } + if let ty::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_ty) = *t.kind() { + let bound_ty = ty::BoundTy { var: bound_ty.var, kind: ty::BoundTyKind::Anon }; + Ty::new_bound(self.tcx, debruijn, bound_ty) + } else { + t.super_fold_with(self) + } + } + + fn fold_const(&mut self, c: ty::Const<'tcx>) -> ty::Const<'tcx> { + if !c.has_bound_vars() { + return c; + } + if let ty::ConstKind::Bound(ty::BoundVarIndexKind::Bound(debruijn), bound_ct) = c.kind() { + ty::Const::new_anon_bound(self.tcx, debruijn, bound_ct.var) + } else { + c.super_fold_with(self) + } } } diff --git a/tests/ui/impl-trait/nesting-fn-inside-impl-future.rs b/tests/ui/impl-trait/nesting-fn-inside-impl-future.rs new file mode 100644 index 0000000000000..550cddd398527 --- /dev/null +++ b/tests/ui/impl-trait/nesting-fn-inside-impl-future.rs @@ -0,0 +1,14 @@ +//! Regression test for + +//@ check-pass +//@ edition: 2024 + +#![deny(refining_impl_trait)] + +trait A { fn f() -> impl B; } +impl A for () { fn f() -> impl B { 0 } } + +trait B {} +impl B for U {} + +fn main() {}