From d78e39c5c722437972c1a4d021887dc3d9873ea3 Mon Sep 17 00:00:00 2001 From: mejrs <59372212+mejrs@users.noreply.github.com> Date: Sat, 18 Jul 2026 00:04:11 +0200 Subject: [PATCH 1/3] Fix string indexing in diagnostic format strings (cherry picked from commit d61c7063bcb574c9fa41cb5677f1756cef4af548) --- compiler/rustc_parse_format/src/lib.rs | 2 +- tests/ui/diagnostic_namespace/unicode.rs | 10 ++++++ tests/ui/diagnostic_namespace/unicode.stderr | 35 ++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 tests/ui/diagnostic_namespace/unicode.rs create mode 100644 tests/ui/diagnostic_namespace/unicode.stderr diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs index 6f20092bb131c..256bc8c3fe30e 100644 --- a/compiler/rustc_parse_format/src/lib.rs +++ b/compiler/rustc_parse_format/src/lib.rs @@ -759,7 +759,7 @@ impl<'input> Parser<'input> { return spec; }; - spec.ty = self.string(self.input_vec_index); + spec.ty = self.string(self.input_vec_index2pos(self.input_vec_index)); spec.ty_span = { let end = self.input_vec_index2range(self.input_vec_index).start; Some(start..end) diff --git a/tests/ui/diagnostic_namespace/unicode.rs b/tests/ui/diagnostic_namespace/unicode.rs new file mode 100644 index 0000000000000..1f5afa8c1dde4 --- /dev/null +++ b/tests/ui/diagnostic_namespace/unicode.rs @@ -0,0 +1,10 @@ +#![crate_type = "lib"] +#![deny(malformed_diagnostic_format_literals)] + +#[diagnostic::on_unimplemented(message = " \x00 \u{b123} \\\u{b123} {:?}")] +//~^ERROR positional arguments are not permitted in diagnostic attributes [malformed_diagnostic_format_literals] +//~|ERROR format specifiers are not permitted in diagnostic attributes [malformed_diagnostic_format_literals] +#[diagnostic::on_unimplemented(note = "🦀🦀🦀🦀🦀🦀🦀🦀🦀🦀🦀🦀{:?}")] +//~^ERROR positional arguments are not permitted in diagnostic attributes [malformed_diagnostic_format_literals] +//~|ERROR format specifiers are not permitted in diagnostic attributes [malformed_diagnostic_format_literals] +pub trait ILoveUnicode {} diff --git a/tests/ui/diagnostic_namespace/unicode.stderr b/tests/ui/diagnostic_namespace/unicode.stderr new file mode 100644 index 0000000000000..964e10ee12e98 --- /dev/null +++ b/tests/ui/diagnostic_namespace/unicode.stderr @@ -0,0 +1,35 @@ +error: positional arguments are not permitted in diagnostic attributes + --> $DIR/unicode.rs:4:70 + | +LL | #[diagnostic::on_unimplemented(message = " \x00 \u{b123} \\u{b123} {:?}")] + | ^ remove this format argument + | + = help: you can print empty braces by escaping them +note: the lint level is defined here + --> $DIR/unicode.rs:2:9 + | +LL | #![deny(malformed_diagnostic_format_literals)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: format specifiers are not permitted in diagnostic attributes + --> $DIR/unicode.rs:4:70 + | +LL | #[diagnostic::on_unimplemented(message = " \x00 \u{b123} \\u{b123} {:?}")] + | ^^ remove this format specifier + +error: positional arguments are not permitted in diagnostic attributes + --> $DIR/unicode.rs:7:53 + | +LL | #[diagnostic::on_unimplemented(note = "🦀🦀🦀🦀🦀🦀🦀🦀🦀🦀🦀🦀{:?}")] + | ^ remove this format argument + | + = help: you can print empty braces by escaping them + +error: format specifiers are not permitted in diagnostic attributes + --> $DIR/unicode.rs:7:53 + | +LL | #[diagnostic::on_unimplemented(note = "🦀🦀🦀🦀🦀🦀🦀🦀🦀🦀🦀🦀{:?}")] + | ^^ remove this format specifier + +error: aborting due to 4 previous errors + From 625edb6c601d74977ad02b10dea708e8d1cfd66c Mon Sep 17 00:00:00 2001 From: LorrensP-2158466 Date: Mon, 20 Jul 2026 12:47:25 +0200 Subject: [PATCH 2/3] When recording traits, if a decl is ambiguous we make sure to record at least 1 trait of the ambiguous decls (is possible) such that we can record the `ambiguously_glob_imported_trait` lint. Also updated the issue linked by the lint. + added extra test + bless original test because of updated link (cherry picked from commit 73ed27196b4bf05c3810be5c4113da2b45662b24) --- compiler/rustc_lint_defs/src/builtin.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 31 +++++++++++---- .../ambiguous-trait-and-struct-in-scope.rs | 39 +++++++++++++++++++ ...ambiguous-trait-and-struct-in-scope.stderr | 16 ++++++++ .../imports/ambiguous-trait-in-scope.stderr | 14 +++---- 5 files changed, 86 insertions(+), 16 deletions(-) create mode 100644 tests/ui/imports/ambiguous-trait-and-struct-in-scope.rs create mode 100644 tests/ui/imports/ambiguous-trait-and-struct-in-scope.stderr diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index d38b1cf47bd6f..13088902cd0db 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -4560,7 +4560,7 @@ declare_lint! { Warn, "detects uses of ambiguously glob imported traits", @future_incompatible = FutureIncompatibleInfo { - reason: fcw!(FutureReleaseError #147992), + reason: fcw!(FutureReleaseError #152822), report_in_deps: false, }; } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index ca0704a9f4352..3086768f83f51 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -818,17 +818,32 @@ impl<'ra> Module<'ra> { let mut traits = self.traits.borrow_mut(resolver.as_ref()); if traits.is_none() { let mut collected_traits = Vec::new(); - self.for_each_child(resolver, |r, ident, _, ns, binding| { + self.for_each_child(resolver, |r, ident, _, ns, mut decl| { if ns != TypeNS { return; } - if let Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) = binding.res() { - collected_traits.push(( - ident.name, - binding, - r.as_ref().get_module(def_id), - binding.is_ambiguity_recursive(), - )); + + let ambiguous = decl.is_ambiguity_recursive(); + let mut try_record_trait = |decl: Decl<'ra>| { + if let Res::Def(DefKind::Trait | DefKind::TraitAlias, def_id) = decl.res() { + collected_traits.push(( + ident.name, + decl, + r.as_ref().get_module(def_id), + ambiguous, + )); + true + } else { + false + } + }; + // Try to record at least one trait if the decl is ambiguous, such that we can + // report the `ambiguous_glob_imported_traits` lint. Otherwise we would report an + // error that the trait is not found. + while !try_record_trait(decl) + && let Some((_, ambig_decl)) = decl.descent_to_ambiguity() + { + decl = ambig_decl; } }); *traits = Some(collected_traits.into_boxed_slice()); diff --git a/tests/ui/imports/ambiguous-trait-and-struct-in-scope.rs b/tests/ui/imports/ambiguous-trait-and-struct-in-scope.rs new file mode 100644 index 0000000000000..ec1ea313302d6 --- /dev/null +++ b/tests/ui/imports/ambiguous-trait-and-struct-in-scope.rs @@ -0,0 +1,39 @@ +//@ check-pass +//@ edition:2018 +// +// Tests that when the primary declaration is not a trait but the ambiguous declaration is, +// the ambiguous trait is still recorded among the module's traits. This is to make sure +// that we can report the `ambiguously_glob_import_trait` lint. +// +// Test case is from #159476. + +mod module_1 { + mod nested_1 { + pub struct Foo; + } + + pub use nested_1::Foo; +} + +mod module_2 { + // same name as the struct + pub trait Foo: Sized { + fn method(self) {} + } + impl Foo for i32 {} +} + +mod module_3 { + mod nested_3 { + use super::*; + use crate::module_2::*; + fn weird() { + 1_i32.method(); //~ WARNING Use of ambiguously glob imported trait `Foo` [ambiguous_glob_imported_traits] + //~| WARNING this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + } + } + + use crate::module_1::*; +} + +fn main() {} diff --git a/tests/ui/imports/ambiguous-trait-and-struct-in-scope.stderr b/tests/ui/imports/ambiguous-trait-and-struct-in-scope.stderr new file mode 100644 index 0000000000000..540d41fb65f22 --- /dev/null +++ b/tests/ui/imports/ambiguous-trait-and-struct-in-scope.stderr @@ -0,0 +1,16 @@ +warning: Use of ambiguously glob imported trait `Foo` + --> $DIR/ambiguous-trait-and-struct-in-scope.rs:31:19 + | +LL | use crate::module_2::*; + | --------------- `Foo` imported ambiguously here +LL | fn weird() { +LL | 1_i32.method(); + | ^^^^^^ + | + = help: Import `Foo` explicitly + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #152822 + = note: `#[warn(ambiguous_glob_imported_traits)]` (part of `#[warn(future_incompatible)]`) on by default + +warning: 1 warning emitted + diff --git a/tests/ui/imports/ambiguous-trait-in-scope.stderr b/tests/ui/imports/ambiguous-trait-in-scope.stderr index 9360e104bf24f..0b37ab0c9d609 100644 --- a/tests/ui/imports/ambiguous-trait-in-scope.stderr +++ b/tests/ui/imports/ambiguous-trait-in-scope.stderr @@ -9,7 +9,7 @@ LL | 0u8.method1(); | = help: Import `Trait` explicitly = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #147992 + = note: for more information, see issue #152822 = note: `#[warn(ambiguous_glob_imported_traits)]` (part of `#[warn(future_incompatible)]`) on by default error[E0599]: no method named `method2` found for type `u8` in the current scope @@ -51,7 +51,7 @@ LL | 0u8.method2(); | = help: Import `Trait` explicitly = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #147992 + = note: for more information, see issue #152822 warning: Use of ambiguously glob imported trait `Trait` --> $DIR/ambiguous-trait-in-scope.rs:49:9 @@ -64,7 +64,7 @@ LL | 0u8.method1(); | = help: Import `Trait` explicitly = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #147992 + = note: for more information, see issue #152822 error[E0599]: no method named `method2` found for type `u8` in the current scope --> $DIR/ambiguous-trait-in-scope.rs:51:9 @@ -90,7 +90,7 @@ LL | 0u8.method1(); | = help: Import `Trait` explicitly = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #147992 + = note: for more information, see issue #152822 error[E0599]: no method named `method2` found for type `u8` in the current scope --> $DIR/ambiguous-trait-in-scope.rs:58:9 @@ -117,7 +117,7 @@ LL | 0u8.method1(); | = help: Import `Trait` explicitly = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #147992 + = note: for more information, see issue #152822 error[E0599]: no method named `method2` found for type `u8` in the current scope --> $DIR/ambiguous-trait-in-scope.rs:66:9 @@ -144,7 +144,7 @@ LL | 0u8.method1(); | = help: Import `Trait` explicitly = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #147992 + = note: for more information, see issue #152822 error[E0599]: no method named `method2` found for type `u8` in the current scope --> $DIR/ambiguous-trait-in-scope.rs:74:9 @@ -170,7 +170,7 @@ LL | 0u8.method1(); | = help: Import `Trait` explicitly = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! - = note: for more information, see issue #147992 + = note: for more information, see issue #152822 error[E0599]: no method named `method2` found for type `u8` in the current scope --> $DIR/ambiguous-trait-in-scope.rs:81:9 From 3eda017460b2757214c2c60a786bd35287448c13 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Mon, 20 Jul 2026 10:30:36 -0700 Subject: [PATCH 3/3] Set the rustc lib path for unstable-book-gen When configured with `rust.rpath = false` or using any other custom library configurations, running `rustc` requires a library path too. This was missing from `unstable-book-gen`'s new `rustc -Zhelp`. (cherry picked from commit 8c6aba08af01d25fd4d6d8b08570c544c5240e29) --- src/bootstrap/src/core/build_steps/doc.rs | 4 ++++ src/tools/unstable-book-gen/src/main.rs | 1 + 2 files changed, 5 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 0f051232757e8..b384cbc362bce 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -1317,6 +1317,10 @@ impl Step for UnstableBookGen { cmd.arg(rustc_path); cmd.arg(out); + // Running rustc requires the library path if rust.rpath = false + // or any other libraries are in a custom location. + builder.add_rustc_lib_path(self.build_compiler, &mut cmd); + cmd.run(builder); } } diff --git a/src/tools/unstable-book-gen/src/main.rs b/src/tools/unstable-book-gen/src/main.rs index 923ca65b25501..e95d00f96c15e 100644 --- a/src/tools/unstable-book-gen/src/main.rs +++ b/src/tools/unstable-book-gen/src/main.rs @@ -128,6 +128,7 @@ fn collect_compiler_flags(rustc_path: impl AsRef) -> Features { rustc.env("RUSTC_BOOTSTRAP", "1"); rustc.arg("-Zhelp"); let output = t!(rustc.output()); + assert!(output.status.success(), "`rustc -Zhelp` failed: {output:?}"); let help_str = t!(String::from_utf8(output.stdout)); let parts = help_str.split("\n -Z").collect::>(); assert!(!parts[1..].is_empty(), "no -Z options were found");