From 6ce0f0ff91b6ed95326b7e14dc6f449d75aff92c Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Tue, 2 Dec 2025 20:43:43 +0900 Subject: [PATCH 1/2] Only apply `no_mangle_const_items`'s suggestion to plain const items --- compiler/rustc_lint/src/builtin.rs | 27 +++++++++++-------- compiler/rustc_lint/src/lints.rs | 2 +- ...gle-generic-const-suggestion-suppressed.rs | 24 +++++++++++++++++ ...generic-const-suggestion-suppressed.stderr | 26 ++++++++++++++++++ 4 files changed, 67 insertions(+), 12 deletions(-) create mode 100644 tests/ui/lint/no-mangle-generic-const-suggestion-suppressed.rs create mode 100644 tests/ui/lint/no-mangle-generic-const-suggestion-suppressed.stderr diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 36f4ad64a42b8..b9b7e0fe6ddff 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -997,18 +997,23 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { self.check_no_mangle_on_generic_fn(cx, attr_span, it.owner_id.def_id); } } - hir::ItemKind::Const(..) => { + hir::ItemKind::Const(_, generics, ..) => { if find_attr!(attrs, AttributeKind::NoMangle(..)) { - // account for "pub const" (#45562) - let start = cx - .tcx - .sess - .source_map() - .span_to_snippet(it.span) - .map(|snippet| snippet.find("const").unwrap_or(0)) - .unwrap_or(0) as u32; - // `const` is 5 chars - let suggestion = it.span.with_hi(BytePos(it.span.lo().0 + start + 5)); + let suggestion = + if generics.params.is_empty() && generics.where_clause_span.is_empty() { + // account for "pub const" (#45562) + let start = cx + .tcx + .sess + .source_map() + .span_to_snippet(it.span) + .map(|snippet| snippet.find("const").unwrap_or(0)) + .unwrap_or(0) as u32; + // `const` is 5 chars + Some(it.span.with_hi(BytePos(it.span.lo().0 + start + 5))) + } else { + None + }; // Const items do not refer to a particular location in memory, and therefore // don't have anything to attach a symbol to diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 096299c16e0fe..9aced66bdccd7 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -230,7 +230,7 @@ pub(crate) struct BuiltinNoMangleGeneric { #[diag(lint_builtin_const_no_mangle)] pub(crate) struct BuiltinConstNoMangle { #[suggestion(code = "pub static", applicability = "machine-applicable")] - pub suggestion: Span, + pub suggestion: Option, } #[derive(LintDiagnostic)] diff --git a/tests/ui/lint/no-mangle-generic-const-suggestion-suppressed.rs b/tests/ui/lint/no-mangle-generic-const-suggestion-suppressed.rs new file mode 100644 index 0000000000000..8dcc741b71b13 --- /dev/null +++ b/tests/ui/lint/no-mangle-generic-const-suggestion-suppressed.rs @@ -0,0 +1,24 @@ +//! Ensure the `no_mangle_const_items` lint triggers but does not offer a `pub static` +//! suggestion for consts that have generics or a where-clause. +//! regression test for + +#![feature(generic_const_items)] +#![allow(incomplete_features)] +#![deny(no_mangle_const_items)] +trait Trait { + const ASSOC: u32; +} + +#[unsafe(no_mangle)] +const WHERE_BOUND: u32 = <&'static ()>::ASSOC where for<'a> &'a (): Trait; +//~^ ERROR: const items should never be `#[no_mangle]` + +#[no_mangle] +const _: () = () where; +//~^ ERROR: const items should never be `#[no_mangle]` + +#[unsafe(no_mangle)] +pub const GENERIC: usize = N; +//~^ ERROR: const items should never be `#[no_mangle]` + +fn main() {} diff --git a/tests/ui/lint/no-mangle-generic-const-suggestion-suppressed.stderr b/tests/ui/lint/no-mangle-generic-const-suggestion-suppressed.stderr new file mode 100644 index 0000000000000..a131015fd9694 --- /dev/null +++ b/tests/ui/lint/no-mangle-generic-const-suggestion-suppressed.stderr @@ -0,0 +1,26 @@ +error: const items should never be `#[no_mangle]` + --> $DIR/no-mangle-generic-const-suggestion-suppressed.rs:13:1 + | +LL | const WHERE_BOUND: u32 = <&'static ()>::ASSOC where for<'a> &'a (): Trait; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/no-mangle-generic-const-suggestion-suppressed.rs:7:9 + | +LL | #![deny(no_mangle_const_items)] + | ^^^^^^^^^^^^^^^^^^^^^ + +error: const items should never be `#[no_mangle]` + --> $DIR/no-mangle-generic-const-suggestion-suppressed.rs:17:1 + | +LL | const _: () = () where; + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: const items should never be `#[no_mangle]` + --> $DIR/no-mangle-generic-const-suggestion-suppressed.rs:21:1 + | +LL | pub const GENERIC: usize = N; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + From 2951d72219b56af04063bb975d581b5337c6482f Mon Sep 17 00:00:00 2001 From: reddevilmidzy Date: Wed, 3 Dec 2025 10:06:16 +0900 Subject: [PATCH 2/2] Simplify and robustly compute suggestion span using `vis_span.to(ident.span.shrink_to_lo())` --- compiler/rustc_lint/src/builtin.rs | 14 +++----------- compiler/rustc_lint/src/lints.rs | 2 +- tests/ui/issues/issue-45562.stderr | 2 +- tests/ui/lint/lint-unexported-no-mangle.stderr | 4 ++-- tests/ui/lint/suggestions.stderr | 6 +++--- 5 files changed, 10 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index b9b7e0fe6ddff..dd0aa848ed2c9 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -41,7 +41,7 @@ pub use rustc_session::lint::builtin::*; use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass}; use rustc_span::edition::Edition; use rustc_span::source_map::Spanned; -use rustc_span::{BytePos, DUMMY_SP, Ident, InnerSpan, Span, Symbol, kw, sym}; +use rustc_span::{DUMMY_SP, Ident, InnerSpan, Span, Symbol, kw, sym}; use rustc_target::asm::InlineAsmArch; use rustc_trait_selection::infer::{InferCtxtExt, TyCtxtInferExt}; use rustc_trait_selection::traits::misc::type_allowed_to_implement_copy; @@ -997,20 +997,12 @@ impl<'tcx> LateLintPass<'tcx> for InvalidNoMangleItems { self.check_no_mangle_on_generic_fn(cx, attr_span, it.owner_id.def_id); } } - hir::ItemKind::Const(_, generics, ..) => { + hir::ItemKind::Const(ident, generics, ..) => { if find_attr!(attrs, AttributeKind::NoMangle(..)) { let suggestion = if generics.params.is_empty() && generics.where_clause_span.is_empty() { // account for "pub const" (#45562) - let start = cx - .tcx - .sess - .source_map() - .span_to_snippet(it.span) - .map(|snippet| snippet.find("const").unwrap_or(0)) - .unwrap_or(0) as u32; - // `const` is 5 chars - Some(it.span.with_hi(BytePos(it.span.lo().0 + start + 5))) + Some(it.span.until(ident.span)) } else { None }; diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 9aced66bdccd7..130c0762eb402 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -229,7 +229,7 @@ pub(crate) struct BuiltinNoMangleGeneric { #[derive(LintDiagnostic)] #[diag(lint_builtin_const_no_mangle)] pub(crate) struct BuiltinConstNoMangle { - #[suggestion(code = "pub static", applicability = "machine-applicable")] + #[suggestion(code = "pub static ", applicability = "machine-applicable")] pub suggestion: Option, } diff --git a/tests/ui/issues/issue-45562.stderr b/tests/ui/issues/issue-45562.stderr index 55d35f76a0198..3372986af9373 100644 --- a/tests/ui/issues/issue-45562.stderr +++ b/tests/ui/issues/issue-45562.stderr @@ -2,7 +2,7 @@ error: const items should never be `#[no_mangle]` --> $DIR/issue-45562.rs:5:14 | LL | #[no_mangle] pub const RAH: usize = 5; - | ---------^^^^^^^^^^^^^^^^ + | ----------^^^^^^^^^^^^^^^ | | | help: try a static value: `pub static` | diff --git a/tests/ui/lint/lint-unexported-no-mangle.stderr b/tests/ui/lint/lint-unexported-no-mangle.stderr index 0efec51abaf6d..cb9477cfe16fb 100644 --- a/tests/ui/lint/lint-unexported-no-mangle.stderr +++ b/tests/ui/lint/lint-unexported-no-mangle.stderr @@ -31,7 +31,7 @@ error: const items should never be `#[no_mangle]` --> $DIR/lint-unexported-no-mangle.rs:9:1 | LL | const FOO: u64 = 1; - | -----^^^^^^^^^^^^^^ + | ------^^^^^^^^^^^^^ | | | help: try a static value: `pub static` | @@ -41,7 +41,7 @@ error: const items should never be `#[no_mangle]` --> $DIR/lint-unexported-no-mangle.rs:12:1 | LL | pub const PUB_FOO: u64 = 1; - | ---------^^^^^^^^^^^^^^^^^^ + | ----------^^^^^^^^^^^^^^^^^ | | | help: try a static value: `pub static` diff --git a/tests/ui/lint/suggestions.stderr b/tests/ui/lint/suggestions.stderr index c35e92f59809a..c6a7de51da2e6 100644 --- a/tests/ui/lint/suggestions.stderr +++ b/tests/ui/lint/suggestions.stderr @@ -52,7 +52,7 @@ error: const items should never be `#[no_mangle]` --> $DIR/suggestions.rs:6:14 | LL | #[no_mangle] const DISCOVERY: usize = 1; - | -----^^^^^^^^^^^^^^^^^^^^^^ + | ------^^^^^^^^^^^^^^^^^^^^^ | | | help: try a static value: `pub static` | @@ -81,7 +81,7 @@ error: const items should never be `#[no_mangle]` --> $DIR/suggestions.rs:22:18 | LL | #[no_mangle] pub const DAUNTLESS: bool = true; - | ---------^^^^^^^^^^^^^^^^^^^^^^^^ + | ----------^^^^^^^^^^^^^^^^^^^^^^^ | | | help: try a static value: `pub static` @@ -97,7 +97,7 @@ error: const items should never be `#[no_mangle]` --> $DIR/suggestions.rs:31:18 | LL | #[no_mangle] pub(crate) const VETAR: bool = true; - | ----------------^^^^^^^^^^^^^^^^^^^^ + | -----------------^^^^^^^^^^^^^^^^^^^ | | | help: try a static value: `pub static`