From ecbbd58eed6d69d789a4a687d54c4f84811cf185 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 1 Apr 2024 23:21:40 +0200 Subject: [PATCH] lib.miri.rs appraoch --- library/alloc/Cargo.toml | 2 - library/alloc/src/lib.miri.rs | 3 + library/alloc/src/lib.rs | 87 +++-- library/alloc/src/lib_.rs | 59 --- library/core/Cargo.toml | 2 - library/core/src/lib.miri.rs | 3 + library/core/src/lib.rs | 338 ++++++++---------- library/std/Cargo.toml | 4 - library/std/src/lib.miri.rs | 3 + library/std/src/lib.rs | 297 +++++++++++++-- library/std/src/lib_.rs | 270 -------------- library/sysroot/Cargo.toml | 1 - src/bootstrap/src/core/build_steps/test.rs | 19 +- src/tools/miri/README.md | 2 + src/tools/miri/cargo-miri/src/phases.rs | 49 ++- src/tools/miri/src/helpers.rs | 10 +- .../miri/src/shims/unix/foreign_items.rs | 5 + ...private-std-reexport-suggest-public.stderr | 2 +- tests/ui/issues/issue-38857.stderr | 2 +- tests/ui/proc-macro/meta-macro-hygiene.stdout | 13 +- .../nonterminal-token-hygiene.stdout | 13 +- 21 files changed, 573 insertions(+), 611 deletions(-) create mode 100644 library/alloc/src/lib.miri.rs delete mode 100644 library/alloc/src/lib_.rs create mode 100644 library/core/src/lib.miri.rs create mode 100644 library/std/src/lib.miri.rs delete mode 100644 library/std/src/lib_.rs diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml index ccb1a9d5ce149..e8afed6b35a83 100644 --- a/library/alloc/Cargo.toml +++ b/library/alloc/Cargo.toml @@ -36,7 +36,5 @@ compiler-builtins-c = ["compiler_builtins/c"] compiler-builtins-no-asm = ["compiler_builtins/no-asm"] compiler-builtins-mangled-names = ["compiler_builtins/mangled-names"] compiler-builtins-weak-intrinsics = ["compiler_builtins/weak-intrinsics"] -# Empty the crate so Miri can run tests -miri-test = ["core/miri-test"] # Make panics and failed asserts immediately abort without formatting any message panic_immediate_abort = [] diff --git a/library/alloc/src/lib.miri.rs b/library/alloc/src/lib.miri.rs new file mode 100644 index 0000000000000..33b06f85a32f6 --- /dev/null +++ b/library/alloc/src/lib.miri.rs @@ -0,0 +1,3 @@ +#![no_std] +extern crate alloc as realalloc; +pub use realalloc::*; diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 723afde2f8618..cafd59cb0d954 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -72,8 +72,6 @@ not(test), not(any(test, bootstrap)), any(not(feature = "miri-test-libstd"), test, doctest), - all(feature = "miri-test", not(any(test, doctest))), - not(all(feature = "miri-test", not(any(test, doctest)))), no_global_oom_handling, not(no_global_oom_handling), not(no_rc), @@ -219,28 +217,6 @@ // from other crates, but since this can only appear for lang items, it doesn't seem worth fixing. #![feature(intra_doc_pointers)] -// We want to be able to `cargo miri test` this crate, but that's tricky. -// We use the `miri-test` feature to indicate that we're running `cargo miri test`, and -// with that feature we turn this crate into a re-export of the sysroot crate. We only do this when -// building the crate that will become a dependency, not when doing the actual (doc)test build. -// See `core/src/lib.rs` for more information. -#[cfg(all(feature = "miri-test", not(any(test, doctest))))] -extern crate alloc as realalloc; -#[cfg(all(feature = "miri-test", not(any(test, doctest))))] -#[stable(feature = "miri_test", since = "1.0.0")] -pub use realalloc::*; - -// Otherwise, we build the crate as usual. Everything that follows should have -// `#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))]`. To avoid having to repeat the -// same `cfg` so many times, we `include!("lib_.rs")` with the main crate contents, and `cfg` the -// `include!`. However, some macro-related things can't be behind the `include!` so we have to -// repeat the `cfg` for them. - -// Module with internal macros used by other modules (needs to be included before other modules). -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] -#[macro_use] -mod macros; - // Allow testing this library #[cfg(test)] #[macro_use] @@ -250,5 +226,64 @@ extern crate test; #[cfg(test)] mod testing; -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] -include!("lib_.rs"); +// Module with internal macros used by other modules (needs to be included before other modules). +#[macro_use] +mod macros; + +mod raw_vec; + +// Heaps provided for low-level allocation strategies + +pub mod alloc; + +// Primitive types using the heaps above + +// Need to conditionally define the mod from `boxed.rs` to avoid +// duplicating the lang-items when building in test cfg; but also need +// to allow code to have `use boxed::Box;` declarations. +#[cfg(not(test))] +pub mod boxed; +#[cfg(test)] +mod boxed { + pub use std::boxed::Box; +} +pub mod borrow; +pub mod collections; +#[cfg(all(not(no_rc), not(no_sync), not(no_global_oom_handling)))] +pub mod ffi; +pub mod fmt; +#[cfg(not(no_rc))] +pub mod rc; +pub mod slice; +pub mod str; +pub mod string; +#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))] +pub mod sync; +#[cfg(all(not(no_global_oom_handling), not(no_rc), not(no_sync)))] +pub mod task; +#[cfg(test)] +mod tests; +pub mod vec; + +#[doc(hidden)] +#[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")] +pub mod __export { + pub use core::format_args; +} + +#[cfg(test)] +#[allow(dead_code)] // Not used in all configurations +pub(crate) mod test_helpers { + /// Copied from `std::test_helpers::test_rng`, since these tests rely on the + /// seed not being the same for every RNG invocation too. + pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng { + use std::hash::{BuildHasher, Hash, Hasher}; + let mut hasher = std::hash::RandomState::new().build_hasher(); + std::panic::Location::caller().hash(&mut hasher); + let hc64 = hasher.finish(); + let seed_vec = + hc64.to_le_bytes().into_iter().chain(0u8..8).collect::>(); + let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap(); + rand::SeedableRng::from_seed(seed) + } +} diff --git a/library/alloc/src/lib_.rs b/library/alloc/src/lib_.rs deleted file mode 100644 index db420c9b3eb26..0000000000000 --- a/library/alloc/src/lib_.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Vec and VecDeque shared core - -mod raw_vec; - -// Heaps provided for low-level allocation strategies - -pub mod alloc; - -// Primitive types using the heaps above - -// Need to conditionally define the mod from `boxed.rs` to avoid -// duplicating the lang-items when building in test cfg; but also need -// to allow code to have `use boxed::Box;` declarations. -#[cfg(not(test))] -pub mod boxed; -#[cfg(test)] -mod boxed { - pub use std::boxed::Box; -} -pub mod borrow; -pub mod collections; -#[cfg(all(not(no_rc), not(no_sync), not(no_global_oom_handling)))] -pub mod ffi; -pub mod fmt; -#[cfg(not(no_rc))] -pub mod rc; -pub mod slice; -pub mod str; -pub mod string; -#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))] -pub mod sync; -#[cfg(all(not(no_global_oom_handling), not(no_rc), not(no_sync)))] -pub mod task; -#[cfg(test)] -mod tests; -pub mod vec; - -#[doc(hidden)] -#[unstable(feature = "liballoc_internals", issue = "none", reason = "implementation detail")] -pub mod __export { - pub use core::format_args; -} - -#[cfg(test)] -#[allow(dead_code)] // Not used in all configurations -pub(crate) mod test_helpers { - /// Copied from `std::test_helpers::test_rng`, since these tests rely on the - /// seed not being the same for every RNG invocation too. - pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng { - use std::hash::{BuildHasher, Hash, Hasher}; - let mut hasher = std::hash::RandomState::new().build_hasher(); - std::panic::Location::caller().hash(&mut hasher); - let hc64 = hasher.finish(); - let seed_vec = - hc64.to_le_bytes().into_iter().chain(0u8..8).collect::>(); - let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap(); - rand::SeedableRng::from_seed(seed) - } -} diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml index a97b1d98837ed..a02fcf504168a 100644 --- a/library/core/Cargo.toml +++ b/library/core/Cargo.toml @@ -34,5 +34,3 @@ panic_immediate_abort = [] # Make `RefCell` store additional debugging information, which is printed out when # a borrow error occurs debug_refcell = [] -# Empty the crate so Miri can run tests -miri-test = [] diff --git a/library/core/src/lib.miri.rs b/library/core/src/lib.miri.rs new file mode 100644 index 0000000000000..e73fdb94d26bf --- /dev/null +++ b/library/core/src/lib.miri.rs @@ -0,0 +1,3 @@ +#![no_std] +extern crate core as realcore; +pub use realcore::*; diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 207f1f7269219..0cc3ad1ead7f6 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -72,8 +72,6 @@ #![doc(cfg_hide( not(test), any(not(feature = "miri-test-libstd"), test, doctest), - all(feature = "miri-test", not(any(test, doctest))), - not(all(feature = "miri-test", not(any(test, doctest)))), no_fp_fmt_parse, target_pointer_width = "16", target_pointer_width = "32", @@ -284,49 +282,160 @@ #![feature(wasm_target_feature)] // tidy-alphabetical-end -// We want to be able to `cargo miri test` this crate, but that's tricky: -// This will build the crate itself again, so now we have two `core` crates, one in the sysroot and -// one built as dependency of the test crate. That leads to duplicate lang item errors. `./x.py test -// library` avoids this by making the sysroot exactly the crates that `cargo build` produces, but -// Miri builds the sysroot itself so that does not work. -// Instead, we use the `miri-test` feature to indicate that we're running `cargo miri test`, and -// with that feature we turn this crate into a re-export of the sysroot crate. We only do this when -// building the crate that will become a dependency, not when doing the actual (doc)test build. -#[cfg(all(feature = "miri-test", not(any(test, doctest))))] -extern crate core as realcore; -#[cfg(all(feature = "miri-test", not(any(test, doctest))))] -#[stable(feature = "miri_test", since = "1.0.0")] -pub use realcore::*; - -// Otherwise, we build the crate as usual. Everything that follows should have -// `#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))]`. - // allow using `core::` in intra-doc links -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] #[allow(unused_extern_crates)] extern crate self as core; -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] #[prelude_import] #[allow(unused)] use prelude::rust_2021::*; #[cfg(not(test))] // See #65860 -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] #[macro_use] mod macros; +// We don't export this through #[macro_export] for now, to avoid breakage. +// See https://github.com/rust-lang/rust/issues/82913 +#[cfg(not(test))] +#[unstable(feature = "assert_matches", issue = "82775")] +/// Unstable module containing the unstable `assert_matches` macro. +pub mod assert_matches { + #[unstable(feature = "assert_matches", issue = "82775")] + pub use crate::macros::{assert_matches, debug_assert_matches}; +} + +#[unstable(feature = "cfg_match", issue = "115585")] +pub use crate::macros::cfg_match; + +#[macro_use] +mod internal_macros; + +#[path = "num/shells/int_macros.rs"] +#[macro_use] +mod int_macros; + +#[rustc_diagnostic_item = "i128_legacy_mod"] +#[path = "num/shells/i128.rs"] +pub mod i128; +#[rustc_diagnostic_item = "i16_legacy_mod"] +#[path = "num/shells/i16.rs"] +pub mod i16; +#[rustc_diagnostic_item = "i32_legacy_mod"] +#[path = "num/shells/i32.rs"] +pub mod i32; +#[rustc_diagnostic_item = "i64_legacy_mod"] +#[path = "num/shells/i64.rs"] +pub mod i64; +#[rustc_diagnostic_item = "i8_legacy_mod"] +#[path = "num/shells/i8.rs"] +pub mod i8; +#[rustc_diagnostic_item = "isize_legacy_mod"] +#[path = "num/shells/isize.rs"] +pub mod isize; + +#[rustc_diagnostic_item = "u128_legacy_mod"] +#[path = "num/shells/u128.rs"] +pub mod u128; +#[rustc_diagnostic_item = "u16_legacy_mod"] +#[path = "num/shells/u16.rs"] +pub mod u16; +#[rustc_diagnostic_item = "u32_legacy_mod"] +#[path = "num/shells/u32.rs"] +pub mod u32; +#[rustc_diagnostic_item = "u64_legacy_mod"] +#[path = "num/shells/u64.rs"] +pub mod u64; +#[rustc_diagnostic_item = "u8_legacy_mod"] +#[path = "num/shells/u8.rs"] +pub mod u8; +#[rustc_diagnostic_item = "usize_legacy_mod"] +#[path = "num/shells/usize.rs"] +pub mod usize; + +#[path = "num/f32.rs"] +pub mod f32; +#[path = "num/f64.rs"] +pub mod f64; + +#[macro_use] +pub mod num; + /* The core prelude, not as all-encompassing as the std prelude */ -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] + pub mod prelude; +/* Core modules for ownership management */ + +pub mod hint; +pub mod intrinsics; +pub mod mem; +pub mod ptr; +mod ub_checks; + +/* Core language traits */ + +pub mod borrow; +pub mod clone; +pub mod cmp; +pub mod convert; +pub mod default; +pub mod error; +pub mod marker; +pub mod ops; + +/* Core types and methods on primitives */ + +pub mod any; +pub mod array; +pub mod ascii; +pub mod asserting; +#[unstable(feature = "async_iterator", issue = "79024")] +pub mod async_iter; +pub mod cell; +pub mod char; +pub mod ffi; +#[unstable(feature = "core_io_borrowed_buf", issue = "117693")] +pub mod io; +pub mod iter; +pub mod net; +pub mod option; +pub mod panic; +pub mod panicking; +pub mod pin; +pub mod result; +pub mod sync; + +pub mod fmt; +pub mod hash; +pub mod slice; +pub mod str; +pub mod time; + +pub mod unicode; + +/* Async */ +pub mod future; +pub mod task; + +/* Heap memory allocator trait */ +#[allow(missing_docs)] +pub mod alloc; + +// note: does not need to be public +mod bool; +mod escape; +mod tuple; +mod unit; + +#[stable(feature = "core_primitive", since = "1.43.0")] +pub mod primitive; + // Pull in the `core_arch` crate directly into core. The contents of // `core_arch` are in a different repository: rust-lang/stdarch. // // `core_arch` depends on core, but the contents of this module are // set up in such a way that directly pulling it here works such that the // crate uses the this crate as its core. -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] #[path = "../../stdarch/crates/core_arch/src/mod.rs"] #[allow( missing_docs, @@ -340,168 +449,27 @@ pub mod prelude; #[allow(rustdoc::bare_urls)] mod core_arch; -// To avoid repeating the `cfg` over and over, we use an identity macro and `cfg` the macro -// invocation. We can't use this for *everything* as having macro-related imports inside a macro -// does not always work. -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] -macro_rules! identity { ($($x:tt)*) => { $($x)* } } -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] -identity! { - // We don't export this through #[macro_export] for now, to avoid breakage. - // See https://github.com/rust-lang/rust/issues/82913 - #[cfg(not(test))] - #[unstable(feature = "assert_matches", issue = "82775")] - /// Unstable module containing the unstable `assert_matches` macro. - pub mod assert_matches { - #[unstable(feature = "assert_matches", issue = "82775")] - pub use crate::macros::{assert_matches, debug_assert_matches}; - } - - #[unstable(feature = "cfg_match", issue = "115585")] - #[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] - pub use crate::macros::cfg_match; - - #[macro_use] - mod internal_macros; - - #[path = "num/shells/int_macros.rs"] - #[macro_use] - mod int_macros; - - #[rustc_diagnostic_item = "i128_legacy_mod"] - #[path = "num/shells/i128.rs"] - pub mod i128; - #[rustc_diagnostic_item = "i16_legacy_mod"] - #[path = "num/shells/i16.rs"] - pub mod i16; - #[rustc_diagnostic_item = "i32_legacy_mod"] - #[path = "num/shells/i32.rs"] - pub mod i32; - #[rustc_diagnostic_item = "i64_legacy_mod"] - #[path = "num/shells/i64.rs"] - pub mod i64; - #[rustc_diagnostic_item = "i8_legacy_mod"] - #[path = "num/shells/i8.rs"] - pub mod i8; - #[rustc_diagnostic_item = "isize_legacy_mod"] - #[path = "num/shells/isize.rs"] - pub mod isize; - - #[rustc_diagnostic_item = "u128_legacy_mod"] - #[path = "num/shells/u128.rs"] - pub mod u128; - #[rustc_diagnostic_item = "u16_legacy_mod"] - #[path = "num/shells/u16.rs"] - pub mod u16; - #[rustc_diagnostic_item = "u32_legacy_mod"] - #[path = "num/shells/u32.rs"] - pub mod u32; - #[rustc_diagnostic_item = "u64_legacy_mod"] - #[path = "num/shells/u64.rs"] - pub mod u64; - #[rustc_diagnostic_item = "u8_legacy_mod"] - #[path = "num/shells/u8.rs"] - pub mod u8; - #[rustc_diagnostic_item = "usize_legacy_mod"] - #[path = "num/shells/usize.rs"] - pub mod usize; - - #[path = "num/f32.rs"] - pub mod f32; - #[path = "num/f64.rs"] - pub mod f64; - - #[macro_use] - pub mod num; - - /* Core modules for ownership management */ - - pub mod hint; - pub mod intrinsics; - pub mod mem; - pub mod ptr; - mod ub_checks; - - /* Core language traits */ - - pub mod borrow; - pub mod clone; - pub mod cmp; - pub mod convert; - pub mod default; - pub mod error; - pub mod marker; - pub mod ops; - - /* Core types and methods on primitives */ - - pub mod any; - pub mod array; - pub mod ascii; - pub mod asserting; - #[unstable(feature = "async_iterator", issue = "79024")] - pub mod async_iter; - pub mod cell; - pub mod char; - pub mod ffi; - #[unstable(feature = "core_io_borrowed_buf", issue = "117693")] - pub mod io; - pub mod iter; - pub mod net; - pub mod option; - pub mod panic; - pub mod panicking; - pub mod pin; - pub mod result; - pub mod sync; - - pub mod fmt; - pub mod hash; - pub mod slice; - pub mod str; - pub mod time; - - pub mod unicode; - - /* Async */ - pub mod future; - pub mod task; - - /* Heap memory allocator trait */ - #[allow(missing_docs)] - pub mod alloc; - - // note: does not need to be public - mod bool; - mod escape; - mod tuple; - mod unit; - - #[stable(feature = "core_primitive", since = "1.43.0")] - pub mod primitive; - - #[stable(feature = "simd_arch", since = "1.27.0")] - pub mod arch; - - // Pull in the `core_simd` crate directly into core. The contents of - // `core_simd` are in a different repository: rust-lang/portable-simd. - // - // `core_simd` depends on core, but the contents of this module are - // set up in such a way that directly pulling it here works such that the - // crate uses this crate as its core. - #[path = "../../portable-simd/crates/core_simd/src/mod.rs"] - #[allow(missing_debug_implementations, dead_code, unsafe_op_in_unsafe_fn)] - #[allow(rustdoc::bare_urls)] - #[unstable(feature = "portable_simd", issue = "86656")] - mod core_simd; +#[stable(feature = "simd_arch", since = "1.27.0")] +pub mod arch; - #[unstable(feature = "portable_simd", issue = "86656")] - pub mod simd { - #![doc = include_str!("../../portable-simd/crates/core_simd/src/core_simd_docs.md")] +// Pull in the `core_simd` crate directly into core. The contents of +// `core_simd` are in a different repository: rust-lang/portable-simd. +// +// `core_simd` depends on core, but the contents of this module are +// set up in such a way that directly pulling it here works such that the +// crate uses this crate as its core. +#[path = "../../portable-simd/crates/core_simd/src/mod.rs"] +#[allow(missing_debug_implementations, dead_code, unsafe_op_in_unsafe_fn)] +#[allow(rustdoc::bare_urls)] +#[unstable(feature = "portable_simd", issue = "86656")] +mod core_simd; - #[unstable(feature = "portable_simd", issue = "86656")] - pub use crate::core_simd::simd::*; - } +#[unstable(feature = "portable_simd", issue = "86656")] +pub mod simd { + #![doc = include_str!("../../portable-simd/crates/core_simd/src/core_simd_docs.md")] - include!("primitive_docs.rs"); + #[unstable(feature = "portable_simd", issue = "86656")] + pub use crate::core_simd::simd::*; } + +include!("primitive_docs.rs"); diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml index 5601d21126a2e..d2804b4d20af3 100644 --- a/library/std/Cargo.toml +++ b/library/std/Cargo.toml @@ -68,15 +68,11 @@ gimli-symbolize = [] panic-unwind = ["panic_unwind"] profiler = ["profiler_builtins"] - compiler-builtins-c = ["alloc/compiler-builtins-c"] compiler-builtins-mem = ["alloc/compiler-builtins-mem"] compiler-builtins-no-asm = ["alloc/compiler-builtins-no-asm"] compiler-builtins-mangled-names = ["alloc/compiler-builtins-mangled-names"] compiler-builtins-weak-intrinsics = ["alloc/compiler-builtins-weak-intrinsics"] -# Empty the crate so Miri can run tests -miri-test = ["alloc/miri-test"] - llvm-libunwind = ["unwind/llvm-libunwind"] system-llvm-libunwind = ["unwind/system-llvm-libunwind"] diff --git a/library/std/src/lib.miri.rs b/library/std/src/lib.miri.rs new file mode 100644 index 0000000000000..8625e7ae8303b --- /dev/null +++ b/library/std/src/lib.miri.rs @@ -0,0 +1,3 @@ +#![no_std] +extern crate std as realstd; +pub use realstd::*; diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index d4d1827e60534..31a8711e0eb97 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -414,26 +414,8 @@ // #![default_lib_allocator] -// We want to be able to `cargo miri test` this crate, but that's tricky. -// We use the `miri-test` feature to indicate that we're running `cargo miri test`, and -// with that feature we turn this crate into a re-export of the sysroot crate. We only do this when -// building the crate that will become a dependency, not when doing the actual (doc)test build. -// See `core/src/lib.rs` for more information. -#[cfg(not(any(not(feature = "miri-test"), test, doctest)))] -extern crate std as realstd; -#[cfg(not(any(not(feature = "miri-test"), test, doctest)))] -#[stable(feature = "miri_test_libstd", since = "1.0.0")] -pub use realstd::*; - -// Otherwise, we build the crate as usual. Everything that follows should have -// `#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))]`. To avoid having to repeat the -// same `cfg` so many times, we `include!("lib_.rs")` with the main crate contents, and `cfg` the -// `include!`. However, some macro-related things can't be behind the `include!` so we have to -// repeat the `cfg` for them. - // Explicitly import the prelude. The compiler uses this same unstable attribute // to import the prelude implicitly when building crates that depend on std. -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] #[prelude_import] #[allow(unused)] use prelude::rust_2021::*; @@ -442,17 +424,14 @@ use prelude::rust_2021::*; #[cfg(test)] extern crate test; -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] #[allow(unused_imports)] // macros from `alloc` are not used on all platforms #[macro_use] extern crate alloc as alloc_crate; -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] #[doc(masked)] #[allow(unused_extern_crates)] extern crate libc; // We always need an unwinder currently for backtraces -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] #[doc(masked)] #[allow(unused_extern_crates)] extern crate unwind; @@ -462,7 +441,6 @@ extern crate unwind; // Remove exclusion from tidy platform check when this removed. #[doc(masked)] #[allow(unused_extern_crates)] -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] #[cfg(all( not(all(windows, target_env = "msvc", not(target_vendor = "uwp"))), feature = "miniz_oxide" @@ -479,23 +457,286 @@ extern crate miniz_oxide; extern crate std as realstd; // The standard macros that are not built-in to the compiler. -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] #[macro_use] mod macros; // The runtime entry point and a few unstable public functions used by the // compiler -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] #[macro_use] pub mod rt; // The Rust prelude -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] pub mod prelude; -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] +// Public module declarations and re-exports +#[stable(feature = "rust1", since = "1.0.0")] +pub use alloc_crate::borrow; +#[stable(feature = "rust1", since = "1.0.0")] +pub use alloc_crate::boxed; +#[stable(feature = "rust1", since = "1.0.0")] +pub use alloc_crate::fmt; +#[stable(feature = "rust1", since = "1.0.0")] +pub use alloc_crate::format; +#[stable(feature = "rust1", since = "1.0.0")] +pub use alloc_crate::rc; +#[stable(feature = "rust1", since = "1.0.0")] +pub use alloc_crate::slice; +#[stable(feature = "rust1", since = "1.0.0")] +pub use alloc_crate::str; +#[stable(feature = "rust1", since = "1.0.0")] +pub use alloc_crate::string; +#[stable(feature = "rust1", since = "1.0.0")] +pub use alloc_crate::vec; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::any; +#[stable(feature = "core_array", since = "1.36.0")] +pub use core::array; +#[unstable(feature = "async_iterator", issue = "79024")] +pub use core::async_iter; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::cell; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::char; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::clone; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::cmp; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::convert; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::default; +#[stable(feature = "futures_api", since = "1.36.0")] +pub use core::future; +#[stable(feature = "core_hint", since = "1.27.0")] +pub use core::hint; +#[stable(feature = "i128", since = "1.26.0")] +#[allow(deprecated, deprecated_in_future)] +pub use core::i128; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated, deprecated_in_future)] +pub use core::i16; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated, deprecated_in_future)] +pub use core::i32; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated, deprecated_in_future)] +pub use core::i64; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated, deprecated_in_future)] +pub use core::i8; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::intrinsics; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated, deprecated_in_future)] +pub use core::isize; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::iter; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::marker; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::mem; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::ops; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::option; +#[stable(feature = "pin", since = "1.33.0")] +pub use core::pin; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::ptr; +#[stable(feature = "rust1", since = "1.0.0")] +pub use core::result; +#[stable(feature = "i128", since = "1.26.0")] +#[allow(deprecated, deprecated_in_future)] +pub use core::u128; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated, deprecated_in_future)] +pub use core::u16; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated, deprecated_in_future)] +pub use core::u32; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated, deprecated_in_future)] +pub use core::u64; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated, deprecated_in_future)] +pub use core::u8; +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated, deprecated_in_future)] +pub use core::usize; + +pub mod f32; +pub mod f64; + #[macro_use] pub mod thread; +pub mod ascii; +pub mod backtrace; +pub mod collections; +pub mod env; +pub mod error; +pub mod ffi; +pub mod fs; +pub mod hash; +pub mod io; +pub mod net; +pub mod num; +pub mod os; +pub mod panic; +pub mod path; +pub mod process; +pub mod sync; +pub mod time; + +// Pull in `std_float` crate into std. The contents of +// `std_float` are in a different repository: rust-lang/portable-simd. +#[path = "../../portable-simd/crates/std_float/src/lib.rs"] +#[allow(missing_debug_implementations, dead_code, unsafe_op_in_unsafe_fn)] +#[allow(rustdoc::bare_urls)] +#[unstable(feature = "portable_simd", issue = "86656")] +mod std_float; + +#[unstable(feature = "portable_simd", issue = "86656")] +pub mod simd { + #![doc = include_str!("../../portable-simd/crates/core_simd/src/core_simd_docs.md")] + + #[doc(inline)] + pub use crate::std_float::StdFloat; + #[doc(inline)] + pub use core::simd::*; +} + +#[stable(feature = "futures_api", since = "1.36.0")] +pub mod task { + //! Types and Traits for working with asynchronous tasks. + + #[doc(inline)] + #[stable(feature = "futures_api", since = "1.36.0")] + pub use core::task::*; + + #[doc(inline)] + #[stable(feature = "wake_trait", since = "1.51.0")] + pub use alloc::task::*; +} + +#[doc = include_str!("../../stdarch/crates/core_arch/src/core_arch_docs.md")] +#[stable(feature = "simd_arch", since = "1.27.0")] +pub mod arch { + #[stable(feature = "simd_arch", since = "1.27.0")] + // The `no_inline`-attribute is required to make the documentation of all + // targets available. + // See https://github.com/rust-lang/rust/pull/57808#issuecomment-457390549 for + // more information. + #[doc(no_inline)] // Note (#82861): required for correct documentation + pub use core::arch::*; + + #[stable(feature = "simd_aarch64", since = "1.60.0")] + pub use std_detect::is_aarch64_feature_detected; + #[unstable(feature = "stdarch_arm_feature_detection", issue = "111190")] + pub use std_detect::is_arm_feature_detected; + #[unstable(feature = "is_riscv_feature_detected", issue = "111192")] + pub use std_detect::is_riscv_feature_detected; + #[stable(feature = "simd_x86", since = "1.27.0")] + pub use std_detect::is_x86_feature_detected; + #[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")] + pub use std_detect::{is_mips64_feature_detected, is_mips_feature_detected}; + #[unstable(feature = "stdarch_powerpc_feature_detection", issue = "111191")] + pub use std_detect::{is_powerpc64_feature_detected, is_powerpc_feature_detected}; +} + +// This was stabilized in the crate root so we have to keep it there. +#[stable(feature = "simd_x86", since = "1.27.0")] +pub use std_detect::is_x86_feature_detected; + +// Platform-abstraction modules +mod sys; +mod sys_common; -#[cfg(not(all(feature = "miri-test", not(any(test, doctest)))))] -include!("lib_.rs"); +pub mod alloc; + +// Private support modules +mod panicking; + +#[path = "../../backtrace/src/lib.rs"] +#[allow(dead_code, unused_attributes, fuzzy_provenance_casts)] +mod backtrace_rs; + +// Re-export macros defined in core. +#[stable(feature = "rust1", since = "1.0.0")] +#[allow(deprecated, deprecated_in_future)] +pub use core::{ + assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, matches, todo, r#try, + unimplemented, unreachable, write, writeln, +}; + +// Re-export built-in macros defined through core. +#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] +#[allow(deprecated)] +pub use core::{ + assert, assert_matches, cfg, column, compile_error, concat, concat_idents, const_format_args, + env, file, format_args, format_args_nl, include, include_bytes, include_str, line, log_syntax, + module_path, option_env, stringify, trace_macros, +}; + +#[unstable( + feature = "concat_bytes", + issue = "87555", + reason = "`concat_bytes` is not stable enough for use and is subject to change" +)] +pub use core::concat_bytes; + +#[unstable(feature = "cfg_match", issue = "115585")] +pub use core::cfg_match; + +#[stable(feature = "core_primitive", since = "1.43.0")] +pub use core::primitive; + +// Include a number of private modules that exist solely to provide +// the rustdoc documentation for primitive types. Using `include!` +// because rustdoc only looks for these modules at the crate level. +include!("../../core/src/primitive_docs.rs"); + +// Include a number of private modules that exist solely to provide +// the rustdoc documentation for the existing keywords. Using `include!` +// because rustdoc only looks for these modules at the crate level. +include!("keyword_docs.rs"); + +// This is required to avoid an unstable error when `restricted-std` is not +// enabled. The use of #![feature(restricted_std)] in rustc-std-workspace-std +// is unconditional, so the unstable feature needs to be defined somewhere. +#[unstable(feature = "restricted_std", issue = "none")] +mod __restricted_std_workaround {} + +mod sealed { + /// This trait being unreachable from outside the crate + /// prevents outside implementations of our extension traits. + /// This allows adding more trait methods in the future. + #[unstable(feature = "sealed", issue = "none")] + pub trait Sealed {} +} + +#[cfg(test)] +#[allow(dead_code)] // Not used in all configurations. +pub(crate) mod test_helpers { + /// Test-only replacement for `rand::thread_rng()`, which is unusable for + /// us, as we want to allow running stdlib tests on tier-3 targets which may + /// not have `getrandom` support. + /// + /// Does a bit of a song and dance to ensure that the seed is different on + /// each call (as some tests sadly rely on this), but doesn't try that hard. + /// + /// This is duplicated in the `core`, `alloc` test suites (as well as + /// `std`'s integration tests), but figuring out a mechanism to share these + /// seems far more painful than copy-pasting a 7 line function a couple + /// times, given that even under a perma-unstable feature, I don't think we + /// want to expose types from `rand` from `std`. + #[track_caller] + pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng { + use core::hash::{BuildHasher, Hash, Hasher}; + let mut hasher = crate::hash::RandomState::new().build_hasher(); + core::panic::Location::caller().hash(&mut hasher); + let hc64 = hasher.finish(); + let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::>(); + let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap(); + rand::SeedableRng::from_seed(seed) + } +} diff --git a/library/std/src/lib_.rs b/library/std/src/lib_.rs deleted file mode 100644 index 74cf61c6713a3..0000000000000 --- a/library/std/src/lib_.rs +++ /dev/null @@ -1,270 +0,0 @@ -// Public module declarations and re-exports -#[stable(feature = "rust1", since = "1.0.0")] -pub use alloc_crate::borrow; -#[stable(feature = "rust1", since = "1.0.0")] -pub use alloc_crate::boxed; -#[stable(feature = "rust1", since = "1.0.0")] -pub use alloc_crate::fmt; -#[stable(feature = "rust1", since = "1.0.0")] -pub use alloc_crate::format; -#[stable(feature = "rust1", since = "1.0.0")] -pub use alloc_crate::rc; -#[stable(feature = "rust1", since = "1.0.0")] -pub use alloc_crate::slice; -#[stable(feature = "rust1", since = "1.0.0")] -pub use alloc_crate::str; -#[stable(feature = "rust1", since = "1.0.0")] -pub use alloc_crate::string; -#[stable(feature = "rust1", since = "1.0.0")] -pub use alloc_crate::vec; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::any; -#[stable(feature = "core_array", since = "1.36.0")] -pub use core::array; -#[unstable(feature = "async_iterator", issue = "79024")] -pub use core::async_iter; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::cell; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::char; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::clone; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::cmp; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::convert; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::default; -#[stable(feature = "futures_api", since = "1.36.0")] -pub use core::future; -#[stable(feature = "core_hint", since = "1.27.0")] -pub use core::hint; -#[stable(feature = "i128", since = "1.26.0")] -#[allow(deprecated, deprecated_in_future)] -pub use core::i128; -#[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future)] -pub use core::i16; -#[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future)] -pub use core::i32; -#[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future)] -pub use core::i64; -#[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future)] -pub use core::i8; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::intrinsics; -#[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future)] -pub use core::isize; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::iter; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::marker; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::mem; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::ops; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::option; -#[stable(feature = "pin", since = "1.33.0")] -pub use core::pin; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::ptr; -#[stable(feature = "rust1", since = "1.0.0")] -pub use core::result; -#[stable(feature = "i128", since = "1.26.0")] -#[allow(deprecated, deprecated_in_future)] -pub use core::u128; -#[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future)] -pub use core::u16; -#[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future)] -pub use core::u32; -#[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future)] -pub use core::u64; -#[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future)] -pub use core::u8; -#[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future)] -pub use core::usize; - -pub mod f32; -pub mod f64; - -pub mod ascii; -pub mod backtrace; -pub mod collections; -pub mod env; -pub mod error; -pub mod ffi; -pub mod fs; -pub mod hash; -pub mod io; -pub mod net; -pub mod num; -pub mod os; -pub mod panic; -pub mod path; -pub mod process; -pub mod sync; -pub mod time; - -// Pull in `std_float` crate into std. The contents of -// `std_float` are in a different repository: rust-lang/portable-simd. -#[path = "../../portable-simd/crates/std_float/src/lib.rs"] -#[allow(missing_debug_implementations, dead_code, unsafe_op_in_unsafe_fn)] -#[allow(rustdoc::bare_urls)] -#[unstable(feature = "portable_simd", issue = "86656")] -mod std_float; - -#[unstable(feature = "portable_simd", issue = "86656")] -pub mod simd { - #![doc = include_str!("../../portable-simd/crates/core_simd/src/core_simd_docs.md")] - - #[doc(inline)] - pub use crate::std_float::StdFloat; - #[doc(inline)] - pub use core::simd::*; -} - -#[stable(feature = "futures_api", since = "1.36.0")] -pub mod task { - //! Types and Traits for working with asynchronous tasks. - - #[doc(inline)] - #[stable(feature = "futures_api", since = "1.36.0")] - pub use core::task::*; - - #[doc(inline)] - #[stable(feature = "wake_trait", since = "1.51.0")] - pub use alloc::task::*; -} - -#[doc = include_str!("../../stdarch/crates/core_arch/src/core_arch_docs.md")] -#[stable(feature = "simd_arch", since = "1.27.0")] -pub mod arch { - #[stable(feature = "simd_arch", since = "1.27.0")] - // The `no_inline`-attribute is required to make the documentation of all - // targets available. - // See https://github.com/rust-lang/rust/pull/57808#issuecomment-457390549 for - // more information. - #[doc(no_inline)] // Note (#82861): required for correct documentation - pub use core::arch::*; - - #[stable(feature = "simd_aarch64", since = "1.60.0")] - pub use std_detect::is_aarch64_feature_detected; - #[unstable(feature = "stdarch_arm_feature_detection", issue = "111190")] - pub use std_detect::is_arm_feature_detected; - #[unstable(feature = "is_riscv_feature_detected", issue = "111192")] - pub use std_detect::is_riscv_feature_detected; - #[stable(feature = "simd_x86", since = "1.27.0")] - pub use std_detect::is_x86_feature_detected; - #[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")] - pub use std_detect::{is_mips64_feature_detected, is_mips_feature_detected}; - #[unstable(feature = "stdarch_powerpc_feature_detection", issue = "111191")] - pub use std_detect::{is_powerpc64_feature_detected, is_powerpc_feature_detected}; -} - -// This was stabilized in the crate root so we have to keep it there. -#[stable(feature = "simd_x86", since = "1.27.0")] -pub use std_detect::is_x86_feature_detected; - -// Platform-abstraction modules -mod sys; -mod sys_common; - -pub mod alloc; - -// Private support modules -mod panicking; - -#[path = "../../backtrace/src/lib.rs"] -#[allow(dead_code, unused_attributes, fuzzy_provenance_casts)] -mod backtrace_rs; - -// Re-export macros defined in core. -#[stable(feature = "rust1", since = "1.0.0")] -#[allow(deprecated, deprecated_in_future)] -pub use core::{ - assert_eq, assert_ne, debug_assert, debug_assert_eq, debug_assert_ne, matches, todo, r#try, - unimplemented, unreachable, write, writeln, -}; - -// Re-export built-in macros defined through core. -#[stable(feature = "builtin_macro_prelude", since = "1.38.0")] -#[allow(deprecated)] -pub use core::{ - assert, assert_matches, cfg, column, compile_error, concat, concat_idents, const_format_args, - env, file, format_args, format_args_nl, include, include_bytes, include_str, line, log_syntax, - module_path, option_env, stringify, trace_macros, -}; - -#[unstable( - feature = "concat_bytes", - issue = "87555", - reason = "`concat_bytes` is not stable enough for use and is subject to change" -)] -pub use core::concat_bytes; - -#[unstable(feature = "cfg_match", issue = "115585")] -pub use core::cfg_match; - -#[stable(feature = "core_primitive", since = "1.43.0")] -pub use core::primitive; - -// Include a number of private modules that exist solely to provide -// the rustdoc documentation for primitive types. Using `include!` -// because rustdoc only looks for these modules at the crate level. -include!("../../core/src/primitive_docs.rs"); - -// Include a number of private modules that exist solely to provide -// the rustdoc documentation for the existing keywords. Using `include!` -// because rustdoc only looks for these modules at the crate level. -include!("keyword_docs.rs"); - -// This is required to avoid an unstable error when `restricted-std` is not -// enabled. The use of #![feature(restricted_std)] in rustc-std-workspace-std -// is unconditional, so the unstable feature needs to be defined somewhere. -#[unstable(feature = "restricted_std", issue = "none")] -mod __restricted_std_workaround {} - -mod sealed { - /// This trait being unreachable from outside the crate - /// prevents outside implementations of our extension traits. - /// This allows adding more trait methods in the future. - #[unstable(feature = "sealed", issue = "none")] - pub trait Sealed {} -} - -#[cfg(test)] -#[allow(dead_code)] // Not used in all configurations. -pub(crate) mod test_helpers { - /// Test-only replacement for `rand::thread_rng()`, which is unusable for - /// us, as we want to allow running stdlib tests on tier-3 targets which may - /// not have `getrandom` support. - /// - /// Does a bit of a song and dance to ensure that the seed is different on - /// each call (as some tests sadly rely on this), but doesn't try that hard. - /// - /// This is duplicated in the `core`, `alloc` test suites (as well as - /// `std`'s integration tests), but figuring out a mechanism to share these - /// seems far more painful than copy-pasting a 7 line function a couple - /// times, given that even under a perma-unstable feature, I don't think we - /// want to expose types from `rand` from `std`. - #[track_caller] - pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng { - use core::hash::{BuildHasher, Hash, Hasher}; - let mut hasher = crate::hash::RandomState::new().build_hasher(); - core::panic::Location::caller().hash(&mut hasher); - let hc64 = hasher.finish(); - let seed_vec = hc64.to_le_bytes().into_iter().chain(0u8..8).collect::>(); - let seed: [u8; 16] = seed_vec.as_slice().try_into().unwrap(); - rand::SeedableRng::from_seed(seed) - } -} diff --git a/library/sysroot/Cargo.toml b/library/sysroot/Cargo.toml index 1227f4b1c798a..6ff24a8db59c3 100644 --- a/library/sysroot/Cargo.toml +++ b/library/sysroot/Cargo.toml @@ -18,7 +18,6 @@ compiler-builtins-mem = ["std/compiler-builtins-mem"] compiler-builtins-no-asm = ["std/compiler-builtins-no-asm"] compiler-builtins-mangled-names = ["std/compiler-builtins-mangled-names"] compiler-builtins-weak-intrinsics = ["std/compiler-builtins-weak-intrinsics"] -miri-test = ["std/miri-test"] llvm-libunwind = ["std/llvm-libunwind"] system-llvm-libunwind = ["std/system-llvm-libunwind"] panic-unwind = ["std/panic_unwind"] diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 8c1b1d8df4553..5b476f30e92ed 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2634,13 +2634,18 @@ impl Step for Crate { ); cargo.env("MIRI_SYSROOT", &miri_sysroot); cargo.env("MIRI_HOST_SYSROOT", &sysroot); - // Regular `cargo test` on the library crates relies on the sysroot being just a copy of - // exactly what `cargo build` would do. Hence these are considered the same crate and - // not two different crates with the same name. But in Miri that's not how we build the - // sysroot, so instead we set this feature that turns the crate into a re-export of the - // sysroot crate for the regular build (but not the test or doctest build!) so we avoid - // duplicate lang items. - cargo.arg("--features").arg("miri-test"); + // This hack helps bootstrap run standard library tests in Miri. The issue is as + // follows: when running `cargo miri test` on libcore, cargo builds a local copy of core + // and makes it a dependency of the integration test crate. This copy duplicates all the + // lang items, so the build fails. (Regular testing avoids this because the sysroot is a + // literal copy of what `cargo build` produces, but since Miri builds its own sysroot + // this does not work for us.) So we need to make it so that the locally built libcore + // contains all the items from `core`, but does not re-define them -- we want to replace + // the entire crate but a re-export of the sysroot crate. We do this by swapping out the + // source file: if `MIRI_REPLACE_LIBRS_IF_NOT_TEST` is set and we are building a + // `lib.rs` file, and a `lib.miri.rs` file exists in the same folder, we build that + // instead. But crucially we only do that for the library, not the test builds. + cargo.env("MIRI_REPLACE_LIBRS_IF_NOT_TEST", "1"); cargo } else { // Prepare sysroot diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md index 26e55b897080c..bd6efeac09ad8 100644 --- a/src/tools/miri/README.md +++ b/src/tools/miri/README.md @@ -507,6 +507,8 @@ binaries, and as such worth documenting: crate currently being compiled. * `MIRI_ORIG_RUSTDOC` is set and read by different phases of `cargo-miri` to remember the value of `RUSTDOC` from before it was overwritten. +* `MIRI_REPLACE_LIBRS_IF_NOT_TEST` when set to any value enables a hack that helps bootstrap + run the standard library tests in Miri. * `MIRI_VERBOSE` when set to any value tells the various `cargo-miri` phases to perform verbose logging. * `MIRI_HOST_SYSROOT` is set by bootstrap to tell `cargo-miri` which sysroot to use for *host* diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs index 694720ab21f2d..702015aee004a 100644 --- a/src/tools/miri/cargo-miri/src/phases.rs +++ b/src/tools/miri/cargo-miri/src/phases.rs @@ -3,7 +3,7 @@ use std::env; use std::fs::{self, File}; use std::io::BufReader; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::process::Command; use rustc_version::VersionMeta; @@ -409,12 +409,27 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { let mut cmd = miri(); let mut emit_link_hack = false; + // This hack helps bootstrap run standard library tests in Miri. The issue is as follows: when + // running `cargo miri test` on libcore, cargo builds a local copy of core and makes it a + // dependency of the integration test crate. This copy duplicates all the lang items, so the + // build fails. (Regular testing avoids this because the sysroot is a literal copy of what + // `cargo build` produces, but since Miri builds its own sysroot this does not work for us.) So + // we need to make it so that the locally built libcore contains all the items from `core`, but + // does not re-define them -- we want to replace the entire crate but a re-export of the sysroot + // crate. We do this by swapping out the source file: if `MIRI_REPLACE_LIBRS_IF_NOT_TEST` is set + // and we are building a `lib.rs` file, and a `lib.miri.rs` file exists in the same folder, we + // build that instead. But crucially we only do that for the library, not the unit test crate + // (which would be runnable) or rustdoc (which would have a different `phase`). + let replace_librs = env::var_os("MIRI_REPLACE_LIBRS_IF_NOT_TEST").is_some() + && !runnable_crate + && phase == RustcPhase::Build; // Arguments are treated very differently depending on whether this crate is // for interpretation by Miri, or for use by a build script / proc macro. if target_crate { - // Forward arguments, but remove "link" from "--emit" to make this a check-only build. + // Forward arguments, but patched. let emit_flag = "--emit"; while let Some(arg) = args.next() { + // Patch `--emit`: remove "link" from "--emit" to make this a check-only build. if let Some(val) = arg.strip_prefix(emit_flag) { // Patch this argument. First, extract its value. let val = @@ -429,13 +444,33 @@ pub fn phase_rustc(mut args: impl Iterator, phase: RustcPhase) { } } cmd.arg(format!("{emit_flag}={}", val.join(","))); - } else if arg == "--extern" { - // Patch `--extern` filenames, since Cargo sometimes passes stub `.rlib` files: - // https://github.com/rust-lang/miri/issues/1705 + continue; + } + // Patch `--extern` filenames, since Cargo sometimes passes stub `.rlib` files: + // https://github.com/rust-lang/miri/issues/1705 + if arg == "--extern" { forward_patched_extern_arg(&mut args, &mut cmd); - } else { - cmd.arg(arg); + continue; } + // If the REPLACE_LIBRS hack is enabled and we are building a `lib.rs` file, and a + // `lib.miri.rs` file exists, then build that instead. We only consider relative paths + // as cargo uses those for files in the workspace; dependencies from crates.io get + // absolute paths. + if replace_librs && arg.ends_with("/lib.rs") { + let path = Path::new(&arg); + if path.is_relative() && path.is_file() { + let miri_rs = Path::new(&arg).with_extension("miri.rs"); + if miri_rs.is_file() { + if verbose > 0 { + eprintln!("Performing REPLACE_LIBRS hack: {arg:?} -> {miri_rs:?}"); + } + cmd.arg(miri_rs); + continue; + } + } + } + // Fallback: just propagate the argument. + cmd.arg(arg); } // During setup, patch the panic runtime for `libpanic_abort` (mirroring what bootstrap usually does). diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs index c12fe0e086d8c..fd6e7e067fb11 100644 --- a/src/tools/miri/src/helpers.rs +++ b/src/tools/miri/src/helpers.rs @@ -983,12 +983,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Fall back to the instance of the function itself. let instance = instance.unwrap_or(frame.instance); // Now check if this is in the same crate as start_fn. - // As a special exception we also allow unit tests from - // to call these - // shims. let frame_crate = this.tcx.def_path(instance.def_id()).krate; + let crate_name = this.tcx.crate_name(frame_crate); + // As a special hack we also need to allow this when we the standard library unit test + // crate. On miri-test-libstd that crate has name `std_miri_test`; in bootstrap it is just + // `std`. frame_crate == this.tcx.def_path(start_fn).krate - || this.tcx.crate_name(frame_crate).as_str() == "std_miri_test" + || crate_name.as_str() == "std_miri_test" + || (crate_name.as_str() == "std" && std::env::var_os("RUSTC_STAGE").is_some()) } /// Handler that should be called when unsupported functionality is encountered. diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs index 4ceda80935047..c5065ae0f6934 100644 --- a/src/tools/miri/src/shims/unix/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/foreign_items.rs @@ -624,6 +624,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { let [_] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; this.write_null(dest)?; } + | "pthread_attr_init" => { + let frame_crate = this.tcx.def_path(this.frame().instance.def_id()).krate; + dbg!(this.tcx.crate_name(frame_crate).as_str()); + throw_unsup_format!("not supported"); + } | "pthread_attr_setstacksize" if this.frame_in_std() => { let [_, _] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; diff --git a/tests/ui/imports/private-std-reexport-suggest-public.stderr b/tests/ui/imports/private-std-reexport-suggest-public.stderr index 1c8add3a974b9..222553235aaac 100644 --- a/tests/ui/imports/private-std-reexport-suggest-public.stderr +++ b/tests/ui/imports/private-std-reexport-suggest-public.stderr @@ -10,7 +10,7 @@ note: the module import `mem` is defined here... LL | use std::mem; | ^^^^^^^^ note: ...and refers to the module `mem` which is defined here - --> $SRC_DIR/std/src/lib_.rs:LL:COL + --> $SRC_DIR/std/src/lib.rs:LL:COL | = note: you could import this directly help: import `mem` through the re-export diff --git a/tests/ui/issues/issue-38857.stderr b/tests/ui/issues/issue-38857.stderr index 70309648ac4fe..4d505784b8654 100644 --- a/tests/ui/issues/issue-38857.stderr +++ b/tests/ui/issues/issue-38857.stderr @@ -11,7 +11,7 @@ LL | let a = std::sys::imp::process::process_common::StdioPipes { ..panic!() | ^^^ private module | note: the module `sys` is defined here - --> $SRC_DIR/std/src/lib_.rs:LL:COL + --> $SRC_DIR/std/src/lib.rs:LL:COL error: aborting due to 2 previous errors diff --git a/tests/ui/proc-macro/meta-macro-hygiene.stdout b/tests/ui/proc-macro/meta-macro-hygiene.stdout index 402ef1e096eb3..8697ba58a3903 100644 --- a/tests/ui/proc-macro/meta-macro-hygiene.stdout +++ b/tests/ui/proc-macro/meta-macro-hygiene.stdout @@ -50,13 +50,12 @@ crate0::{{expn1}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: crate0::{{expn2}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "produce_it") crate0::{{expn3}}: parent: crate0::{{expn2}}, call_site_ctxt: #3, def_site_ctxt: #0, kind: Macro(Bang, "meta_macro::print_def_site") crate0::{{expn4}}: parent: crate0::{{expn3}}, call_site_ctxt: #4, def_site_ctxt: #0, kind: Macro(Bang, "$crate::dummy") -crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "identity") -crate1::{{expnNNN}}: parent: crate1::{{expnNNN}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") -crate1::{{expnNNN}}: parent: crate1::{{expnNNN}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") -crate1::{{expnNNN}}: parent: crate1::{{expnNNN}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") -crate1::{{expnNNN}}: parent: crate1::{{expnNNN}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "derive") -crate1::{{expnNNN}}: parent: crate1::{{expnNNN}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "derive") -crate1::{{expnNNN}}: parent: crate1::{{expnNNN}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "include") +crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") +crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") +crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") +crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "derive") +crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "derive") +crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "include") SyntaxContexts: #0: parent: #0, outer_mark: (crate0::{{expn0}}, Opaque) diff --git a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout index 2aae5630f3ed6..2078e59b8b4b0 100644 --- a/tests/ui/proc-macro/nonterminal-token-hygiene.stdout +++ b/tests/ui/proc-macro/nonterminal-token-hygiene.stdout @@ -72,13 +72,12 @@ crate0::{{expn1}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: crate0::{{expn2}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "outer") crate0::{{expn3}}: parent: crate0::{{expn2}}, call_site_ctxt: #3, def_site_ctxt: #3, kind: Macro(Bang, "inner") crate0::{{expn4}}: parent: crate0::{{expn3}}, call_site_ctxt: #5, def_site_ctxt: #0, kind: Macro(Bang, "print_bang") -crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "identity") -crate1::{{expnNNN}}: parent: crate1::{{expnNNN}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") -crate1::{{expnNNN}}: parent: crate1::{{expnNNN}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") -crate1::{{expnNNN}}: parent: crate1::{{expnNNN}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") -crate1::{{expnNNN}}: parent: crate1::{{expnNNN}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "derive") -crate1::{{expnNNN}}: parent: crate1::{{expnNNN}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "derive") -crate1::{{expnNNN}}: parent: crate1::{{expnNNN}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "include") +crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") +crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") +crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "diagnostic::on_unimplemented") +crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "derive") +crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Attr, "derive") +crate1::{{expnNNN}}: parent: crate0::{{expn0}}, call_site_ctxt: #0, def_site_ctxt: #0, kind: Macro(Bang, "include") SyntaxContexts: #0: parent: #0, outer_mark: (crate0::{{expn0}}, Opaque)