From fe420251223e50b17577aad1e146ee66ec653a15 Mon Sep 17 00:00:00 2001 From: usamoi Date: Thu, 17 Jul 2025 20:50:49 +0800 Subject: [PATCH 01/14] update `Atomic*::from_ptr` and `Atomic*::as_ptr` docs --- library/core/src/sync/atomic.rs | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs index 04c8d1473b04..c010b4d5a0b7 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -563,8 +563,8 @@ pub const fn new(v: bool) -> AtomicBool { /// `align_of::() == 1`). /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`. /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not - /// allowed to mix atomic and non-atomic accesses, or atomic accesses of different sizes, - /// without synchronization. + /// allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different + /// sizes, without synchronization. /// /// [valid]: crate::ptr#safety /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses @@ -1246,7 +1246,7 @@ pub fn fetch_not(&self, order: Ordering) -> bool { /// atomic types work with interior mutability. All modifications of an atomic change the value /// through a shared reference, and can do so safely as long as they use atomic operations. Any /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the same - /// restriction: operations on it must be atomic. + /// restriction in [Memory model for atomic accesses]. /// /// # Examples /// @@ -1264,6 +1264,8 @@ pub fn fetch_not(&self, order: Ordering) -> bool { /// } /// # } /// ``` + /// + /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses #[inline] #[stable(feature = "atomic_as_ptr", since = "1.70.0")] #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")] @@ -1519,8 +1521,8 @@ pub const fn new(p: *mut T) -> AtomicPtr { /// can be bigger than `align_of::<*mut T>()`). /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`. /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not - /// allowed to mix atomic and non-atomic accesses, or atomic accesses of different sizes, - /// without synchronization. + /// allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different + /// sizes, without synchronization. /// /// [valid]: crate::ptr#safety /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses @@ -2488,7 +2490,7 @@ pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T { /// atomic types work with interior mutability. All modifications of an atomic change the value /// through a shared reference, and can do so safely as long as they use atomic operations. Any /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the same - /// restriction: operations on it must be atomic. + /// restriction in [Memory model for atomic accesses]. /// /// # Examples /// @@ -2507,6 +2509,8 @@ pub fn fetch_xor(&self, val: usize, order: Ordering) -> *mut T { /// my_atomic_op(atomic.as_ptr()); /// } /// ``` + /// + /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses #[inline] #[stable(feature = "atomic_as_ptr", since = "1.70.0")] #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")] @@ -2696,8 +2700,8 @@ pub const fn new(v: $int_type) -> Self { }] /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`. /// * You must adhere to the [Memory model for atomic accesses]. In particular, it is not - /// allowed to mix atomic and non-atomic accesses, or atomic accesses of different sizes, - /// without synchronization. + /// allowed to mix conflicting atomic and non-atomic accesses, or atomic accesses of different + /// sizes, without synchronization. /// /// [valid]: crate::ptr#safety /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses @@ -3618,7 +3622,7 @@ pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { /// atomic types work with interior mutability. All modifications of an atomic change the value /// through a shared reference, and can do so safely as long as they use atomic operations. Any /// use of the returned raw pointer requires an `unsafe` block and still has to uphold the same - /// restriction: operations on it must be atomic. + /// restriction in [Memory model for atomic accesses]. /// /// # Examples /// @@ -3638,6 +3642,8 @@ pub fn fetch_min(&self, val: $int_type, order: Ordering) -> $int_type { /// } /// # } /// ``` + /// + /// [Memory model for atomic accesses]: self#memory-model-for-atomic-accesses #[inline] #[stable(feature = "atomic_as_ptr", since = "1.70.0")] #[rustc_const_stable(feature = "atomic_as_ptr", since = "1.70.0")] From 0494311b9c09fc72a17d040299eebdb189e582d2 Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Tue, 22 Jul 2025 11:45:05 +0000 Subject: [PATCH 02/14] miropt: clippy fixes --- src/tools/miropt-test-tools/src/lib.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/tools/miropt-test-tools/src/lib.rs b/src/tools/miropt-test-tools/src/lib.rs index 41b53d2ad0e9..10769c9c8abf 100644 --- a/src/tools/miropt-test-tools/src/lib.rs +++ b/src/tools/miropt-test-tools/src/lib.rs @@ -34,7 +34,7 @@ fn output_file_suffix(testfile: &Path, bit_width: u32, panic_strategy: PanicStra let mut suffix = String::new(); if each_bit_width { - suffix.push_str(&format!(".{}bit", bit_width)); + suffix.push_str(&format!(".{bit_width}bit")); } if each_panic_strategy { match panic_strategy { @@ -51,7 +51,7 @@ pub fn files_for_miropt_test( panic_strategy: PanicStrategy, ) -> MiroptTest { let mut out = Vec::new(); - let test_file_contents = fs::read_to_string(&testfile).unwrap(); + let test_file_contents = fs::read_to_string(testfile).unwrap(); let test_dir = testfile.parent().unwrap(); let test_crate = testfile.file_stem().unwrap().to_str().unwrap().replace('-', "_"); @@ -76,10 +76,10 @@ pub fn files_for_miropt_test( if test_name.ends_with(".diff") { let trimmed = test_name.trim_end_matches(".diff"); - passes.push(trimmed.split('.').last().unwrap().to_owned()); - let test_against = format!("{}.after.mir", trimmed); - from_file = format!("{}.before.mir", trimmed); - expected_file = format!("{}{}.diff", trimmed, suffix); + passes.push(trimmed.split('.').next_back().unwrap().to_owned()); + let test_against = format!("{trimmed}.after.mir"); + from_file = format!("{trimmed}.before.mir"); + expected_file = format!("{trimmed}{suffix}.diff"); assert!(test_names.next().is_none(), "two mir pass names specified for MIR diff"); to_file = Some(test_against); } else if let Some(first_pass) = test_names.next() { @@ -92,10 +92,9 @@ pub fn files_for_miropt_test( } assert!(test_names.next().is_none(), "three mir pass names specified for MIR diff"); - expected_file = - format!("{}{}.{}-{}.diff", test_name, suffix, first_pass, second_pass); - let second_file = format!("{}.{}.mir", test_name, second_pass); - from_file = format!("{}.{}.mir", test_name, first_pass); + expected_file = format!("{test_name}{suffix}.{first_pass}-{second_pass}.diff"); + let second_file = format!("{test_name}.{second_pass}.mir"); + from_file = format!("{test_name}.{first_pass}.mir"); to_file = Some(second_file); } else { // Allow-list for file extensions that can be produced by MIR dumps. @@ -112,7 +111,7 @@ pub fn files_for_miropt_test( ) } - expected_file = format!("{}{}.{}", test_name_wo_ext, suffix, test_name_ext); + expected_file = format!("{test_name_wo_ext}{suffix}.{test_name_ext}"); from_file = test_name.to_string(); assert!(test_names.next().is_none(), "two mir pass names specified for MIR dump"); to_file = None; @@ -123,7 +122,7 @@ pub fn files_for_miropt_test( ); }; if !expected_file.starts_with(&test_crate) { - expected_file = format!("{}.{}", test_crate, expected_file); + expected_file = format!("{test_crate}.{expected_file}"); } let expected_file = test_dir.join(expected_file); From 39ef6a96ad6d4d3340a3597e1efe9755d52c690b Mon Sep 17 00:00:00 2001 From: Marijn Schouten Date: Tue, 22 Jul 2025 11:45:38 +0000 Subject: [PATCH 03/14] miropt: move to edition 2024 --- src/tools/miropt-test-tools/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miropt-test-tools/Cargo.toml b/src/tools/miropt-test-tools/Cargo.toml index 09b4c7d16dce..3eb5020968d3 100644 --- a/src/tools/miropt-test-tools/Cargo.toml +++ b/src/tools/miropt-test-tools/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "miropt-test-tools" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] From 5e1ffef03c79a92143b87edd660a147d889e17d9 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 24 Jul 2025 09:14:46 +0000 Subject: [PATCH 04/14] Improve unit_tests tidy lint Make it clearer where unit tests are allowed and restrict standard library unit tests inside the same package to std_detect, std and test. --- src/tools/tidy/src/main.rs | 6 +-- src/tools/tidy/src/unit_tests.rs | 84 ++++++++++++++++++++------------ 2 files changed, 57 insertions(+), 33 deletions(-) diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 13b20f33bd0f..1a32372d2093 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -127,9 +127,9 @@ macro_rules! check { check!(pal, &library_path); // Checks that need to be done for both the compiler and std libraries. - check!(unit_tests, &src_path); - check!(unit_tests, &compiler_path); - check!(unit_tests, &library_path); + check!(unit_tests, &src_path, false); + check!(unit_tests, &compiler_path, false); + check!(unit_tests, &library_path, true); if bins::check_filesystem_support(&[&root_path], &output_directory) { check!(bins, &root_path); diff --git a/src/tools/tidy/src/unit_tests.rs b/src/tools/tidy/src/unit_tests.rs index df9146b51474..90da1bc765a9 100644 --- a/src/tools/tidy/src/unit_tests.rs +++ b/src/tools/tidy/src/unit_tests.rs @@ -1,44 +1,60 @@ //! Tidy check to ensure `#[test]` and `#[bench]` are not used directly inside -//! `core` or `alloc`. +//! of the standard library. //! //! `core` and `alloc` cannot be tested directly due to duplicating lang items. //! All tests and benchmarks must be written externally in //! `{coretests,alloctests}/{tests,benches}`. //! -//! Outside of `core` and `alloc`, tests and benchmarks should be outlined into -//! separate files named `tests.rs` or `benches.rs`, or directories named +//! Outside of the standard library, tests and benchmarks should be outlined +//! into separate files named `tests.rs` or `benches.rs`, or directories named //! `tests` or `benches` unconfigured during normal build. use std::path::Path; use crate::walk::{filter_dirs, walk}; -pub fn check(root_path: &Path, bad: &mut bool) { - let core = root_path.join("core"); - let core_copy = core.clone(); - let is_core = move |path: &Path| path.starts_with(&core); - let alloc = root_path.join("alloc"); - let alloc_copy = alloc.clone(); - let is_alloc = move |path: &Path| path.starts_with(&alloc); - +pub fn check(root_path: &Path, stdlib: bool, bad: &mut bool) { let skip = move |path: &Path, is_dir| { let file_name = path.file_name().unwrap_or_default(); + + // Skip excluded directories and non-rust files if is_dir { - filter_dirs(path) - || path.ends_with("src/doc") - || (file_name == "tests" || file_name == "benches") - && !is_core(path) - && !is_alloc(path) + if filter_dirs(path) || path.ends_with("src/doc") { + return true; + } } else { let extension = path.extension().unwrap_or_default(); - extension != "rs" - || (file_name == "tests.rs" || file_name == "benches.rs") - && !is_core(path) - && !is_alloc(path) - // Tests which use non-public internals and, as such, need to - // have the types in the same crate as the tests themselves. See - // the comment in alloctests/lib.rs. - || path.ends_with("library/alloc/src/collections/btree/borrow/tests.rs") + if extension != "rs" { + return true; + } + } + + // Tests in a separate package are always allowed + if is_dir && file_name != "tests" && file_name.as_encoded_bytes().ends_with(b"tests") { + return true; + } + + if !stdlib { + // Outside of the standard library tests may also be in separate files in the same crate + if is_dir { + if file_name == "tests" || file_name == "benches" { + return true; + } + } else { + if file_name == "tests.rs" || file_name == "benches.rs" { + return true; + } + } + } + + if is_dir { + // FIXME remove those exceptions once no longer necessary + file_name == "std_detect" || file_name == "std" || file_name == "test" + } else { + // Tests which use non-public internals and, as such, need to + // have the types in the same crate as the tests themselves. See + // the comment in alloctests/lib.rs. + path.ends_with("library/alloc/src/collections/btree/borrow/tests.rs") || path.ends_with("library/alloc/src/collections/btree/map/tests.rs") || path.ends_with("library/alloc/src/collections/btree/node/tests.rs") || path.ends_with("library/alloc/src/collections/btree/set/tests.rs") @@ -50,22 +66,30 @@ pub fn check(root_path: &Path, bad: &mut bool) { walk(root_path, skip, &mut |entry, contents| { let path = entry.path(); - let is_core = path.starts_with(&core_copy); - let is_alloc = path.starts_with(&alloc_copy); + let package = path + .strip_prefix(root_path) + .unwrap() + .components() + .next() + .unwrap() + .as_os_str() + .to_str() + .unwrap(); for (i, line) in contents.lines().enumerate() { let line = line.trim(); let is_test = || line.contains("#[test]") && !line.contains("`#[test]"); let is_bench = || line.contains("#[bench]") && !line.contains("`#[bench]"); let manual_skip = line.contains("//tidy:skip"); if !line.starts_with("//") && (is_test() || is_bench()) && !manual_skip { - let explanation = if is_core { - "`core` unit tests and benchmarks must be placed into `coretests`" - } else if is_alloc { - "`alloc` unit tests and benchmarks must be placed into `alloctests`" + let explanation = if stdlib { + format!( + "`{package}` unit tests and benchmarks must be placed into `{package}tests`" + ) } else { "unit tests and benchmarks must be placed into \ separate files or directories named \ `tests.rs`, `benches.rs`, `tests` or `benches`" + .to_owned() }; let name = if is_test() { "test" } else { "bench" }; tidy_error!( From c5d7021cddd97a4ec8dd64f878711ec983986fcd Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 24 Jul 2025 09:15:28 +0000 Subject: [PATCH 05/14] Disable unit tests for stdlib packages that don't contain any --- library/rustc-std-workspace-alloc/Cargo.toml | 3 +++ library/rustc-std-workspace-core/Cargo.toml | 3 +++ library/rustc-std-workspace-std/Cargo.toml | 3 +++ library/sysroot/Cargo.toml | 2 ++ library/windows_targets/Cargo.toml | 5 +++++ 5 files changed, 16 insertions(+) diff --git a/library/rustc-std-workspace-alloc/Cargo.toml b/library/rustc-std-workspace-alloc/Cargo.toml index 5a177808d1bd..a5b51059119c 100644 --- a/library/rustc-std-workspace-alloc/Cargo.toml +++ b/library/rustc-std-workspace-alloc/Cargo.toml @@ -9,6 +9,9 @@ edition = "2024" [lib] path = "lib.rs" +test = false +bench = false +doc = false [dependencies] alloc = { path = "../alloc" } diff --git a/library/rustc-std-workspace-core/Cargo.toml b/library/rustc-std-workspace-core/Cargo.toml index 1ddc112380f1..d68965c63457 100644 --- a/library/rustc-std-workspace-core/Cargo.toml +++ b/library/rustc-std-workspace-core/Cargo.toml @@ -11,6 +11,9 @@ edition = "2024" [lib] path = "lib.rs" +test = false +bench = false +doc = false [dependencies] core = { path = "../core", public = true } diff --git a/library/rustc-std-workspace-std/Cargo.toml b/library/rustc-std-workspace-std/Cargo.toml index f70994e1f886..6079dc85d906 100644 --- a/library/rustc-std-workspace-std/Cargo.toml +++ b/library/rustc-std-workspace-std/Cargo.toml @@ -9,6 +9,9 @@ edition = "2024" [lib] path = "lib.rs" +test = false +bench = false +doc = false [dependencies] std = { path = "../std" } diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml index 032f5272a9cd..2952556f699d 100644 --- a/library/sysroot/Cargo.toml +++ b/library/sysroot/Cargo.toml @@ -6,6 +6,8 @@ version = "0.0.0" edition = "2024" [lib] +test = false +bench = false # make sure this crate isn't included in public standard library docs doc = false diff --git a/library/windows_targets/Cargo.toml b/library/windows_targets/Cargo.toml index 705c9e043811..1c804a0ab391 100644 --- a/library/windows_targets/Cargo.toml +++ b/library/windows_targets/Cargo.toml @@ -4,6 +4,11 @@ description = "A drop-in replacement for the real windows-targets crate for use version = "0.0.0" edition = "2024" +[lib] +test = false +bench = false +doc = false + [features] # Enable using raw-dylib for Windows imports. # This will eventually be the default. From b481c5b8ba322612fb3bc167e323f7a548a2390c Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Thu, 24 Jul 2025 13:01:08 +0000 Subject: [PATCH 06/14] std_detect testing improvements * Fix riscv testing. Previously the mod tests; would be looking for src/detect/os/tests.rs. * Replace a test with an unnamed const item. It is testing that no warnings are emitted. It doesn't contain any checks that need to run at runtime. Replacing the test allows removing the tidy:skip directive for test locations. --- library/std_detect/src/detect/macros.rs | 5 ++--- library/std_detect/src/detect/os/riscv.rs | 1 + src/tools/tidy/src/unit_tests.rs | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/library/std_detect/src/detect/macros.rs b/library/std_detect/src/detect/macros.rs index c2a006d3753a..17140e15653d 100644 --- a/library/std_detect/src/detect/macros.rs +++ b/library/std_detect/src/detect/macros.rs @@ -131,14 +131,13 @@ macro_rules! $macro_name { }; } - #[test] //tidy:skip #[deny(unexpected_cfgs)] #[deny(unfulfilled_lint_expectations)] - fn unexpected_cfgs() { + const _: () = { $( check_cfg_feature!($feature, $feature_lit $(, without cfg check: $feature_cfg_check)? $(: $($target_feature_lit),*)?); )* - } + }; /// Each variant denotes a position in a bitset for a particular feature. /// diff --git a/library/std_detect/src/detect/os/riscv.rs b/library/std_detect/src/detect/os/riscv.rs index 46b7dd71eb35..dc9a4036d86a 100644 --- a/library/std_detect/src/detect/os/riscv.rs +++ b/library/std_detect/src/detect/os/riscv.rs @@ -135,4 +135,5 @@ macro_rules! group { } #[cfg(test)] +#[path = "riscv/tests.rs"] mod tests; diff --git a/src/tools/tidy/src/unit_tests.rs b/src/tools/tidy/src/unit_tests.rs index 90da1bc765a9..3d14a4673193 100644 --- a/src/tools/tidy/src/unit_tests.rs +++ b/src/tools/tidy/src/unit_tests.rs @@ -79,8 +79,7 @@ pub fn check(root_path: &Path, stdlib: bool, bad: &mut bool) { let line = line.trim(); let is_test = || line.contains("#[test]") && !line.contains("`#[test]"); let is_bench = || line.contains("#[bench]") && !line.contains("`#[bench]"); - let manual_skip = line.contains("//tidy:skip"); - if !line.starts_with("//") && (is_test() || is_bench()) && !manual_skip { + if !line.starts_with("//") && (is_test() || is_bench()) { let explanation = if stdlib { format!( "`{package}` unit tests and benchmarks must be placed into `{package}tests`" From 27e2709f3e8d8f03b05704bc7e3e9110dd64397b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Tue, 22 Jul 2025 14:05:03 +0000 Subject: [PATCH 07/14] Improve coordinator channel handling Remove usage of Any, reduce visibility of fields and remove unused backend arguments. --- compiler/rustc_codegen_ssa/src/back/write.rs | 49 +++++++++----------- compiler/rustc_codegen_ssa/src/base.rs | 16 ++----- 2 files changed, 25 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 7be274df1d41..a41cbd306d0c 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -1,4 +1,3 @@ -use std::any::Any; use std::assert_matches::assert_matches; use std::marker::PhantomData; use std::path::{Path, PathBuf}; @@ -372,8 +371,6 @@ pub struct CodegenContext { /// The incremental compilation session directory, or None if we are not /// compiling incrementally pub incr_comp_session_dir: Option, - /// Channel back to the main control thread to send messages to - pub coordinator_send: Sender>, /// `true` if the codegen should be run in parallel. /// /// Depends on [`ExtraBackendMethods::supports_parallel()`] and `-Zno_parallel_backend`. @@ -1122,10 +1119,10 @@ fn start_executing_work( autodiff_items: &[AutoDiffItem], shared_emitter: SharedEmitter, codegen_worker_send: Sender, - coordinator_receive: Receiver>, + coordinator_receive: Receiver>, regular_config: Arc, allocator_config: Arc, - tx_to_llvm_workers: Sender>, + tx_to_llvm_workers: Sender>, ) -> thread::JoinHandle> { let coordinator_send = tx_to_llvm_workers; let sess = tcx.sess; @@ -1153,7 +1150,7 @@ fn start_executing_work( let coordinator_send2 = coordinator_send.clone(); let helper = jobserver::client() .into_helper_thread(move |token| { - drop(coordinator_send2.send(Box::new(Message::Token::(token)))); + drop(coordinator_send2.send(Message::Token::(token))); }) .expect("failed to spawn helper thread"); @@ -1187,7 +1184,6 @@ fn start_executing_work( remark: sess.opts.cg.remark.clone(), remark_dir, incr_comp_session_dir: sess.incr_comp_session_dir_opt().map(|r| r.clone()), - coordinator_send, expanded_args: tcx.sess.expanded_args.clone(), diag_emitter: shared_emitter.clone(), output_filenames: Arc::clone(tcx.output_filenames(())), @@ -1423,7 +1419,7 @@ enum CodegenState { let (item, _) = work_items.pop().expect("queue empty - queue_full_enough() broken?"); main_thread_state = MainThreadState::Lending; - spawn_work(&cgcx, &mut llvm_start_time, item); + spawn_work(&cgcx, coordinator_send.clone(), &mut llvm_start_time, item); } } } else if codegen_state == Completed { @@ -1502,7 +1498,7 @@ enum CodegenState { MainThreadState::Idle => { if let Some((item, _)) = work_items.pop() { main_thread_state = MainThreadState::Lending; - spawn_work(&cgcx, &mut llvm_start_time, item); + spawn_work(&cgcx, coordinator_send.clone(), &mut llvm_start_time, item); } else { // There is no unstarted work, so let the main thread // take over for a running worker. Otherwise the @@ -1538,7 +1534,7 @@ enum CodegenState { while running_with_own_token < tokens.len() && let Some((item, _)) = work_items.pop() { - spawn_work(&cgcx, &mut llvm_start_time, item); + spawn_work(&cgcx, coordinator_send.clone(), &mut llvm_start_time, item); running_with_own_token += 1; } } @@ -1546,8 +1542,7 @@ enum CodegenState { // Relinquish accidentally acquired extra tokens. tokens.truncate(running_with_own_token); - let msg = coordinator_receive.recv().unwrap(); - match *msg.downcast::>().ok().unwrap() { + match coordinator_receive.recv().unwrap() { // Save the token locally and the next turn of the loop will use // this to spawn a new unit of work, or it may get dropped // immediately if we have no more work to spawn. @@ -1769,6 +1764,7 @@ fn queue_full_enough(items_in_queue: usize, workers_running: usize) -> bool { fn spawn_work<'a, B: ExtraBackendMethods>( cgcx: &'a CodegenContext, + coordinator_send: Sender>, llvm_start_time: &mut Option>, work: WorkItem, ) { @@ -1782,7 +1778,7 @@ fn spawn_work<'a, B: ExtraBackendMethods>( // Set up a destructor which will fire off a message that we're done as // we exit. struct Bomb { - coordinator_send: Sender>, + coordinator_send: Sender>, result: Option, FatalError>>, } impl Drop for Bomb { @@ -1794,11 +1790,11 @@ fn drop(&mut self) { } None => Message::WorkItem:: { result: Err(None) }, }; - drop(self.coordinator_send.send(Box::new(msg))); + drop(self.coordinator_send.send(msg)); } } - let mut bomb = Bomb:: { coordinator_send: cgcx.coordinator_send.clone(), result: None }; + let mut bomb = Bomb:: { coordinator_send, result: None }; // Execute the work itself, and if it finishes successfully then flag // ourselves as a success as well. @@ -2003,7 +1999,7 @@ fn check(&self, sess: &Session, blocking: bool) { } pub struct Coordinator { - pub sender: Sender>, + sender: Sender>, future: Option>>, // Only used for the Message type. phantom: PhantomData, @@ -2020,7 +2016,7 @@ fn drop(&mut self) { if let Some(future) = self.future.take() { // If we haven't joined yet, signal to the coordinator that it should spawn no more // work, and wait for worker threads to finish. - drop(self.sender.send(Box::new(Message::CodegenAborted::))); + drop(self.sender.send(Message::CodegenAborted::)); drop(future.join()); } } @@ -2079,7 +2075,7 @@ pub fn join(self, sess: &Session) -> (CodegenResults, FxIndexMap) { self.wait_for_signal_to_codegen_item(); self.check_for_errors(tcx.sess); - drop(self.coordinator.sender.send(Box::new(Message::CodegenComplete::))); + drop(self.coordinator.sender.send(Message::CodegenComplete::)); } pub(crate) fn check_for_errors(&self, sess: &Session) { @@ -2100,28 +2096,25 @@ pub(crate) fn wait_for_signal_to_codegen_item(&self) { } pub(crate) fn submit_codegened_module_to_llvm( - _backend: &B, - tx_to_llvm_workers: &Sender>, + coordinator: &Coordinator, module: ModuleCodegen, cost: u64, ) { let llvm_work_item = WorkItem::Optimize(module); - drop(tx_to_llvm_workers.send(Box::new(Message::CodegenDone:: { llvm_work_item, cost }))); + drop(coordinator.sender.send(Message::CodegenDone:: { llvm_work_item, cost })); } pub(crate) fn submit_post_lto_module_to_llvm( - _backend: &B, - tx_to_llvm_workers: &Sender>, + coordinator: &Coordinator, module: CachedModuleCodegen, ) { let llvm_work_item = WorkItem::CopyPostLtoArtifacts(module); - drop(tx_to_llvm_workers.send(Box::new(Message::CodegenDone:: { llvm_work_item, cost: 0 }))); + drop(coordinator.sender.send(Message::CodegenDone:: { llvm_work_item, cost: 0 })); } pub(crate) fn submit_pre_lto_module_to_llvm( - _backend: &B, tcx: TyCtxt<'_>, - tx_to_llvm_workers: &Sender>, + coordinator: &Coordinator, module: CachedModuleCodegen, ) { let filename = pre_lto_bitcode_filename(&module.name); @@ -2135,10 +2128,10 @@ pub(crate) fn submit_pre_lto_module_to_llvm( }) }; // Schedule the module to be loaded - drop(tx_to_llvm_workers.send(Box::new(Message::AddImportOnlyModule:: { + drop(coordinator.sender.send(Message::AddImportOnlyModule:: { module_data: SerializedModule::FromUncompressedFile(mmap), work_product: module.source, - }))); + })); } fn pre_lto_bitcode_filename(module_name: &str) -> String { diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 833456abb8ab..a5807c56e317 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -702,8 +702,7 @@ pub fn codegen_crate( // These modules are generally cheap and won't throw off scheduling. let cost = 0; submit_codegened_module_to_llvm( - &backend, - &ongoing_codegen.coordinator.sender, + &ongoing_codegen.coordinator, ModuleCodegen::new_allocator(llmod_id, module_llvm), cost, ); @@ -800,18 +799,12 @@ pub fn codegen_crate( // compilation hang on post-monomorphization errors. tcx.dcx().abort_if_errors(); - submit_codegened_module_to_llvm( - &backend, - &ongoing_codegen.coordinator.sender, - module, - cost, - ); + submit_codegened_module_to_llvm(&ongoing_codegen.coordinator, module, cost); } CguReuse::PreLto => { submit_pre_lto_module_to_llvm( - &backend, tcx, - &ongoing_codegen.coordinator.sender, + &ongoing_codegen.coordinator, CachedModuleCodegen { name: cgu.name().to_string(), source: cgu.previous_work_product(tcx), @@ -820,8 +813,7 @@ pub fn codegen_crate( } CguReuse::PostLto => { submit_post_lto_module_to_llvm( - &backend, - &ongoing_codegen.coordinator.sender, + &ongoing_codegen.coordinator, CachedModuleCodegen { name: cgu.name().to_string(), source: cgu.previous_work_product(tcx), From fe2eeabe27ce3d5b871ab903e65b4707ad015764 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 25 Jul 2025 09:42:18 +0000 Subject: [PATCH 08/14] Use the object crate rather than LLVM for extracting bitcode sections --- compiler/rustc_codegen_llvm/messages.ftl | 2 +- compiler/rustc_codegen_llvm/src/back/lto.rs | 31 +++++------------ compiler/rustc_codegen_llvm/src/errors.rs | 2 +- compiler/rustc_codegen_llvm/src/llvm/ffi.rs | 7 ---- .../rustc_llvm/llvm-wrapper/PassWrapper.cpp | 34 ------------------- 5 files changed, 10 insertions(+), 66 deletions(-) diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl index 3d5f17a60345..ce9a51b539d8 100644 --- a/compiler/rustc_codegen_llvm/messages.ftl +++ b/compiler/rustc_codegen_llvm/messages.ftl @@ -12,7 +12,7 @@ codegen_llvm_from_llvm_optimization_diag = {$filename}:{$line}:{$column} {$pass_ codegen_llvm_load_bitcode = failed to load bitcode of module "{$name}" codegen_llvm_load_bitcode_with_llvm_err = failed to load bitcode of module "{$name}": {$llvm_err} -codegen_llvm_lto_bitcode_from_rlib = failed to get bitcode from object file for LTO ({$llvm_err}) +codegen_llvm_lto_bitcode_from_rlib = failed to get bitcode from object file for LTO ({$err}) codegen_llvm_mismatch_data_layout = data-layout for target `{$rustc_target}`, `{$rustc_layout}`, differs from LLVM target's `{$llvm_target}` default layout, `{$llvm_layout}` diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs index 767835c34f02..cac7d49b74a5 100644 --- a/compiler/rustc_codegen_llvm/src/back/lto.rs +++ b/compiler/rustc_codegen_llvm/src/back/lto.rs @@ -7,6 +7,7 @@ use std::{io, iter, slice}; use object::read::archive::ArchiveFile; +use object::{Object, ObjectSection}; use rustc_codegen_ssa::back::lto::{SerializedModule, ThinModule, ThinShared}; use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput}; use rustc_codegen_ssa::traits::*; @@ -105,31 +106,15 @@ fn get_bitcode_slice_from_object_data<'a>( // name" which in the public API for sections gets treated as part of the section name, but // internally in MachOObjectFile.cpp gets treated separately. let section_name = bitcode_section_name(cgcx).to_str().unwrap().trim_start_matches("__LLVM,"); - let mut len = 0; - let data = unsafe { - llvm::LLVMRustGetSliceFromObjectDataByName( - obj.as_ptr(), - obj.len(), - section_name.as_ptr(), - section_name.len(), - &mut len, - ) - }; - if !data.is_null() { - assert!(len != 0); - let bc = unsafe { slice::from_raw_parts(data, len) }; - // `bc` must be a sub-slice of `obj`. - assert!(obj.as_ptr() <= bc.as_ptr()); - assert!(bc[bc.len()..bc.len()].as_ptr() <= obj[obj.len()..obj.len()].as_ptr()); + let obj = + object::File::parse(obj).map_err(|err| LtoBitcodeFromRlib { err: err.to_string() })?; - Ok(bc) - } else { - assert!(len == 0); - Err(LtoBitcodeFromRlib { - llvm_err: llvm::last_error().unwrap_or_else(|| "unknown LLVM error".to_string()), - }) - } + let section = obj + .section_by_name(section_name) + .ok_or_else(|| LtoBitcodeFromRlib { err: format!("Can't find section {section_name}") })?; + + section.data().map_err(|err| LtoBitcodeFromRlib { err: err.to_string() }) } /// Performs fat LTO by merging all modules into a single one and returning it diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs index 2a889888a39b..627b0c9ff3b3 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -39,7 +39,7 @@ fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> { #[derive(Diagnostic)] #[diag(codegen_llvm_lto_bitcode_from_rlib)] pub(crate) struct LtoBitcodeFromRlib { - pub llvm_err: String, + pub err: String, } #[derive(Diagnostic)] diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs index edfb29dd1be7..0d0cb5f139ee 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2612,13 +2612,6 @@ pub(crate) fn LLVMRustParseBitcodeForLTO( len: usize, Identifier: *const c_char, ) -> Option<&Module>; - pub(crate) fn LLVMRustGetSliceFromObjectDataByName( - data: *const u8, - len: usize, - name: *const u8, - name_len: usize, - out_len: &mut usize, - ) -> *const u8; pub(crate) fn LLVMRustLinkerNew(M: &Module) -> &mut Linker<'_>; pub(crate) fn LLVMRustLinkerAdd( diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp index a2e4d7306cbf..8c34052770e6 100644 --- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp @@ -1650,40 +1650,6 @@ extern "C" LLVMModuleRef LLVMRustParseBitcodeForLTO(LLVMContextRef Context, return wrap(std::move(*SrcOrError).release()); } -// Find a section of an object file by name. Fail if the section is missing or -// empty. -extern "C" const char *LLVMRustGetSliceFromObjectDataByName(const char *data, - size_t len, - const char *name, - size_t name_len, - size_t *out_len) { - *out_len = 0; - auto Name = StringRef(name, name_len); - auto Data = StringRef(data, len); - auto Buffer = MemoryBufferRef(Data, ""); // The id is unused. - file_magic Type = identify_magic(Buffer.getBuffer()); - Expected> ObjFileOrError = - object::ObjectFile::createObjectFile(Buffer, Type); - if (!ObjFileOrError) { - LLVMRustSetLastError(toString(ObjFileOrError.takeError()).c_str()); - return nullptr; - } - for (const object::SectionRef &Sec : (*ObjFileOrError)->sections()) { - Expected SecName = Sec.getName(); - if (SecName && *SecName == Name) { - Expected SectionOrError = Sec.getContents(); - if (!SectionOrError) { - LLVMRustSetLastError(toString(SectionOrError.takeError()).c_str()); - return nullptr; - } - *out_len = SectionOrError->size(); - return SectionOrError->data(); - } - } - LLVMRustSetLastError("could not find requested section"); - return nullptr; -} - // Computes the LTO cache key for the provided 'ModId' in the given 'Data', // storing the result in 'KeyOut'. // Currently, this cache key is a SHA-1 hash of anything that could affect From 9f38ca97eab53ba2f431a48bec2343ef52335714 Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Fri, 18 Jul 2025 22:00:30 +0500 Subject: [PATCH 09/14] move 28 tests --- .../issue-10396.rs => array-slice-vec/array-pattern-matching.rs} | 0 .../issue-11205.rs => array-slice-vec/trait-object-arrays.rs} | 0 .../issue-11192.rs => borrowck/closure-borrow-conflict.rs} | 0 .../issue-11085.rs => cfg/conditional-compilation-struct.rs} | 0 .../ui/{issues/issue-10718.rs => closures/fnonce-closure-call.rs} | 0 .../{issues/issue-10734.rs => drop/conditional-drop-behavior.rs} | 0 .../{issues/issue-10802.rs => drop/trait-object-drop-behavior.rs} | 0 .../issue-10764.rs => extern/extern-rust-fn-type-error.rs} | 0 .../{issues/issue-10877.rs => extern/foreign-fn-pattern-error.rs} | 0 tests/ui/{issues/issue-10767.rs => fn/boxed-fn-pointer.rs} | 0 .../{issues/issue-10436.rs => generics/generic-type-inference.rs} | 0 .../ui/{issues/issue-10806.rs => imports/empty-use-statements.rs} | 0 .../issue-10291.rs => lifetimes/closure-lifetime-bounds-error.rs} | 0 .../issue-11374.rs => lifetimes/container-lifetime-error.rs} | 0 .../issue-10228.rs => lifetimes/enum-lifetime-container.rs} | 0 .../issue-10412.rs => lifetimes/keyword-self-lifetime-error.rs} | 0 .../{issues/issue-10902.rs => lifetimes/trait-lifetime-bounds.rs} | 0 tests/ui/{issues/issue-10853.rs => lint/inner-doc-attributes.rs} | 0 tests/ui/{issues/issue-10638.rs => parser/comment-parsing.rs} | 0 .../{issues/issue-10683.rs => pattern/ascii-lowercase-match.rs} | 0 .../issue-10545.rs => privacy/private-struct-access-error.rs} | 0 .../issue-11267.rs => structs/mutable-unit-struct-borrow.rs} | 0 .../issue-10456.rs => traits/blanket-impl-trait-object.rs} | 0 .../issue-10465.rs => traits/missing-trait-method-error.rs} | 0 .../issue-106755.rs => traits/negative-positive-impl-conflict.rs} | 0 .../issue-102964.rs => type-alias/mismatched-rc-foo-types.rs} | 0 .../issue-11047.rs => type-alias/static-method-type-alias.rs} | 0 .../issue-11004.rs => unsafe/raw-pointer-field-access-error.rs} | 0 28 files changed, 0 insertions(+), 0 deletions(-) rename tests/ui/{issues/issue-10396.rs => array-slice-vec/array-pattern-matching.rs} (100%) rename tests/ui/{issues/issue-11205.rs => array-slice-vec/trait-object-arrays.rs} (100%) rename tests/ui/{issues/issue-11192.rs => borrowck/closure-borrow-conflict.rs} (100%) rename tests/ui/{issues/issue-11085.rs => cfg/conditional-compilation-struct.rs} (100%) rename tests/ui/{issues/issue-10718.rs => closures/fnonce-closure-call.rs} (100%) rename tests/ui/{issues/issue-10734.rs => drop/conditional-drop-behavior.rs} (100%) rename tests/ui/{issues/issue-10802.rs => drop/trait-object-drop-behavior.rs} (100%) rename tests/ui/{issues/issue-10764.rs => extern/extern-rust-fn-type-error.rs} (100%) rename tests/ui/{issues/issue-10877.rs => extern/foreign-fn-pattern-error.rs} (100%) rename tests/ui/{issues/issue-10767.rs => fn/boxed-fn-pointer.rs} (100%) rename tests/ui/{issues/issue-10436.rs => generics/generic-type-inference.rs} (100%) rename tests/ui/{issues/issue-10806.rs => imports/empty-use-statements.rs} (100%) rename tests/ui/{issues/issue-10291.rs => lifetimes/closure-lifetime-bounds-error.rs} (100%) rename tests/ui/{issues/issue-11374.rs => lifetimes/container-lifetime-error.rs} (100%) rename tests/ui/{issues/issue-10228.rs => lifetimes/enum-lifetime-container.rs} (100%) rename tests/ui/{issues/issue-10412.rs => lifetimes/keyword-self-lifetime-error.rs} (100%) rename tests/ui/{issues/issue-10902.rs => lifetimes/trait-lifetime-bounds.rs} (100%) rename tests/ui/{issues/issue-10853.rs => lint/inner-doc-attributes.rs} (100%) rename tests/ui/{issues/issue-10638.rs => parser/comment-parsing.rs} (100%) rename tests/ui/{issues/issue-10683.rs => pattern/ascii-lowercase-match.rs} (100%) rename tests/ui/{issues/issue-10545.rs => privacy/private-struct-access-error.rs} (100%) rename tests/ui/{issues/issue-11267.rs => structs/mutable-unit-struct-borrow.rs} (100%) rename tests/ui/{issues/issue-10456.rs => traits/blanket-impl-trait-object.rs} (100%) rename tests/ui/{issues/issue-10465.rs => traits/missing-trait-method-error.rs} (100%) rename tests/ui/{issues/issue-106755.rs => traits/negative-positive-impl-conflict.rs} (100%) rename tests/ui/{issues/issue-102964.rs => type-alias/mismatched-rc-foo-types.rs} (100%) rename tests/ui/{issues/issue-11047.rs => type-alias/static-method-type-alias.rs} (100%) rename tests/ui/{issues/issue-11004.rs => unsafe/raw-pointer-field-access-error.rs} (100%) diff --git a/tests/ui/issues/issue-10396.rs b/tests/ui/array-slice-vec/array-pattern-matching.rs similarity index 100% rename from tests/ui/issues/issue-10396.rs rename to tests/ui/array-slice-vec/array-pattern-matching.rs diff --git a/tests/ui/issues/issue-11205.rs b/tests/ui/array-slice-vec/trait-object-arrays.rs similarity index 100% rename from tests/ui/issues/issue-11205.rs rename to tests/ui/array-slice-vec/trait-object-arrays.rs diff --git a/tests/ui/issues/issue-11192.rs b/tests/ui/borrowck/closure-borrow-conflict.rs similarity index 100% rename from tests/ui/issues/issue-11192.rs rename to tests/ui/borrowck/closure-borrow-conflict.rs diff --git a/tests/ui/issues/issue-11085.rs b/tests/ui/cfg/conditional-compilation-struct.rs similarity index 100% rename from tests/ui/issues/issue-11085.rs rename to tests/ui/cfg/conditional-compilation-struct.rs diff --git a/tests/ui/issues/issue-10718.rs b/tests/ui/closures/fnonce-closure-call.rs similarity index 100% rename from tests/ui/issues/issue-10718.rs rename to tests/ui/closures/fnonce-closure-call.rs diff --git a/tests/ui/issues/issue-10734.rs b/tests/ui/drop/conditional-drop-behavior.rs similarity index 100% rename from tests/ui/issues/issue-10734.rs rename to tests/ui/drop/conditional-drop-behavior.rs diff --git a/tests/ui/issues/issue-10802.rs b/tests/ui/drop/trait-object-drop-behavior.rs similarity index 100% rename from tests/ui/issues/issue-10802.rs rename to tests/ui/drop/trait-object-drop-behavior.rs diff --git a/tests/ui/issues/issue-10764.rs b/tests/ui/extern/extern-rust-fn-type-error.rs similarity index 100% rename from tests/ui/issues/issue-10764.rs rename to tests/ui/extern/extern-rust-fn-type-error.rs diff --git a/tests/ui/issues/issue-10877.rs b/tests/ui/extern/foreign-fn-pattern-error.rs similarity index 100% rename from tests/ui/issues/issue-10877.rs rename to tests/ui/extern/foreign-fn-pattern-error.rs diff --git a/tests/ui/issues/issue-10767.rs b/tests/ui/fn/boxed-fn-pointer.rs similarity index 100% rename from tests/ui/issues/issue-10767.rs rename to tests/ui/fn/boxed-fn-pointer.rs diff --git a/tests/ui/issues/issue-10436.rs b/tests/ui/generics/generic-type-inference.rs similarity index 100% rename from tests/ui/issues/issue-10436.rs rename to tests/ui/generics/generic-type-inference.rs diff --git a/tests/ui/issues/issue-10806.rs b/tests/ui/imports/empty-use-statements.rs similarity index 100% rename from tests/ui/issues/issue-10806.rs rename to tests/ui/imports/empty-use-statements.rs diff --git a/tests/ui/issues/issue-10291.rs b/tests/ui/lifetimes/closure-lifetime-bounds-error.rs similarity index 100% rename from tests/ui/issues/issue-10291.rs rename to tests/ui/lifetimes/closure-lifetime-bounds-error.rs diff --git a/tests/ui/issues/issue-11374.rs b/tests/ui/lifetimes/container-lifetime-error.rs similarity index 100% rename from tests/ui/issues/issue-11374.rs rename to tests/ui/lifetimes/container-lifetime-error.rs diff --git a/tests/ui/issues/issue-10228.rs b/tests/ui/lifetimes/enum-lifetime-container.rs similarity index 100% rename from tests/ui/issues/issue-10228.rs rename to tests/ui/lifetimes/enum-lifetime-container.rs diff --git a/tests/ui/issues/issue-10412.rs b/tests/ui/lifetimes/keyword-self-lifetime-error.rs similarity index 100% rename from tests/ui/issues/issue-10412.rs rename to tests/ui/lifetimes/keyword-self-lifetime-error.rs diff --git a/tests/ui/issues/issue-10902.rs b/tests/ui/lifetimes/trait-lifetime-bounds.rs similarity index 100% rename from tests/ui/issues/issue-10902.rs rename to tests/ui/lifetimes/trait-lifetime-bounds.rs diff --git a/tests/ui/issues/issue-10853.rs b/tests/ui/lint/inner-doc-attributes.rs similarity index 100% rename from tests/ui/issues/issue-10853.rs rename to tests/ui/lint/inner-doc-attributes.rs diff --git a/tests/ui/issues/issue-10638.rs b/tests/ui/parser/comment-parsing.rs similarity index 100% rename from tests/ui/issues/issue-10638.rs rename to tests/ui/parser/comment-parsing.rs diff --git a/tests/ui/issues/issue-10683.rs b/tests/ui/pattern/ascii-lowercase-match.rs similarity index 100% rename from tests/ui/issues/issue-10683.rs rename to tests/ui/pattern/ascii-lowercase-match.rs diff --git a/tests/ui/issues/issue-10545.rs b/tests/ui/privacy/private-struct-access-error.rs similarity index 100% rename from tests/ui/issues/issue-10545.rs rename to tests/ui/privacy/private-struct-access-error.rs diff --git a/tests/ui/issues/issue-11267.rs b/tests/ui/structs/mutable-unit-struct-borrow.rs similarity index 100% rename from tests/ui/issues/issue-11267.rs rename to tests/ui/structs/mutable-unit-struct-borrow.rs diff --git a/tests/ui/issues/issue-10456.rs b/tests/ui/traits/blanket-impl-trait-object.rs similarity index 100% rename from tests/ui/issues/issue-10456.rs rename to tests/ui/traits/blanket-impl-trait-object.rs diff --git a/tests/ui/issues/issue-10465.rs b/tests/ui/traits/missing-trait-method-error.rs similarity index 100% rename from tests/ui/issues/issue-10465.rs rename to tests/ui/traits/missing-trait-method-error.rs diff --git a/tests/ui/issues/issue-106755.rs b/tests/ui/traits/negative-positive-impl-conflict.rs similarity index 100% rename from tests/ui/issues/issue-106755.rs rename to tests/ui/traits/negative-positive-impl-conflict.rs diff --git a/tests/ui/issues/issue-102964.rs b/tests/ui/type-alias/mismatched-rc-foo-types.rs similarity index 100% rename from tests/ui/issues/issue-102964.rs rename to tests/ui/type-alias/mismatched-rc-foo-types.rs diff --git a/tests/ui/issues/issue-11047.rs b/tests/ui/type-alias/static-method-type-alias.rs similarity index 100% rename from tests/ui/issues/issue-11047.rs rename to tests/ui/type-alias/static-method-type-alias.rs diff --git a/tests/ui/issues/issue-11004.rs b/tests/ui/unsafe/raw-pointer-field-access-error.rs similarity index 100% rename from tests/ui/issues/issue-11004.rs rename to tests/ui/unsafe/raw-pointer-field-access-error.rs From e9959aa74e23eb340d6c9e9a4eab807be03b028f Mon Sep 17 00:00:00 2001 From: Kivooeo Date: Fri, 18 Jul 2025 22:06:07 +0500 Subject: [PATCH 10/14] comments --- tests/ui/README.md | 4 ++++ ...flict.rs => closure-borrow-conflict-11192.rs} | 2 ++ .../closure-borrow-conflict-11192.stderr} | 2 +- ...s => conditional-compilation-struct-11085.rs} | 2 ++ .../trait-object-arrays-11205.rs} | 2 ++ .../primary-fluent-bundle-missing.rs} | 2 ++ .../primary-fluent-bundle-missing.stderr} | 12 ++++++------ ...rop-behavior.rs => conditional-drop-10734.rs} | 2 ++ ...op-behavior.rs => trait-object-drop-10802.rs} | 2 ++ ...ror.rs => extern-rust-fn-type-error-10764.rs} | 2 ++ .../extern-rust-fn-type-error-10764.stderr} | 4 ++-- ...rror.rs => foreign-fn-pattern-error-10877.rs} | 2 ++ .../foreign-fn-pattern-error-10877.stderr} | 8 ++++---- tests/ui/fn/boxed-fn-pointer.rs | 7 ------- ...=> use-declaration-no-path-segment-prefix.rs} | 2 ++ .../fnonce-closure-call.rs | 2 ++ .../generic-type-inference-10436.rs} | 2 ++ .../array-pattern-matching-10396.rs} | 2 ++ ...error.rs => closure-lifetime-bounds-10291.rs} | 2 ++ .../closure-lifetime-bounds-10291.stderr} | 2 +- ...rror.rs => container-lifetime-error-11374.rs} | 2 ++ .../container-lifetime-error-11374.stderr} | 6 +++--- ...ainer.rs => enum-lifetime-container-10228.rs} | 2 ++ ...r.rs => keyword-self-lifetime-error-10412.rs} | 2 ++ .../keyword-self-lifetime-error-10412.stderr} | 16 ++++++++-------- ...ruct-vs-struct-with-fields-borrowck-10902.rs} | 2 ++ ...rs => missing-doc-unsugard-doc-attr-10853.rs} | 2 ++ ...comment-parsing.rs => doc-comment-parsing.rs} | 2 ++ ...ture-match-scrutinee-temporary-drop-10683.rs} | 2 ++ ....rs => struct-field-and-impl-expose-10545.rs} | 2 ++ .../struct-field-and-impl-expose-10545.stderr} | 4 ++-- ...ow.rs => mutable-unit-struct-borrow-11267.rs} | 2 ++ ...ect.rs => blanket-impl-trait-object-10456.rs} | 2 ++ ...nested-mod-trait-method-lookup-leak-10465.rs} | 2 ++ ...ed-mod-trait-method-lookup-leak-10465.stderr} | 2 +- ...ed-rc-foo-types.rs => dummy-binder-102964.rs} | 2 ++ .../dummy-binder-102964.stderr} | 2 +- ...lias.rs => static-method-type-alias-11047.rs} | 2 ++ .../ui/unsafe/raw-pointer-field-access-error.rs | 2 ++ .../raw-pointer-field-access-error.stderr} | 4 ++-- 40 files changed, 89 insertions(+), 38 deletions(-) rename tests/ui/borrowck/{closure-borrow-conflict.rs => closure-borrow-conflict-11192.rs} (85%) rename tests/ui/{issues/issue-11192.stderr => borrowck/closure-borrow-conflict-11192.stderr} (92%) rename tests/ui/cfg/{conditional-compilation-struct.rs => conditional-compilation-struct-11085.rs} (88%) rename tests/ui/{array-slice-vec/trait-object-arrays.rs => coercion/trait-object-arrays-11205.rs} (95%) rename tests/ui/{traits/negative-positive-impl-conflict.rs => diagnostics-infra/primary-fluent-bundle-missing.rs} (89%) rename tests/ui/{issues/issue-106755.stderr => diagnostics-infra/primary-fluent-bundle-missing.stderr} (84%) rename tests/ui/drop/{conditional-drop-behavior.rs => conditional-drop-10734.rs} (93%) rename tests/ui/drop/{trait-object-drop-behavior.rs => trait-object-drop-10802.rs} (93%) rename tests/ui/extern/{extern-rust-fn-type-error.rs => extern-rust-fn-type-error-10764.rs} (59%) rename tests/ui/{issues/issue-10764.stderr => extern/extern-rust-fn-type-error-10764.stderr} (83%) rename tests/ui/extern/{foreign-fn-pattern-error.rs => foreign-fn-pattern-error-10877.rs} (87%) rename tests/ui/{issues/issue-10877.stderr => extern/foreign-fn-pattern-error-10877.stderr} (79%) delete mode 100644 tests/ui/fn/boxed-fn-pointer.rs rename tests/ui/imports/{empty-use-statements.rs => use-declaration-no-path-segment-prefix.rs} (87%) rename tests/ui/{closures => inference}/fnonce-closure-call.rs (57%) rename tests/ui/{generics/generic-type-inference.rs => inference/generic-type-inference-10436.rs} (77%) rename tests/ui/{array-slice-vec/array-pattern-matching.rs => lifetimes/array-pattern-matching-10396.rs} (71%) rename tests/ui/lifetimes/{closure-lifetime-bounds-error.rs => closure-lifetime-bounds-10291.rs} (72%) rename tests/ui/{issues/issue-10291.stderr => lifetimes/closure-lifetime-bounds-10291.stderr} (87%) rename tests/ui/lifetimes/{container-lifetime-error.rs => container-lifetime-error-11374.rs} (89%) rename tests/ui/{issues/issue-11374.stderr => lifetimes/container-lifetime-error-11374.stderr} (86%) rename tests/ui/lifetimes/{enum-lifetime-container.rs => enum-lifetime-container-10228.rs} (80%) rename tests/ui/lifetimes/{keyword-self-lifetime-error.rs => keyword-self-lifetime-error-10412.rs} (91%) rename tests/ui/{issues/issue-10412.stderr => lifetimes/keyword-self-lifetime-error-10412.stderr} (76%) rename tests/ui/lifetimes/{trait-lifetime-bounds.rs => tuple-struct-vs-struct-with-fields-borrowck-10902.rs} (87%) rename tests/ui/lint/{inner-doc-attributes.rs => missing-doc-unsugard-doc-attr-10853.rs} (68%) rename tests/ui/parser/{comment-parsing.rs => doc-comment-parsing.rs} (74%) rename tests/ui/pattern/{ascii-lowercase-match.rs => premature-match-scrutinee-temporary-drop-10683.rs} (68%) rename tests/ui/privacy/{private-struct-access-error.rs => struct-field-and-impl-expose-10545.rs} (59%) rename tests/ui/{issues/issue-10545.stderr => privacy/struct-field-and-impl-expose-10545.stderr} (73%) rename tests/ui/structs/{mutable-unit-struct-borrow.rs => mutable-unit-struct-borrow-11267.rs} (82%) rename tests/ui/traits/{blanket-impl-trait-object.rs => blanket-impl-trait-object-10456.rs} (81%) rename tests/ui/traits/{missing-trait-method-error.rs => nested-mod-trait-method-lookup-leak-10465.rs} (80%) rename tests/ui/{issues/issue-10465.stderr => traits/nested-mod-trait-method-lookup-leak-10465.stderr} (88%) rename tests/ui/type-alias/{mismatched-rc-foo-types.rs => dummy-binder-102964.rs} (75%) rename tests/ui/{issues/issue-102964.stderr => type-alias/dummy-binder-102964.stderr} (93%) rename tests/ui/type-alias/{static-method-type-alias.rs => static-method-type-alias-11047.rs} (87%) rename tests/ui/{issues/issue-11004.stderr => unsafe/raw-pointer-field-access-error.stderr} (85%) diff --git a/tests/ui/README.md b/tests/ui/README.md index b635b6326fce..3630ce9285da 100644 --- a/tests/ui/README.md +++ b/tests/ui/README.md @@ -412,6 +412,10 @@ These tests revolve around command-line flags which change the way error/warning Exercises `#[diagnostic::*]` namespaced attributes. See [RFC 3368 Diagnostic attribute namespace](https://github.com/rust-lang/rfcs/blob/master/text/3368-diagnostic-attribute-namespace.md). +## `tests/ui/diagnostics-infra` + +This directory contains tests and infrastructure related to the diagnostics system, including support for translatable diagnostics + ## `tests/ui/diagnostic-width/`: `--diagnostic-width` Everything to do with `--diagnostic-width`. diff --git a/tests/ui/borrowck/closure-borrow-conflict.rs b/tests/ui/borrowck/closure-borrow-conflict-11192.rs similarity index 85% rename from tests/ui/borrowck/closure-borrow-conflict.rs rename to tests/ui/borrowck/closure-borrow-conflict-11192.rs index 1a3d8c9fe586..dff70d62d6f4 100644 --- a/tests/ui/borrowck/closure-borrow-conflict.rs +++ b/tests/ui/borrowck/closure-borrow-conflict-11192.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/11192 + struct Foo { x: isize } diff --git a/tests/ui/issues/issue-11192.stderr b/tests/ui/borrowck/closure-borrow-conflict-11192.stderr similarity index 92% rename from tests/ui/issues/issue-11192.stderr rename to tests/ui/borrowck/closure-borrow-conflict-11192.stderr index a8a18c49549d..f1df635276b4 100644 --- a/tests/ui/issues/issue-11192.stderr +++ b/tests/ui/borrowck/closure-borrow-conflict-11192.stderr @@ -1,5 +1,5 @@ error[E0502]: cannot borrow `*ptr` as immutable because it is also borrowed as mutable - --> $DIR/issue-11192.rs:20:10 + --> $DIR/closure-borrow-conflict-11192.rs:22:10 | LL | let mut test = |foo: &Foo| { | ----------- mutable borrow occurs here diff --git a/tests/ui/cfg/conditional-compilation-struct.rs b/tests/ui/cfg/conditional-compilation-struct-11085.rs similarity index 88% rename from tests/ui/cfg/conditional-compilation-struct.rs rename to tests/ui/cfg/conditional-compilation-struct-11085.rs index c3f13199b308..cd6dded54d30 100644 --- a/tests/ui/cfg/conditional-compilation-struct.rs +++ b/tests/ui/cfg/conditional-compilation-struct-11085.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/11085 + //@ run-pass #![allow(dead_code)] diff --git a/tests/ui/array-slice-vec/trait-object-arrays.rs b/tests/ui/coercion/trait-object-arrays-11205.rs similarity index 95% rename from tests/ui/array-slice-vec/trait-object-arrays.rs rename to tests/ui/coercion/trait-object-arrays-11205.rs index 8530514f0edf..45d69dce3238 100644 --- a/tests/ui/array-slice-vec/trait-object-arrays.rs +++ b/tests/ui/coercion/trait-object-arrays-11205.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/11205 + //@ run-pass #![allow(dead_code)] diff --git a/tests/ui/traits/negative-positive-impl-conflict.rs b/tests/ui/diagnostics-infra/primary-fluent-bundle-missing.rs similarity index 89% rename from tests/ui/traits/negative-positive-impl-conflict.rs rename to tests/ui/diagnostics-infra/primary-fluent-bundle-missing.rs index d7e7122ebda1..f2965778431c 100644 --- a/tests/ui/traits/negative-positive-impl-conflict.rs +++ b/tests/ui/diagnostics-infra/primary-fluent-bundle-missing.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/106755 + //@ compile-flags:-Ztranslate-lang=en_US #![feature(negative_impls)] diff --git a/tests/ui/issues/issue-106755.stderr b/tests/ui/diagnostics-infra/primary-fluent-bundle-missing.stderr similarity index 84% rename from tests/ui/issues/issue-106755.stderr rename to tests/ui/diagnostics-infra/primary-fluent-bundle-missing.stderr index da6b8c5c5632..1dc31e161a76 100644 --- a/tests/ui/issues/issue-106755.stderr +++ b/tests/ui/diagnostics-infra/primary-fluent-bundle-missing.stderr @@ -1,5 +1,5 @@ error[E0751]: found both positive and negative implementation of trait `Send` for type `TestType<_>`: - --> $DIR/issue-106755.rs:13:1 + --> $DIR/primary-fluent-bundle-missing.rs:15:1 | LL | unsafe impl Send for TestType {} | ------------------------------------------------------ positive implementation here @@ -8,7 +8,7 @@ LL | impl !Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>` - --> $DIR/issue-106755.rs:17:1 + --> $DIR/primary-fluent-bundle-missing.rs:19:1 | LL | unsafe impl Send for TestType {} | ------------------------------------------------------ first implementation here @@ -17,26 +17,26 @@ LL | unsafe impl Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>` error[E0367]: `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not - --> $DIR/issue-106755.rs:13:9 + --> $DIR/primary-fluent-bundle-missing.rs:15:9 | LL | impl !Send for TestType {} | ^^^^^^^ | note: the implementor must specify the same requirement - --> $DIR/issue-106755.rs:9:1 + --> $DIR/primary-fluent-bundle-missing.rs:11:1 | LL | struct TestType(::std::marker::PhantomData); | ^^^^^^^^^^^^^^^^^^ error[E0366]: `!Send` impls cannot be specialized - --> $DIR/issue-106755.rs:19:1 + --> $DIR/primary-fluent-bundle-missing.rs:21:1 | LL | impl !Send for TestType {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: `i32` is not a generic parameter note: use the same sequence of generic lifetime, type and const parameters as the struct definition - --> $DIR/issue-106755.rs:9:1 + --> $DIR/primary-fluent-bundle-missing.rs:11:1 | LL | struct TestType(::std::marker::PhantomData); | ^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/drop/conditional-drop-behavior.rs b/tests/ui/drop/conditional-drop-10734.rs similarity index 93% rename from tests/ui/drop/conditional-drop-behavior.rs rename to tests/ui/drop/conditional-drop-10734.rs index 6d815aeca076..25f492bf9e08 100644 --- a/tests/ui/drop/conditional-drop-behavior.rs +++ b/tests/ui/drop/conditional-drop-10734.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10734 + //@ run-pass #![allow(non_upper_case_globals)] diff --git a/tests/ui/drop/trait-object-drop-behavior.rs b/tests/ui/drop/trait-object-drop-10802.rs similarity index 93% rename from tests/ui/drop/trait-object-drop-behavior.rs rename to tests/ui/drop/trait-object-drop-10802.rs index eca701ce98c9..a8a955ad8334 100644 --- a/tests/ui/drop/trait-object-drop-behavior.rs +++ b/tests/ui/drop/trait-object-drop-10802.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10802 + //@ run-pass #![allow(dead_code)] diff --git a/tests/ui/extern/extern-rust-fn-type-error.rs b/tests/ui/extern/extern-rust-fn-type-error-10764.rs similarity index 59% rename from tests/ui/extern/extern-rust-fn-type-error.rs rename to tests/ui/extern/extern-rust-fn-type-error-10764.rs index bb915f58d9d2..f172f6e6b7d9 100644 --- a/tests/ui/extern/extern-rust-fn-type-error.rs +++ b/tests/ui/extern/extern-rust-fn-type-error-10764.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10764 + fn f(_: extern "Rust" fn()) {} extern "C" fn bar() {} diff --git a/tests/ui/issues/issue-10764.stderr b/tests/ui/extern/extern-rust-fn-type-error-10764.stderr similarity index 83% rename from tests/ui/issues/issue-10764.stderr rename to tests/ui/extern/extern-rust-fn-type-error-10764.stderr index f3bd0100a72a..fa72d7dd6b2f 100644 --- a/tests/ui/issues/issue-10764.stderr +++ b/tests/ui/extern/extern-rust-fn-type-error-10764.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-10764.rs:4:15 + --> $DIR/extern-rust-fn-type-error-10764.rs:6:15 | LL | fn main() { f(bar) } | - ^^^ expected "Rust" fn, found "C" fn @@ -9,7 +9,7 @@ LL | fn main() { f(bar) } = note: expected fn pointer `fn()` found fn item `extern "C" fn() {bar}` note: function defined here - --> $DIR/issue-10764.rs:1:4 + --> $DIR/extern-rust-fn-type-error-10764.rs:3:4 | LL | fn f(_: extern "Rust" fn()) {} | ^ --------------------- diff --git a/tests/ui/extern/foreign-fn-pattern-error.rs b/tests/ui/extern/foreign-fn-pattern-error-10877.rs similarity index 87% rename from tests/ui/extern/foreign-fn-pattern-error.rs rename to tests/ui/extern/foreign-fn-pattern-error-10877.rs index 15a383175b97..9a047d4f34e7 100644 --- a/tests/ui/extern/foreign-fn-pattern-error.rs +++ b/tests/ui/extern/foreign-fn-pattern-error-10877.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10877 + struct Foo { x: isize, } diff --git a/tests/ui/issues/issue-10877.stderr b/tests/ui/extern/foreign-fn-pattern-error-10877.stderr similarity index 79% rename from tests/ui/issues/issue-10877.stderr rename to tests/ui/extern/foreign-fn-pattern-error-10877.stderr index bd3797cba558..cab7b6ab06be 100644 --- a/tests/ui/issues/issue-10877.stderr +++ b/tests/ui/extern/foreign-fn-pattern-error-10877.stderr @@ -1,23 +1,23 @@ error[E0130]: patterns aren't allowed in foreign function declarations - --> $DIR/issue-10877.rs:5:12 + --> $DIR/foreign-fn-pattern-error-10877.rs:7:12 | LL | fn foo(1: ()); | ^ pattern not allowed in foreign function error[E0130]: patterns aren't allowed in foreign function declarations - --> $DIR/issue-10877.rs:7:12 + --> $DIR/foreign-fn-pattern-error-10877.rs:9:12 | LL | fn bar((): isize); | ^^ pattern not allowed in foreign function error[E0130]: patterns aren't allowed in foreign function declarations - --> $DIR/issue-10877.rs:9:12 + --> $DIR/foreign-fn-pattern-error-10877.rs:11:12 | LL | fn baz(Foo { x }: isize); | ^^^^^^^^^ pattern not allowed in foreign function error[E0130]: patterns aren't allowed in foreign function declarations - --> $DIR/issue-10877.rs:11:12 + --> $DIR/foreign-fn-pattern-error-10877.rs:13:12 | LL | fn qux((x, y): ()); | ^^^^^^ pattern not allowed in foreign function diff --git a/tests/ui/fn/boxed-fn-pointer.rs b/tests/ui/fn/boxed-fn-pointer.rs deleted file mode 100644 index 2060d15b4c78..000000000000 --- a/tests/ui/fn/boxed-fn-pointer.rs +++ /dev/null @@ -1,7 +0,0 @@ -//@ run-pass - -pub fn main() { - fn f() { - } - let _: Box = Box::new(f as fn()); -} diff --git a/tests/ui/imports/empty-use-statements.rs b/tests/ui/imports/use-declaration-no-path-segment-prefix.rs similarity index 87% rename from tests/ui/imports/empty-use-statements.rs rename to tests/ui/imports/use-declaration-no-path-segment-prefix.rs index 31315dc7c93a..f7fbc084ebfe 100644 --- a/tests/ui/imports/empty-use-statements.rs +++ b/tests/ui/imports/use-declaration-no-path-segment-prefix.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10806 + //@ edition: 2015 //@ run-pass #![allow(unused_imports)] diff --git a/tests/ui/closures/fnonce-closure-call.rs b/tests/ui/inference/fnonce-closure-call.rs similarity index 57% rename from tests/ui/closures/fnonce-closure-call.rs rename to tests/ui/inference/fnonce-closure-call.rs index 68ac0bbe49fb..262a193609fc 100644 --- a/tests/ui/closures/fnonce-closure-call.rs +++ b/tests/ui/inference/fnonce-closure-call.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10718 + //@ run-pass fn f(p: F) { diff --git a/tests/ui/generics/generic-type-inference.rs b/tests/ui/inference/generic-type-inference-10436.rs similarity index 77% rename from tests/ui/generics/generic-type-inference.rs rename to tests/ui/inference/generic-type-inference-10436.rs index 672aa2464dc1..456a9b86c347 100644 --- a/tests/ui/generics/generic-type-inference.rs +++ b/tests/ui/inference/generic-type-inference-10436.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10436 + //@ run-pass fn works(x: T) -> Vec { vec![x] } diff --git a/tests/ui/array-slice-vec/array-pattern-matching.rs b/tests/ui/lifetimes/array-pattern-matching-10396.rs similarity index 71% rename from tests/ui/array-slice-vec/array-pattern-matching.rs rename to tests/ui/lifetimes/array-pattern-matching-10396.rs index 082216d557cf..5fc141bc4601 100644 --- a/tests/ui/array-slice-vec/array-pattern-matching.rs +++ b/tests/ui/lifetimes/array-pattern-matching-10396.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10396 + //@ check-pass #![allow(dead_code)] #[derive(Debug)] diff --git a/tests/ui/lifetimes/closure-lifetime-bounds-error.rs b/tests/ui/lifetimes/closure-lifetime-bounds-10291.rs similarity index 72% rename from tests/ui/lifetimes/closure-lifetime-bounds-error.rs rename to tests/ui/lifetimes/closure-lifetime-bounds-10291.rs index 31b9e1240461..42dc6c2cafad 100644 --- a/tests/ui/lifetimes/closure-lifetime-bounds-error.rs +++ b/tests/ui/lifetimes/closure-lifetime-bounds-10291.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10291 + fn test<'x>(x: &'x isize) { drop:: FnMut(&'z isize) -> &'z isize>>(Box::new(|z| { x diff --git a/tests/ui/issues/issue-10291.stderr b/tests/ui/lifetimes/closure-lifetime-bounds-10291.stderr similarity index 87% rename from tests/ui/issues/issue-10291.stderr rename to tests/ui/lifetimes/closure-lifetime-bounds-10291.stderr index 68ed9a0de5d5..34f8ca40871f 100644 --- a/tests/ui/issues/issue-10291.stderr +++ b/tests/ui/lifetimes/closure-lifetime-bounds-10291.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/issue-10291.rs:3:9 + --> $DIR/closure-lifetime-bounds-10291.rs:5:9 | LL | fn test<'x>(x: &'x isize) { | -- lifetime `'x` defined here diff --git a/tests/ui/lifetimes/container-lifetime-error.rs b/tests/ui/lifetimes/container-lifetime-error-11374.rs similarity index 89% rename from tests/ui/lifetimes/container-lifetime-error.rs rename to tests/ui/lifetimes/container-lifetime-error-11374.rs index 60ee256c65a9..59d13d04e466 100644 --- a/tests/ui/lifetimes/container-lifetime-error.rs +++ b/tests/ui/lifetimes/container-lifetime-error-11374.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/11374 + use std::io::{self, Read}; use std::vec; diff --git a/tests/ui/issues/issue-11374.stderr b/tests/ui/lifetimes/container-lifetime-error-11374.stderr similarity index 86% rename from tests/ui/issues/issue-11374.stderr rename to tests/ui/lifetimes/container-lifetime-error-11374.stderr index 3ae5cfc79f87..a29b5ae137c2 100644 --- a/tests/ui/issues/issue-11374.stderr +++ b/tests/ui/lifetimes/container-lifetime-error-11374.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-11374.rs:27:15 + --> $DIR/container-lifetime-error-11374.rs:29:15 | LL | c.read_to(v); | ------- ^ expected `&mut [u8]`, found `Vec<_>` @@ -9,7 +9,7 @@ LL | c.read_to(v); = note: expected mutable reference `&mut [u8]` found struct `Vec<_>` note: method defined here - --> $DIR/issue-11374.rs:13:12 + --> $DIR/container-lifetime-error-11374.rs:15:12 | LL | pub fn read_to(&mut self, vec: &mut [u8]) { | ^^^^^^^ -------------- @@ -19,7 +19,7 @@ LL | c.read_to(&mut v); | ++++ error[E0515]: cannot return value referencing local variable `r` - --> $DIR/issue-11374.rs:20:5 + --> $DIR/container-lifetime-error-11374.rs:22:5 | LL | Container::wrap(&mut r as &mut dyn io::Read) | ^^^^^^^^^^^^^^^^------^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/ui/lifetimes/enum-lifetime-container.rs b/tests/ui/lifetimes/enum-lifetime-container-10228.rs similarity index 80% rename from tests/ui/lifetimes/enum-lifetime-container.rs rename to tests/ui/lifetimes/enum-lifetime-container-10228.rs index a59ccf926f9c..ebbefb619c61 100644 --- a/tests/ui/lifetimes/enum-lifetime-container.rs +++ b/tests/ui/lifetimes/enum-lifetime-container-10228.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10228 + //@ run-pass #![allow(dead_code)] #![allow(unused_variables)] diff --git a/tests/ui/lifetimes/keyword-self-lifetime-error.rs b/tests/ui/lifetimes/keyword-self-lifetime-error-10412.rs similarity index 91% rename from tests/ui/lifetimes/keyword-self-lifetime-error.rs rename to tests/ui/lifetimes/keyword-self-lifetime-error-10412.rs index 68ce0c2ea3cb..a5b303df2fd4 100644 --- a/tests/ui/lifetimes/keyword-self-lifetime-error.rs +++ b/tests/ui/lifetimes/keyword-self-lifetime-error-10412.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10412 + trait Serializable<'self, T> { //~^ ERROR lifetimes cannot use keyword names fn serialize(val: &'self T) -> Vec; //~ ERROR lifetimes cannot use keyword names diff --git a/tests/ui/issues/issue-10412.stderr b/tests/ui/lifetimes/keyword-self-lifetime-error-10412.stderr similarity index 76% rename from tests/ui/issues/issue-10412.stderr rename to tests/ui/lifetimes/keyword-self-lifetime-error-10412.stderr index c74ba1306cc4..236bdf1ac854 100644 --- a/tests/ui/issues/issue-10412.stderr +++ b/tests/ui/lifetimes/keyword-self-lifetime-error-10412.stderr @@ -1,47 +1,47 @@ error: lifetimes cannot use keyword names - --> $DIR/issue-10412.rs:1:20 + --> $DIR/keyword-self-lifetime-error-10412.rs:3:20 | LL | trait Serializable<'self, T> { | ^^^^^ error: lifetimes cannot use keyword names - --> $DIR/issue-10412.rs:3:24 + --> $DIR/keyword-self-lifetime-error-10412.rs:5:24 | LL | fn serialize(val: &'self T) -> Vec; | ^^^^^ error: lifetimes cannot use keyword names - --> $DIR/issue-10412.rs:4:37 + --> $DIR/keyword-self-lifetime-error-10412.rs:6:37 | LL | fn deserialize(repr: &[u8]) -> &'self T; | ^^^^^ error: lifetimes cannot use keyword names - --> $DIR/issue-10412.rs:7:6 + --> $DIR/keyword-self-lifetime-error-10412.rs:9:6 | LL | impl<'self> Serializable for &'self str { | ^^^^^ error: lifetimes cannot use keyword names - --> $DIR/issue-10412.rs:7:36 + --> $DIR/keyword-self-lifetime-error-10412.rs:9:36 | LL | impl<'self> Serializable for &'self str { | ^^^^^ error: lifetimes cannot use keyword names - --> $DIR/issue-10412.rs:11:24 + --> $DIR/keyword-self-lifetime-error-10412.rs:13:24 | LL | fn serialize(val: &'self str) -> Vec { | ^^^^^ error: lifetimes cannot use keyword names - --> $DIR/issue-10412.rs:15:37 + --> $DIR/keyword-self-lifetime-error-10412.rs:17:37 | LL | fn deserialize(repr: &[u8]) -> &'self str { | ^^^^^ error[E0726]: implicit elided lifetime not allowed here - --> $DIR/issue-10412.rs:7:13 + --> $DIR/keyword-self-lifetime-error-10412.rs:9:13 | LL | impl<'self> Serializable for &'self str { | ^^^^^^^^^^^^^^^^^ expected lifetime parameter diff --git a/tests/ui/lifetimes/trait-lifetime-bounds.rs b/tests/ui/lifetimes/tuple-struct-vs-struct-with-fields-borrowck-10902.rs similarity index 87% rename from tests/ui/lifetimes/trait-lifetime-bounds.rs rename to tests/ui/lifetimes/tuple-struct-vs-struct-with-fields-borrowck-10902.rs index 7cdf8808aa02..97c0d0bf554e 100644 --- a/tests/ui/lifetimes/trait-lifetime-bounds.rs +++ b/tests/ui/lifetimes/tuple-struct-vs-struct-with-fields-borrowck-10902.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10902 + //@ check-pass #![allow(dead_code)] diff --git a/tests/ui/lint/inner-doc-attributes.rs b/tests/ui/lint/missing-doc-unsugard-doc-attr-10853.rs similarity index 68% rename from tests/ui/lint/inner-doc-attributes.rs rename to tests/ui/lint/missing-doc-unsugard-doc-attr-10853.rs index 4c22393d9c0a..ec13ae997878 100644 --- a/tests/ui/lint/inner-doc-attributes.rs +++ b/tests/ui/lint/missing-doc-unsugard-doc-attr-10853.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10853 + //@ check-pass #![deny(missing_docs)] diff --git a/tests/ui/parser/comment-parsing.rs b/tests/ui/parser/doc-comment-parsing.rs similarity index 74% rename from tests/ui/parser/comment-parsing.rs rename to tests/ui/parser/doc-comment-parsing.rs index c6c6939bda53..00f6b0e09a89 100644 --- a/tests/ui/parser/comment-parsing.rs +++ b/tests/ui/parser/doc-comment-parsing.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10638 + //@ run-pass pub fn main() { diff --git a/tests/ui/pattern/ascii-lowercase-match.rs b/tests/ui/pattern/premature-match-scrutinee-temporary-drop-10683.rs similarity index 68% rename from tests/ui/pattern/ascii-lowercase-match.rs rename to tests/ui/pattern/premature-match-scrutinee-temporary-drop-10683.rs index 5657ec1864b2..a4dfa56117c2 100644 --- a/tests/ui/pattern/ascii-lowercase-match.rs +++ b/tests/ui/pattern/premature-match-scrutinee-temporary-drop-10683.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10683 + //@ run-pass static NAME: &'static str = "hello world"; diff --git a/tests/ui/privacy/private-struct-access-error.rs b/tests/ui/privacy/struct-field-and-impl-expose-10545.rs similarity index 59% rename from tests/ui/privacy/private-struct-access-error.rs rename to tests/ui/privacy/struct-field-and-impl-expose-10545.rs index acd071496190..8a8c8240c2d0 100644 --- a/tests/ui/privacy/private-struct-access-error.rs +++ b/tests/ui/privacy/struct-field-and-impl-expose-10545.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10545 + mod a { struct S; impl S { } diff --git a/tests/ui/issues/issue-10545.stderr b/tests/ui/privacy/struct-field-and-impl-expose-10545.stderr similarity index 73% rename from tests/ui/issues/issue-10545.stderr rename to tests/ui/privacy/struct-field-and-impl-expose-10545.stderr index 9aa042171748..ddf87d1d23ad 100644 --- a/tests/ui/issues/issue-10545.stderr +++ b/tests/ui/privacy/struct-field-and-impl-expose-10545.stderr @@ -1,11 +1,11 @@ error[E0603]: struct `S` is private - --> $DIR/issue-10545.rs:6:14 + --> $DIR/struct-field-and-impl-expose-10545.rs:8:14 | LL | fn foo(_: a::S) { | ^ private struct | note: the struct `S` is defined here - --> $DIR/issue-10545.rs:2:5 + --> $DIR/struct-field-and-impl-expose-10545.rs:4:5 | LL | struct S; | ^^^^^^^^^ diff --git a/tests/ui/structs/mutable-unit-struct-borrow.rs b/tests/ui/structs/mutable-unit-struct-borrow-11267.rs similarity index 82% rename from tests/ui/structs/mutable-unit-struct-borrow.rs rename to tests/ui/structs/mutable-unit-struct-borrow-11267.rs index 036ad1d54edc..d96c4a4e79bc 100644 --- a/tests/ui/structs/mutable-unit-struct-borrow.rs +++ b/tests/ui/structs/mutable-unit-struct-borrow-11267.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/11267 + //@ run-pass // Tests that unary structs can be mutably borrowed. diff --git a/tests/ui/traits/blanket-impl-trait-object.rs b/tests/ui/traits/blanket-impl-trait-object-10456.rs similarity index 81% rename from tests/ui/traits/blanket-impl-trait-object.rs rename to tests/ui/traits/blanket-impl-trait-object-10456.rs index 51c740fd7293..f84214317746 100644 --- a/tests/ui/traits/blanket-impl-trait-object.rs +++ b/tests/ui/traits/blanket-impl-trait-object-10456.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10456 + //@ check-pass pub struct Foo; diff --git a/tests/ui/traits/missing-trait-method-error.rs b/tests/ui/traits/nested-mod-trait-method-lookup-leak-10465.rs similarity index 80% rename from tests/ui/traits/missing-trait-method-error.rs rename to tests/ui/traits/nested-mod-trait-method-lookup-leak-10465.rs index d899c3ffa912..d5a500900ff0 100644 --- a/tests/ui/traits/missing-trait-method-error.rs +++ b/tests/ui/traits/nested-mod-trait-method-lookup-leak-10465.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/10465 + pub mod a { pub trait A { fn foo(&self); diff --git a/tests/ui/issues/issue-10465.stderr b/tests/ui/traits/nested-mod-trait-method-lookup-leak-10465.stderr similarity index 88% rename from tests/ui/issues/issue-10465.stderr rename to tests/ui/traits/nested-mod-trait-method-lookup-leak-10465.stderr index 0f46ebe505aa..ffd8fd39250d 100644 --- a/tests/ui/issues/issue-10465.stderr +++ b/tests/ui/traits/nested-mod-trait-method-lookup-leak-10465.stderr @@ -1,5 +1,5 @@ error[E0599]: no method named `foo` found for reference `&B` in the current scope - --> $DIR/issue-10465.rs:17:15 + --> $DIR/nested-mod-trait-method-lookup-leak-10465.rs:19:15 | LL | b.foo(); | ^^^ method not found in `&B` diff --git a/tests/ui/type-alias/mismatched-rc-foo-types.rs b/tests/ui/type-alias/dummy-binder-102964.rs similarity index 75% rename from tests/ui/type-alias/mismatched-rc-foo-types.rs rename to tests/ui/type-alias/dummy-binder-102964.rs index 43ff23600766..6b6fa3ed5e33 100644 --- a/tests/ui/type-alias/mismatched-rc-foo-types.rs +++ b/tests/ui/type-alias/dummy-binder-102964.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/102964 + use std::rc::Rc; type Foo<'a, T> = &'a dyn Fn(&T); type RcFoo<'a, T> = Rc>; diff --git a/tests/ui/issues/issue-102964.stderr b/tests/ui/type-alias/dummy-binder-102964.stderr similarity index 93% rename from tests/ui/issues/issue-102964.stderr rename to tests/ui/type-alias/dummy-binder-102964.stderr index 0e2761f3f57b..fc32cabaf71a 100644 --- a/tests/ui/issues/issue-102964.stderr +++ b/tests/ui/type-alias/dummy-binder-102964.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/issue-102964.rs:5:41 + --> $DIR/dummy-binder-102964.rs:7:41 | LL | fn bar_function(function: Foo) -> RcFoo { | ------------ ^^^^^^^^ expected `Rc<&dyn Fn(&T)>`, found `()` diff --git a/tests/ui/type-alias/static-method-type-alias.rs b/tests/ui/type-alias/static-method-type-alias-11047.rs similarity index 87% rename from tests/ui/type-alias/static-method-type-alias.rs rename to tests/ui/type-alias/static-method-type-alias-11047.rs index 6e1b2856afcd..efb336fb4f76 100644 --- a/tests/ui/type-alias/static-method-type-alias.rs +++ b/tests/ui/type-alias/static-method-type-alias-11047.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/11047 + //@ run-pass // Test that static methods can be invoked on `type` aliases diff --git a/tests/ui/unsafe/raw-pointer-field-access-error.rs b/tests/ui/unsafe/raw-pointer-field-access-error.rs index 0c34554c12d1..04b45b2d3c68 100644 --- a/tests/ui/unsafe/raw-pointer-field-access-error.rs +++ b/tests/ui/unsafe/raw-pointer-field-access-error.rs @@ -1,3 +1,5 @@ +//! Regression test for https://github.com/rust-lang/rust/issues/11004 + use std::mem; struct A { x: i32, y: f64 } diff --git a/tests/ui/issues/issue-11004.stderr b/tests/ui/unsafe/raw-pointer-field-access-error.stderr similarity index 85% rename from tests/ui/issues/issue-11004.stderr rename to tests/ui/unsafe/raw-pointer-field-access-error.stderr index 6d157c911302..e9a205a5fa64 100644 --- a/tests/ui/issues/issue-11004.stderr +++ b/tests/ui/unsafe/raw-pointer-field-access-error.stderr @@ -1,5 +1,5 @@ error[E0609]: no field `x` on type `*mut A` - --> $DIR/issue-11004.rs:7:21 + --> $DIR/raw-pointer-field-access-error.rs:9:21 | LL | let x : i32 = n.x; | ^ unknown field @@ -10,7 +10,7 @@ LL | let x : i32 = (*n).x; | ++ + error[E0609]: no field `y` on type `*mut A` - --> $DIR/issue-11004.rs:8:21 + --> $DIR/raw-pointer-field-access-error.rs:10:21 | LL | let y : f64 = n.y; | ^ unknown field From 7f7d343400de843c12f880b02ea1a7b22ccc7379 Mon Sep 17 00:00:00 2001 From: okaneco <47607823+okaneco@users.noreply.github.com> Date: Fri, 25 Jul 2025 18:35:53 -0400 Subject: [PATCH 11/14] str: Mark unstable `round_char_boundary` feature functions as const Mark `floor_char_boundary`, `ceil_char_boundary` const Simplify the implementations, reducing the number of arithmetic operations --- library/core/src/str/mod.rs | 38 ++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 029abf175391..c40af4de7e03 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -407,17 +407,22 @@ pub const fn is_char_boundary(&self, index: usize) -> bool { /// ``` #[unstable(feature = "round_char_boundary", issue = "93743")] #[inline] - pub fn floor_char_boundary(&self, index: usize) -> usize { + pub const fn floor_char_boundary(&self, index: usize) -> usize { if index >= self.len() { self.len() } else { - let lower_bound = index.saturating_sub(3); - let new_index = self.as_bytes()[lower_bound..=index] - .iter() - .rposition(|b| b.is_utf8_char_boundary()); + let mut i = index; + while i > 0 { + if self.as_bytes()[i].is_utf8_char_boundary() { + break; + } + i -= 1; + } - // SAFETY: we know that the character boundary will be within four bytes - unsafe { lower_bound + new_index.unwrap_unchecked() } + // The character boundary will be within four bytes of the index + debug_assert!(i >= index.saturating_sub(3)); + + i } } @@ -445,15 +450,22 @@ pub fn floor_char_boundary(&self, index: usize) -> usize { /// ``` #[unstable(feature = "round_char_boundary", issue = "93743")] #[inline] - pub fn ceil_char_boundary(&self, index: usize) -> usize { + pub const fn ceil_char_boundary(&self, index: usize) -> usize { if index >= self.len() { self.len() } else { - let upper_bound = Ord::min(index + 4, self.len()); - self.as_bytes()[index..upper_bound] - .iter() - .position(|b| b.is_utf8_char_boundary()) - .map_or(upper_bound, |pos| pos + index) + let mut i = index; + while i < self.len() { + if self.as_bytes()[i].is_utf8_char_boundary() { + break; + } + i += 1; + } + + // The character boundary will be within four bytes of the index + debug_assert!(i <= index + 3); + + i } } From 948f7798d70b6adb6a490b8867e155dadebd3f0e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 6 Jul 2025 18:03:07 +0000 Subject: [PATCH 12/14] Remove support for -Zcombine-cgu Nobody seems to actually use this, while still adding some extra complexity to the already rather complex codegen coordinator code. It is also not supported by any backend other than the LLVM backend. --- compiler/rustc_codegen_gcc/src/back/write.rs | 9 ---- compiler/rustc_codegen_gcc/src/lib.rs | 8 ---- compiler/rustc_codegen_llvm/src/back/write.rs | 23 ---------- compiler/rustc_codegen_llvm/src/lib.rs | 7 ---- compiler/rustc_codegen_ssa/src/back/write.rs | 42 +++---------------- .../rustc_codegen_ssa/src/traits/write.rs | 6 --- compiler/rustc_session/src/options.rs | 2 - 7 files changed, 6 insertions(+), 91 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/back/write.rs b/compiler/rustc_codegen_gcc/src/back/write.rs index 113abe70805b..c1231142c658 100644 --- a/compiler/rustc_codegen_gcc/src/back/write.rs +++ b/compiler/rustc_codegen_gcc/src/back/write.rs @@ -4,7 +4,6 @@ use rustc_codegen_ssa::back::link::ensure_removed; use rustc_codegen_ssa::back::write::{BitcodeSection, CodegenContext, EmitObj, ModuleConfig}; use rustc_codegen_ssa::{CompiledModule, ModuleCodegen}; -use rustc_errors::DiagCtxtHandle; use rustc_fs_util::link_or_copy; use rustc_session::config::OutputType; use rustc_span::fatal_error::FatalError; @@ -258,14 +257,6 @@ pub(crate) fn codegen( )) } -pub(crate) fn link( - _cgcx: &CodegenContext, - _dcx: DiagCtxtHandle<'_>, - mut _modules: Vec>, -) -> Result, FatalError> { - unimplemented!(); -} - pub(crate) fn save_temp_bitcode( cgcx: &CodegenContext, _module: &ModuleCodegen, diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs index 71765c511381..a31206825007 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -426,14 +426,6 @@ fn prepare_thin( fn serialize_module(_module: ModuleCodegen) -> (String, Self::ModuleBuffer) { unimplemented!(); } - - fn run_link( - cgcx: &CodegenContext, - dcx: DiagCtxtHandle<'_>, - modules: Vec>, - ) -> Result, FatalError> { - back::write::link(cgcx, dcx, modules) - } } /// This is the entrypoint for a hot plugged rustc_codegen_gccjit diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 6f8fba2a30dc..85a06f457ebe 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -796,29 +796,6 @@ pub(crate) fn optimize( Ok(()) } -pub(crate) fn link( - cgcx: &CodegenContext, - dcx: DiagCtxtHandle<'_>, - mut modules: Vec>, -) -> Result, FatalError> { - use super::lto::{Linker, ModuleBuffer}; - // Sort the modules by name to ensure deterministic behavior. - modules.sort_by(|a, b| a.name.cmp(&b.name)); - let (first, elements) = - modules.split_first().expect("Bug! modules must contain at least one module."); - - let mut linker = Linker::new(first.module_llvm.llmod()); - for module in elements { - let _timer = cgcx.prof.generic_activity_with_arg("LLVM_link_module", &*module.name); - let buffer = ModuleBuffer::new(module.module_llvm.llmod()); - linker - .add(buffer.data()) - .map_err(|()| llvm_err(dcx, LlvmError::SerializeModule { name: &module.name }))?; - } - drop(linker); - Ok(modules.remove(0)) -} - pub(crate) fn codegen( cgcx: &CodegenContext, module: ModuleCodegen, diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs index 8b1913cfa756..ca84b6de8b11 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -168,13 +168,6 @@ fn print_statistics(&self) { let stats = llvm::build_string(|s| unsafe { llvm::LLVMRustPrintStatistics(s) }).unwrap(); print!("{stats}"); } - fn run_link( - cgcx: &CodegenContext, - dcx: DiagCtxtHandle<'_>, - modules: Vec>, - ) -> Result, FatalError> { - back::write::link(cgcx, dcx, modules) - } fn run_and_optimize_fat_lto( cgcx: &CodegenContext, exported_symbols_for_lto: &[String], diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index a41cbd306d0c..6773d3e24e94 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -797,10 +797,6 @@ pub(crate) enum WorkItemResult { /// The backend has finished compiling a CGU, nothing more required. Finished(CompiledModule), - /// The backend has finished compiling a CGU, which now needs linking - /// because `-Zcombine-cgu` was specified. - NeedsLink(ModuleCodegen), - /// The backend has finished compiling a CGU, which now needs to go through /// fat LTO. NeedsFatLto(FatLtoInput), @@ -884,7 +880,10 @@ fn execute_optimize_work_item( }; match lto_type { - ComputedLtoType::No => finish_intra_module_work(cgcx, module, module_config), + ComputedLtoType::No => { + let module = B::codegen(cgcx, module, module_config)?; + Ok(WorkItemResult::Finished(module)) + } ComputedLtoType::Thin => { let (name, thin_buffer) = B::prepare_thin(module, false); if let Some(path) = bitcode { @@ -1024,20 +1023,8 @@ fn execute_thin_lto_work_item( module_config: &ModuleConfig, ) -> Result, FatalError> { let module = B::optimize_thin(cgcx, module)?; - finish_intra_module_work(cgcx, module, module_config) -} - -fn finish_intra_module_work( - cgcx: &CodegenContext, - module: ModuleCodegen, - module_config: &ModuleConfig, -) -> Result, FatalError> { - if !cgcx.opts.unstable_opts.combine_cgu || module.kind == ModuleKind::Allocator { - let module = B::codegen(cgcx, module, module_config)?; - Ok(WorkItemResult::Finished(module)) - } else { - Ok(WorkItemResult::NeedsLink(module)) - } + let module = B::codegen(cgcx, module, module_config)?; + Ok(WorkItemResult::Finished(module)) } /// Messages sent to the coordinator. @@ -1343,7 +1330,6 @@ fn start_executing_work( // through codegen and LLVM. let mut compiled_modules = vec![]; let mut compiled_allocator_module = None; - let mut needs_link = Vec::new(); let mut needs_fat_lto = Vec::new(); let mut needs_thin_lto = Vec::new(); let mut lto_import_only_modules = Vec::new(); @@ -1625,7 +1611,6 @@ enum CodegenState { Ok(WorkItemResult::Finished(compiled_module)) => { match compiled_module.kind { ModuleKind::Regular => { - assert!(needs_link.is_empty()); compiled_modules.push(compiled_module); } ModuleKind::Allocator => { @@ -1634,10 +1619,6 @@ enum CodegenState { } } } - Ok(WorkItemResult::NeedsLink(module)) => { - assert!(compiled_modules.is_empty()); - needs_link.push(module); - } Ok(WorkItemResult::NeedsFatLto(fat_lto_input)) => { assert!(!started_lto); assert!(needs_thin_lto.is_empty()); @@ -1674,17 +1655,6 @@ enum CodegenState { return Err(()); } - let needs_link = mem::take(&mut needs_link); - if !needs_link.is_empty() { - assert!(compiled_modules.is_empty()); - let dcx = cgcx.create_dcx(); - let dcx = dcx.handle(); - let module = B::run_link(&cgcx, dcx, needs_link).map_err(|_| ())?; - let module = - B::codegen(&cgcx, module, cgcx.config(ModuleKind::Regular)).map_err(|_| ())?; - compiled_modules.push(module); - } - // Drop to print timings drop(llvm_start_time); diff --git a/compiler/rustc_codegen_ssa/src/traits/write.rs b/compiler/rustc_codegen_ssa/src/traits/write.rs index 8e78cbe1963b..f391c198e1a1 100644 --- a/compiler/rustc_codegen_ssa/src/traits/write.rs +++ b/compiler/rustc_codegen_ssa/src/traits/write.rs @@ -16,12 +16,6 @@ pub trait WriteBackendMethods: Clone + 'static { type ThinData: Send + Sync; type ThinBuffer: ThinBufferMethods; - /// Merge all modules into main_module and returning it - fn run_link( - cgcx: &CodegenContext, - dcx: DiagCtxtHandle<'_>, - modules: Vec>, - ) -> Result, FatalError>; /// Performs fat LTO by merging all modules into a single one, running autodiff /// if necessary and running any further optimizations fn run_and_optimize_fat_lto( diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 5f1973b31a1b..44b35e8921ec 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2168,8 +2168,6 @@ pub(crate) fn parse_align(slot: &mut Option, v: Option<&str>) -> bool { "hash algorithm of source files used to check freshness in cargo (`blake3` or `sha256`)"), codegen_backend: Option = (None, parse_opt_string, [TRACKED], "the backend to use"), - combine_cgu: bool = (false, parse_bool, [TRACKED], - "combine CGUs into a single one"), contract_checks: Option = (None, parse_opt_bool, [TRACKED], "emit runtime checks for contract pre- and post-conditions (default: no)"), coverage_options: CoverageOptions = (CoverageOptions::default(), parse_coverage_options, [TRACKED], From 24e2b4832bfa0bf1b60159af0ae11b15de55590e Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 27 Jul 2025 21:19:07 +1000 Subject: [PATCH 13/14] coverage: Infer `instances_used` from `pgo_func_name_var_map` In obscure circumstances, we would sometimes emit a covfun record for a function with no physical coverage counters, causing `llvm-cov` to fail with the cryptic error message: malformed instrumentation profile data: function name is empty We can eliminate this mismatch by removing `instances_used` entirely, and instead inferring its contents from the keys of `pgo_func_name_var_map`. This makes it impossible for a "used" function to lack a PGO name entry. --- .../src/coverageinfo/mapgen.rs | 12 +++------ .../src/coverageinfo/mod.rs | 27 ++++++++++++------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs index a9be833a6439..8c9dfcfd18c2 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs @@ -46,21 +46,17 @@ pub(crate) fn finalize(cx: &mut CodegenCx<'_, '_>) { debug!("Generating coverage map for CodegenUnit: `{}`", cx.codegen_unit.name()); // FIXME(#132395): Can this be none even when coverage is enabled? - let instances_used = match cx.coverage_cx { - Some(ref cx) => cx.instances_used.borrow(), - None => return, - }; + let Some(ref coverage_cx) = cx.coverage_cx else { return }; - let mut covfun_records = instances_used - .iter() - .copied() + let mut covfun_records = coverage_cx + .instances_used() + .into_iter() // Sort by symbol name, so that the global file table is built in an // order that doesn't depend on the stable-hash-based order in which // instances were visited during codegen. .sorted_by_cached_key(|&instance| tcx.symbol_name(instance).name) .filter_map(|instance| prepare_covfun_record(tcx, instance, true)) .collect::>(); - drop(instances_used); // In a single designated CGU, also prepare covfun records for functions // in this crate that were instrumented for coverage, but are unused. diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index eefbd7cf6c48..35c322326f8e 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -5,7 +5,7 @@ use rustc_codegen_ssa::traits::{ BuilderMethods, ConstCodegenMethods, CoverageInfoBuilderMethods, MiscCodegenMethods, }; -use rustc_data_structures::fx::{FxHashMap, FxIndexSet}; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::ty::Instance; use tracing::{debug, instrument}; @@ -20,9 +20,14 @@ /// Extra per-CGU context/state needed for coverage instrumentation. pub(crate) struct CguCoverageContext<'ll, 'tcx> { - /// Coverage data for each instrumented function identified by DefId. - pub(crate) instances_used: RefCell>>, - pub(crate) pgo_func_name_var_map: RefCell, &'ll llvm::Value>>, + /// Associates function instances with an LLVM global that holds the + /// function's symbol name, as needed by LLVM coverage intrinsics. + /// + /// Instances in this map are also considered "used" for the purposes of + /// emitting covfun records. Every covfun record holds a hash of its + /// symbol name, and `llvm-cov` will exit fatally if it can't resolve that + /// hash back to an entry in the binary's `__llvm_prf_names` linker section. + pub(crate) pgo_func_name_var_map: RefCell, &'ll llvm::Value>>, pub(crate) mcdc_condition_bitmap_map: RefCell, Vec<&'ll llvm::Value>>>, covfun_section_name: OnceCell, @@ -31,7 +36,6 @@ pub(crate) struct CguCoverageContext<'ll, 'tcx> { impl<'ll, 'tcx> CguCoverageContext<'ll, 'tcx> { pub(crate) fn new() -> Self { Self { - instances_used: RefCell::>::default(), pgo_func_name_var_map: Default::default(), mcdc_condition_bitmap_map: Default::default(), covfun_section_name: Default::default(), @@ -53,6 +57,14 @@ fn try_get_mcdc_condition_bitmap( .and_then(|bitmap_map| bitmap_map.get(decision_depth as usize)) .copied() // Dereference Option<&&Value> to Option<&Value> } + + /// Returns the list of instances considered "used" in this CGU, as + /// inferred from the keys of `pgo_func_name_var_map`. + pub(crate) fn instances_used(&self) -> Vec> { + // Collecting into a Vec is way easier than trying to juggle RefCell + // projections, and this should only run once per CGU anyway. + self.pgo_func_name_var_map.borrow().keys().copied().collect::>() + } } impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { @@ -151,11 +163,6 @@ fn add_coverage(&mut self, instance: Instance<'tcx>, kind: &CoverageKind) { return; }; - // Mark the instance as used in this CGU, for coverage purposes. - // This includes functions that were not partitioned into this CGU, - // but were MIR-inlined into one of this CGU's functions. - coverage_cx.instances_used.borrow_mut().insert(instance); - match *kind { CoverageKind::SpanMarker | CoverageKind::BlockMarker { .. } => unreachable!( "marker statement {kind:?} should have been removed by CleanupPostBorrowck" From 89b6b0b6a482cb0d632f54f14936def9c034570d Mon Sep 17 00:00:00 2001 From: Zalathar Date: Sun, 27 Jul 2025 21:29:48 +1000 Subject: [PATCH 14/14] coverage: Clarify that getting a PGO name also makes a function "used" --- compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs index 35c322326f8e..119237abd6b8 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -90,7 +90,10 @@ fn covfun_section_name(&self) -> &CStr { /// string, to hold the function name passed to LLVM intrinsic /// `instrprof.increment()`. The `Value` is only created once per instance. /// Multiple invocations with the same instance return the same `Value`. - fn get_pgo_func_name_var(&self, instance: Instance<'tcx>) -> &'ll llvm::Value { + /// + /// This has the side-effect of causing coverage codegen to consider this + /// function "used", making it eligible to emit an associated covfun record. + fn ensure_pgo_func_name_var(&self, instance: Instance<'tcx>) -> &'ll llvm::Value { debug!("getting pgo_func_name_var for instance={:?}", instance); let mut pgo_func_name_var_map = self.coverage_cx().pgo_func_name_var_map.borrow_mut(); pgo_func_name_var_map.entry(instance).or_insert_with(|| { @@ -114,7 +117,7 @@ fn init_coverage(&mut self, instance: Instance<'tcx>) { return; } - let fn_name = self.get_pgo_func_name_var(instance); + let fn_name = self.ensure_pgo_func_name_var(instance); let hash = self.const_u64(function_coverage_info.function_source_hash); let bitmap_bits = self.const_u32(function_coverage_info.mcdc_bitmap_bits as u32); self.mcdc_parameters(fn_name, hash, bitmap_bits); @@ -170,7 +173,7 @@ fn add_coverage(&mut self, instance: Instance<'tcx>, kind: &CoverageKind) { CoverageKind::VirtualCounter { bcb } if let Some(&id) = ids_info.phys_counter_for_node.get(&bcb) => { - let fn_name = bx.get_pgo_func_name_var(instance); + let fn_name = bx.ensure_pgo_func_name_var(instance); let hash = bx.const_u64(function_coverage_info.function_source_hash); let num_counters = bx.const_u32(ids_info.num_counters); let index = bx.const_u32(id.as_u32()); @@ -200,7 +203,7 @@ fn add_coverage(&mut self, instance: Instance<'tcx>, kind: &CoverageKind) { "bitmap index of the decision out of range" ); - let fn_name = bx.get_pgo_func_name_var(instance); + let fn_name = bx.ensure_pgo_func_name_var(instance); let hash = bx.const_u64(function_coverage_info.function_source_hash); let bitmap_index = bx.const_u32(bitmap_idx); bx.mcdc_tvbitmap_update(fn_name, hash, bitmap_index, cond_bitmap);