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 04c8d1473b048..c010b4d5a0b71 100644 --- a/library/core/src/sync/atomic.rs +++ b/library/core/src/sync/atomic.rs @@ -563,8 +563,8 @@ impl 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 @@ impl AtomicBool { /// 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 @@ impl AtomicBool { /// } /// # } /// ``` + /// + /// [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 @@ impl 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 @@ impl AtomicPtr { /// 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 @@ impl AtomicPtr { /// 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 @@ macro_rules! atomic_int { }] /// * `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 @@ macro_rules! atomic_int { /// 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 @@ macro_rules! atomic_int { /// } /// # } /// ``` + /// + /// [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 41b53d2ad0e95..10769c9c8abfe 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 09b4c7d16dce3..3eb5020968d31 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 13b20f33bd0f7..1a32372d2093f 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -127,9 +127,9 @@ fn main() { 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 df9146b51474c..90da1bc765a9d 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 5a177808d1bd8..a5b51059119c0 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 1ddc112380f16..d68965c634578 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 f70994e1f8868..6079dc85d906b 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 032f5272a9cd4..2952556f699d8 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 705c9e0438119..1c804a0ab391f 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 c2a006d3753a1..17140e15653d2 100644 --- a/library/std_detect/src/detect/macros.rs +++ b/library/std_detect/src/detect/macros.rs @@ -131,14 +131,13 @@ macro_rules! features { }; } - #[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 46b7dd71eb351..dc9a4036d86a1 100644 --- a/library/std_detect/src/detect/os/riscv.rs +++ b/library/std_detect/src/detect/os/riscv.rs @@ -135,4 +135,5 @@ pub(crate) fn imply_features(mut value: cache::Initializer) -> cache::Initialize } #[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 90da1bc765a9d..3d14a46731932 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 7be274df1d41d..a41cbd306d0c2 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 @@ fn start_executing_work( 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 @@ fn start_executing_work( 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 @@ fn start_executing_work( 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 @@ fn start_executing_work( // 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 @@ pub(crate) struct WorkerFatalError; 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 spawn_work<'a, B: ExtraBackendMethods>( } 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 @@ impl SharedEmitterMain { } pub struct Coordinator { - pub sender: Sender>, + sender: Sender>, future: Option>>, // Only used for the Message type. phantom: PhantomData, @@ -2020,7 +2016,7 @@ impl Drop for Coordinator { 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 @@ impl OngoingCodegen { pub(crate) fn codegen_finished(&self, tcx: TyCtxt<'_>) { 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 @@ impl OngoingCodegen { } 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 833456abb8abb..a5807c56e3171 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 3d5f17a60345a..ce9a51b539d83 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 767835c34f02e..cac7d49b74a56 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::sync::Arc; 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 2a889888a39b5..627b0c9ff3b33 100644 --- a/compiler/rustc_codegen_llvm/src/errors.rs +++ b/compiler/rustc_codegen_llvm/src/errors.rs @@ -39,7 +39,7 @@ pub(crate) struct AutoDiffWithoutEnable; #[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 edfb29dd1be72..0d0cb5f139eed 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs @@ -2612,13 +2612,6 @@ unsafe extern "C" { 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 a2e4d7306cbf3..8c34052770e61 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 b635b6326fce7..3630ce9285dad 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 1a3d8c9fe5869..dff70d62d6f49 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 a8a18c49549d5..f1df635276b44 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 c3f13199b308e..cd6dded54d30b 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 8530514f0edf7..45d69dce32389 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 d7e7122ebda16..f2965778431c9 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 da6b8c5c56325..1dc31e161a76a 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 6d815aeca076e..25f492bf9e087 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 eca701ce98c95..a8a955ad83340 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 bb915f58d9d25..f172f6e6b7d91 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 f3bd0100a72a3..fa72d7dd6b2fd 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 15a383175b975..9a047d4f34e70 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 bd3797cba5585..cab7b6ab06be5 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 2060d15b4c787..0000000000000 --- 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 31315dc7c93a5..f7fbc084ebfe4 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 68ac0bbe49fbc..262a193609fc9 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 672aa2464dc13..456a9b86c3474 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 082216d557cfc..5fc141bc46018 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 31b9e1240461e..42dc6c2cafad8 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 68ed9a0de5d59..34f8ca40871ff 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 60ee256c65a90..59d13d04e466a 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 3ae5cfc79f874..a29b5ae137c22 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 a59ccf926f9c2..ebbefb619c616 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 68ce0c2ea3cb7..a5b303df2fd44 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 c74ba1306cc48..236bdf1ac854d 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 7cdf8808aa028..97c0d0bf554e4 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 4c22393d9c0a3..ec13ae997878b 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 c6c6939bda539..00f6b0e09a892 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 5657ec1864b2e..a4dfa56117c2b 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 acd0714961906..8a8c8240c2d08 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 9aa0421717480..ddf87d1d23ad8 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 036ad1d54edcd..d96c4a4e79bc0 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 51c740fd72937..f84214317746b 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 d899c3ffa9129..d5a500900ff03 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 0f46ebe505aa9..ffd8fd39250d1 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 43ff23600766e..6b6fa3ed5e33d 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 0e2761f3f57b1..fc32cabaf71ae 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 6e1b2856afcde..efb336fb4f76d 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 0c34554c12d11..04b45b2d3c68c 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 6d157c9113024..e9a205a5fa64e 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 | 40 ++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 029abf1753913..c40af4de7e03d 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -407,17 +407,22 @@ impl str { /// ``` #[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()); - - // SAFETY: we know that the character boundary will be within four bytes - unsafe { lower_bound + new_index.unwrap_unchecked() } + let mut i = index; + while i > 0 { + 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.saturating_sub(3)); + + i } } @@ -445,15 +450,22 @@ impl str { /// ``` #[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 113abe70805b0..c1231142c6585 100644 --- a/compiler/rustc_codegen_gcc/src/back/write.rs +++ b/compiler/rustc_codegen_gcc/src/back/write.rs @@ -4,7 +4,6 @@ use gccjit::{Context, OutputKind}; 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 71765c5113811..a312068250073 100644 --- a/compiler/rustc_codegen_gcc/src/lib.rs +++ b/compiler/rustc_codegen_gcc/src/lib.rs @@ -426,14 +426,6 @@ impl WriteBackendMethods for GccCodegenBackend { 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 6f8fba2a30dc3..85a06f457ebea 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 8b1913cfa7566..ca84b6de8b11a 100644 --- a/compiler/rustc_codegen_llvm/src/lib.rs +++ b/compiler/rustc_codegen_llvm/src/lib.rs @@ -168,13 +168,6 @@ impl WriteBackendMethods for LlvmCodegenBackend { 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 a41cbd306d0c2..6773d3e24e94f 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 @@ fn start_executing_work( 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 @@ fn start_executing_work( } } } - 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 @@ fn start_executing_work( 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 8e78cbe1963bf..f391c198e1a10 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 5f1973b31a1b8..44b35e8921ec3 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -2168,8 +2168,6 @@ options! { "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 a9be833a6439e..8c9dfcfd18c2c 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 eefbd7cf6c48b..35c322326f8ea 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_abi::Size; 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 @@ mod mapgen; /// 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 @@ impl<'ll, 'tcx> CguCoverageContext<'ll, 'tcx> { .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 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { 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 35c322326f8ea..119237abd6b8f 100644 --- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs +++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs @@ -90,7 +90,10 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> { /// 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 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, '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 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { 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 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> { "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);