From b6d30faa798bcc42fbd1e9875e2b15d23b2fd11a Mon Sep 17 00:00:00 2001 From: ltdk Date: Wed, 22 Oct 2025 20:27:46 -0400 Subject: [PATCH 1/8] Revert inference failure from AsRef constification (cherry picked from commit cb7fb35ad1b567f02d8f2226df173736fba86850) --- library/alloc/src/borrow.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index cb32896161e5c..4659fb2a8426d 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -441,11 +441,13 @@ where } } +// FIXME(inference): const bounds removed due to inference regressions found by crater; +// see https://github.com/rust-lang/rust/issues/147964 +// #[rustc_const_unstable(feature = "const_convert", issue = "143773")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "143773")] -impl const AsRef for Cow<'_, T> -where - T::Owned: [const] Borrow, +impl AsRef for Cow<'_, T> +// where +// T::Owned: [const] Borrow, { fn as_ref(&self) -> &T { self From 566809897fa37ae389c001c8ac26acb76f019da4 Mon Sep 17 00:00:00 2001 From: ltdk Date: Thu, 23 Oct 2025 03:22:56 -0400 Subject: [PATCH 2/8] Revert inference failure from Deref/Borrow constification (cherry picked from commit ebd5bea84fee777c5f79bb18e39f28b3f666206a) --- library/alloc/src/borrow.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index 4659fb2a8426d..d2ab5412eeabc 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -16,12 +16,13 @@ use crate::fmt; #[cfg(not(no_global_oom_handling))] use crate::string::String; +// FIXME(inference): const bounds removed due to inference regressions found by crater; +// see https://github.com/rust-lang/rust/issues/147964 +// #[rustc_const_unstable(feature = "const_convert", issue = "143773")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "143773")] -impl<'a, B: ?Sized> const Borrow for Cow<'a, B> -where - B: ToOwned, - B::Owned: [const] Borrow, +impl<'a, B: ?Sized + ToOwned> Borrow for Cow<'a, B> +// where +// B::Owned: [const] Borrow, { fn borrow(&self) -> &B { &**self @@ -327,11 +328,13 @@ impl Cow<'_, B> { } } +// FIXME(inference): const bounds removed due to inference regressions found by crater; +// see https://github.com/rust-lang/rust/issues/147964 +// #[rustc_const_unstable(feature = "const_convert", issue = "143773")] #[stable(feature = "rust1", since = "1.0.0")] -#[rustc_const_unstable(feature = "const_convert", issue = "143773")] -impl const Deref for Cow<'_, B> -where - B::Owned: [const] Borrow, +impl Deref for Cow<'_, B> +// where +// B::Owned: [const] Borrow, { type Target = B; From 21ffe30cd5e9e8b5f03454ea0cae6dc4f8cfb33a Mon Sep 17 00:00:00 2001 From: ltdk Date: Thu, 23 Oct 2025 18:24:39 -0400 Subject: [PATCH 3/8] Add regression test for inference failures (cherry picked from commit 4a4f3b0e8e9609136c10a190c3f5572d70bb33ee) --- .../generic-cow-inference-regression.rs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tests/ui/traits/generic-cow-inference-regression.rs diff --git a/tests/ui/traits/generic-cow-inference-regression.rs b/tests/ui/traits/generic-cow-inference-regression.rs new file mode 100644 index 0000000000000..6fd4715f85bbd --- /dev/null +++ b/tests/ui/traits/generic-cow-inference-regression.rs @@ -0,0 +1,20 @@ +//@ run-pass + +// regression test for #147964: +// constification of these traits resulted in inference errors due to additional where clauses + +use std::borrow::{Cow, Borrow}; + +pub fn generic_deref<'a, T: ToOwned, U>(cow: Cow<'a, T>) { + let _: &T = &cow; +} + +pub fn generic_borrow<'a, T: ToOwned, U>(cow: Cow<'a, T>) { + let _: &T = cow.borrow(); +} + +pub fn generic_as_ref<'a, T: ToOwned, U>(cow: Cow<'a, T>) { + let _: &T = cow.as_ref(); +} + +fn main() {} From c956a76bd66cf702ed58f8c61e09712740279f87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Thu, 23 Oct 2025 16:10:53 +0000 Subject: [PATCH 4/8] Revert "Auto merge of #146121 - Muscraft:filter-suggestion-parts, r=petrochenkov" This reverts commit 99317ef14d0be42fa4039eea7c5ce50cb4e9aee7, reversing changes made to 9cd272dc85320e85a8c83a1a338870de52c005f3. (cherry picked from commit a2b48332bac36ede29a14e3fbbed6a45f1527677) --- compiler/rustc_errors/src/diagnostic.rs | 5 ++++ compiler/rustc_errors/src/emitter.rs | 1 + compiler/rustc_errors/src/lib.rs | 27 +++++++------------ .../tests/ui/bool_assert_comparison.stderr | 12 ++++++--- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index ae23ef1e25536..96a4ed3218fbf 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -945,6 +945,11 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { None, "Span must not be empty and have no suggestion", ); + debug_assert_eq!( + parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)), + None, + "suggestion must not have overlapping parts", + ); self.push_suggestion(CodeSuggestion { substitutions: vec![Substitution { parts }], diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 93b1e6b761520..b94370e8e9b40 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -2354,6 +2354,7 @@ impl HumanEmitter { .sum(); let underline_start = (span_start_pos + start) as isize + offset; let underline_end = (span_start_pos + start + sub_len) as isize + offset; + assert!(underline_start >= 0 && underline_end >= 0); let padding: usize = max_line_num_len + 3; for p in underline_start..underline_end { if let DisplaySuggestion::Underline = show_code_change diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 8869799ce90d9..a56e0f3fae132 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -381,17 +381,6 @@ impl CodeSuggestion { // Assumption: all spans are in the same file, and all spans // are disjoint. Sort in ascending order. substitution.parts.sort_by_key(|part| part.span.lo()); - // Verify the assumption that all spans are disjoint - assert_eq!( - substitution.parts.array_windows().find(|[a, b]| a.span.overlaps(b.span)), - None, - "all spans must be disjoint", - ); - - // Account for cases where we are suggesting the same code that's already - // there. This shouldn't happen often, but in some cases for multipart - // suggestions it's much easier to handle it here than in the origin. - substitution.parts.retain(|p| is_different(sm, &p.snippet, p.span)); // Find the bounding span. let lo = substitution.parts.iter().map(|part| part.span.lo()).min()?; @@ -481,12 +470,16 @@ impl CodeSuggestion { _ => 1, }) .sum(); - - line_highlight.push(SubstitutionHighlight { - start: (cur_lo.col.0 as isize + acc) as usize, - end: (cur_lo.col.0 as isize + acc + len) as usize, - }); - + if !is_different(sm, &part.snippet, part.span) { + // Account for cases where we are suggesting the same code that's already + // there. This shouldn't happen often, but in some cases for multipart + // suggestions it's much easier to handle it here than in the origin. + } else { + line_highlight.push(SubstitutionHighlight { + start: (cur_lo.col.0 as isize + acc) as usize, + end: (cur_lo.col.0 as isize + acc + len) as usize, + }); + } buf.push_str(&part.snippet); let cur_hi = sm.lookup_char_pos(part.span.hi()); // Account for the difference between the width of the current code and the diff --git a/src/tools/clippy/tests/ui/bool_assert_comparison.stderr b/src/tools/clippy/tests/ui/bool_assert_comparison.stderr index 72aa6303a2026..f823f08f31dca 100644 --- a/src/tools/clippy/tests/ui/bool_assert_comparison.stderr +++ b/src/tools/clippy/tests/ui/bool_assert_comparison.stderr @@ -272,8 +272,10 @@ LL | assert_eq!(a!(), true); | help: replace it with `assert!(..)` | -LL - assert_eq!(a!(), true); -LL + assert!(a!()); +LL | true +... +LL | +LL ~ assert!(a!()); | error: used `assert_eq!` with a literal bool @@ -284,8 +286,10 @@ LL | assert_eq!(true, b!()); | help: replace it with `assert!(..)` | -LL - assert_eq!(true, b!()); -LL + assert!(b!()); +LL | true +... +LL | +LL ~ assert!(b!()); | error: used `debug_assert_eq!` with a literal bool From 1dda76181e5c05f7d3c59a1de9e946bd340b3afa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Thu, 23 Oct 2025 16:33:56 +0000 Subject: [PATCH 5/8] add `crashes` tests for overlapping spans (cherry picked from commit dd83c576749c66061c2109b96ebec050bb8de5de) --- tests/crashes/146261.rs | 13 +++++++++++++ tests/crashes/146706.rs | 15 +++++++++++++++ tests/crashes/147973.rs | 14 ++++++++++++++ .../crashes/auxiliary/overlapping_spans_helper.rs | 15 +++++++++++++++ 4 files changed, 57 insertions(+) create mode 100644 tests/crashes/146261.rs create mode 100644 tests/crashes/146706.rs create mode 100644 tests/crashes/147973.rs create mode 100644 tests/crashes/auxiliary/overlapping_spans_helper.rs diff --git a/tests/crashes/146261.rs b/tests/crashes/146261.rs new file mode 100644 index 0000000000000..f901497a769c2 --- /dev/null +++ b/tests/crashes/146261.rs @@ -0,0 +1,13 @@ +// This is part of series of regression tests for some diagnostics ICEs encountered in the wild with +// suggestions having overlapping parts under https://github.com/rust-lang/rust/pull/146121. + +//@ needs-rustc-debug-assertions +//@ known-bug: #146261 + +enum U { + B(), +} + +fn main() { + A(U::C) +} diff --git a/tests/crashes/146706.rs b/tests/crashes/146706.rs new file mode 100644 index 0000000000000..358ce3e8600a8 --- /dev/null +++ b/tests/crashes/146706.rs @@ -0,0 +1,15 @@ +// This is part of series of regression tests for some diagnostics ICEs encountered in the wild with +// suggestions having overlapping parts under https://github.com/rust-lang/rust/pull/146121. + +//@ needs-rustc-debug-assertions +//@ known-bug: #146706 + +type Alias<'a, T> = Foo; + +enum Foo { + Bar { t: T }, +} + +fn main() { + Alias::Bar:: { t: 0 }; +} diff --git a/tests/crashes/147973.rs b/tests/crashes/147973.rs new file mode 100644 index 0000000000000..7271c54846f15 --- /dev/null +++ b/tests/crashes/147973.rs @@ -0,0 +1,14 @@ +// This is part of series of regression tests for some diagnostics ICEs encountered in the wild with +// suggestions having overlapping parts under https://github.com/rust-lang/rust/pull/146121. +// This is one MCVE from the beta crater run regressions from issue 147973. + +//@ needs-rustc-debug-assertions +//@ known-bug: #147973 + +//@ aux-build: overlapping_spans_helper.rs +extern crate overlapping_spans_helper; + +fn main() { + let _name = Some(1); + overlapping_spans_helper::do_loop!(_name); +} diff --git a/tests/crashes/auxiliary/overlapping_spans_helper.rs b/tests/crashes/auxiliary/overlapping_spans_helper.rs new file mode 100644 index 0000000000000..e449fcd36c376 --- /dev/null +++ b/tests/crashes/auxiliary/overlapping_spans_helper.rs @@ -0,0 +1,15 @@ +// Auxiliary lib for the issue 147973 regression test with ICEs due to overlapping spans. + +#[macro_export] +macro_rules! identity { + ($x:ident) => { + $x + }; +} + +#[macro_export] +macro_rules! do_loop { + ($x:ident) => { + for $crate::identity!($x) in $x {} + }; +} From 4bc789b5b1fbbbf1d448abcdd17970e97ae70c28 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 23 Oct 2025 12:23:30 -0700 Subject: [PATCH 6/8] Add a regression test for rust-lang/rust#147971 (cherry picked from commit a81ed52f5830b6a305ad8e8547196744d460afa0) --- library/std/tests/ambiguous-hash_map.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 library/std/tests/ambiguous-hash_map.rs diff --git a/library/std/tests/ambiguous-hash_map.rs b/library/std/tests/ambiguous-hash_map.rs new file mode 100644 index 0000000000000..bd5ae5a8957b5 --- /dev/null +++ b/library/std/tests/ambiguous-hash_map.rs @@ -0,0 +1,17 @@ +//! Make sure that a `std` macro `hash_map!` does not cause ambiguity +//! with a local glob import with the same name. +//! +//! See regression https://github.com/rust-lang/rust/issues/147971 + +mod module { + macro_rules! hash_map { + () => {}; + } + pub(crate) use hash_map; +} + +use module::*; + +fn main() { + hash_map! {} +} From 912aba687477596b3a83c93805ae9565650d5e5e Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 23 Oct 2025 12:23:59 -0700 Subject: [PATCH 7/8] Revert "feat: implement `hash_map!` macro" This reverts commit 066023e47c0c92e7edefd60831ce7d6f15f23750. (cherry picked from commit c01682ebf603355795e870afdc28bd0c3bfe2ef5) --- library/std/src/lib.rs | 2 -- library/std/src/macros.rs | 74 --------------------------------------- 2 files changed, 76 deletions(-) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 33e3bf0c085da..39c76ddba568f 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -294,8 +294,6 @@ #![feature(ffi_const)] #![feature(formatting_options)] #![feature(funnel_shifts)] -#![feature(hash_map_internals)] -#![feature(hash_map_macro)] #![feature(if_let_guard)] #![feature(intra_doc_pointers)] #![feature(iter_advance_by)] diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index 254570ae9c836..25e2b7ea13703 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -379,77 +379,3 @@ macro_rules! dbg { ($($crate::dbg!($val)),+,) }; } - -#[doc(hidden)] -#[macro_export] -#[allow_internal_unstable(hash_map_internals)] -#[unstable(feature = "hash_map_internals", issue = "none")] -macro_rules! repetition_utils { - (@count $($tokens:tt),*) => {{ - [$($crate::repetition_utils!(@replace $tokens => ())),*].len() - }}; - - (@replace $x:tt => $y:tt) => { $y } -} - -/// Creates a [`HashMap`] containing the arguments. -/// -/// `hash_map!` allows specifying the entries that make -/// up the [`HashMap`] where the key and value are separated by a `=>`. -/// -/// The entries are separated by commas with a trailing comma being allowed. -/// -/// It is semantically equivalent to using repeated [`HashMap::insert`] -/// on a newly created hashmap. -/// -/// `hash_map!` will attempt to avoid repeated reallocations by -/// using [`HashMap::with_capacity`]. -/// -/// # Examples -/// -/// ```rust -/// #![feature(hash_map_macro)] -/// -/// let map = hash_map! { -/// "key" => "value", -/// "key1" => "value1" -/// }; -/// -/// assert_eq!(map.get("key"), Some(&"value")); -/// assert_eq!(map.get("key1"), Some(&"value1")); -/// assert!(map.get("brrrrrrooooommm").is_none()); -/// ``` -/// -/// And with a trailing comma -/// -///```rust -/// #![feature(hash_map_macro)] -/// -/// let map = hash_map! { -/// "key" => "value", // notice the , -/// }; -/// -/// assert_eq!(map.get("key"), Some(&"value")); -/// ``` -/// -/// The key and value are moved into the HashMap. -/// -/// [`HashMap`]: crate::collections::HashMap -/// [`HashMap::insert`]: crate::collections::HashMap::insert -/// [`HashMap::with_capacity`]: crate::collections::HashMap::with_capacity -#[macro_export] -#[allow_internal_unstable(hash_map_internals)] -#[unstable(feature = "hash_map_macro", issue = "144032")] -macro_rules! hash_map { - () => {{ - $crate::collections::HashMap::new() - }}; - - ( $( $key:expr => $value:expr ),* $(,)? ) => {{ - let mut map = $crate::collections::HashMap::with_capacity( - const { $crate::repetition_utils!(@count $($key),*) } - ); - $( map.insert($key, $value); )* - map - }} -} From 1e668e089dcc294fcc33daab6f0c4d40f0585aec Mon Sep 17 00:00:00 2001 From: Pierre Tardy Date: Thu, 23 Oct 2025 10:06:59 +0200 Subject: [PATCH 8/8] fix panic when rustc tries to reduce intermediate filenames length with multi byte chars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The issue cannot be reproduced with the former testcase of creating external crates because rust refuses to use "external crate 28_找出字符串中第一个匹配项的下标" because it is not a valid indentifier (starts with number, and contain non ascii chars) But still using 28_找出字符串中第一个匹配项的下标.rs as a filename is accepted by previous rustc releases So we consider it valid, and add an integration test for it to catch any regression on other code related to non ascii filenames. (cherry picked from commit c6acffeb785e3efa2909f5ec4a4452cb38ddde17) --- compiler/rustc_session/src/config.rs | 15 ++++++++--- compiler/rustc_session/src/lib.rs | 1 + tests/run-make/lto-long-filenames/rmake.rs | 2 -- tests/run-make/lto-long-filenames_cn/rmake.rs | 25 +++++++++++++++++++ 4 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 tests/run-make/lto-long-filenames_cn/rmake.rs diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 297df7c2c9765..5e47559847e00 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1207,13 +1207,22 @@ fn maybe_strip_file_name(mut path: PathBuf) -> PathBuf { if path.file_name().map_or(0, |name| name.len()) > MAX_FILENAME_LENGTH { let filename = path.file_name().unwrap().to_string_lossy(); let hash_len = 64 / 4; // Hash64 is 64 bits encoded in hex - let stripped_len = filename.len() - MAX_FILENAME_LENGTH + hash_len; + let hyphen_len = 1; // the '-' we insert between hash and suffix + + // number of bytes of suffix we can keep so that "hash-" fits + let allowed_suffix = MAX_FILENAME_LENGTH.saturating_sub(hash_len + hyphen_len); + + // number of bytes to remove from the start + let stripped_bytes = filename.len().saturating_sub(allowed_suffix); + + // ensure we don't cut in a middle of a char + let split_at = filename.ceil_char_boundary(stripped_bytes); let mut hasher = StableHasher::new(); - filename[..stripped_len].hash(&mut hasher); + filename[..split_at].hash(&mut hasher); let hash = hasher.finish::(); - path.set_file_name(format!("{:x}-{}", hash, &filename[stripped_len..])); + path.set_file_name(format!("{:x}-{}", hash, &filename[split_at..])); } path } diff --git a/compiler/rustc_session/src/lib.rs b/compiler/rustc_session/src/lib.rs index 5e5872ee06815..ac11e792fc2e3 100644 --- a/compiler/rustc_session/src/lib.rs +++ b/compiler/rustc_session/src/lib.rs @@ -1,5 +1,6 @@ // tidy-alphabetical-start #![allow(internal_features)] +#![cfg_attr(bootstrap, feature(round_char_boundary))] #![feature(default_field_values)] #![feature(iter_intersperse)] #![feature(rustc_attrs)] diff --git a/tests/run-make/lto-long-filenames/rmake.rs b/tests/run-make/lto-long-filenames/rmake.rs index 9e0ba63e9f5b8..98ce54e5efc82 100644 --- a/tests/run-make/lto-long-filenames/rmake.rs +++ b/tests/run-make/lto-long-filenames/rmake.rs @@ -9,8 +9,6 @@ //@ ignore-cross-compile -use std::fs; - use run_make_support::{rfs, rustc}; // This test make sure we don't get such following error: diff --git a/tests/run-make/lto-long-filenames_cn/rmake.rs b/tests/run-make/lto-long-filenames_cn/rmake.rs new file mode 100644 index 0000000000000..fc25a2ac166b2 --- /dev/null +++ b/tests/run-make/lto-long-filenames_cn/rmake.rs @@ -0,0 +1,25 @@ +//@ ignore-cross-compile +// gnu ld is confused with intermediate files having multibytes characters in their names: +// = note: ld.exe: cannot find f0d5ff18d6510ebc-???_???_??????????_?_?????_?_???????.d50c2 \ +// 4c0c4ea93cc-cgu.0.rcgu.o: Invalid argument +// as this is not something rustc can fix by itself, +// we just skip the test on windows-gnu for now. Hence: +//@ ignore-windows-gnu + +use run_make_support::{rfs, rustc}; + +// This test make sure we don't crash when lto creates output files with long names. +// cn characters can be multi-byte and thus trigger the long filename reduction code more easily. +// we need to make sure that the code is properly generating names at char boundaries. +// as reported in issue #147975 +fn main() { + let lto_flags = ["-Clto", "-Clto=yes", "-Clto=off", "-Clto=thin", "-Clto=fat"]; + for prefix_len in 0..4 { + let prefix: String = std::iter::repeat("_").take(prefix_len).collect(); + let main_file = format!("{}ⵅⴻⵎⵎⴻⵎ_ⴷⵉⵎⴰ_ⵖⴻⴼ_ⵢⵉⵙⴻⴽⴽⵉⵍⴻⵏ_ⵏ_ⵡⴰⵟⴰⵙ_ⵏ_ⵢⵉⴱⵢⵜⴻⵏ.rs", prefix); + rfs::write(&main_file, "fn main() {}\n"); + for flag in lto_flags { + rustc().input(&main_file).arg(flag).run(); + } + } +}