From 71763208216e44901c4865119458edc8e6e466c1 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Sat, 4 Jan 2025 09:36:07 +0100 Subject: [PATCH 1/7] tests: Use `as *const _` instead of `.as_ptr()` in ptr fmt test Because `.as_ptr()` changes the type of the pointer (e.g. `&[u8]` becomes `*const u8` instead of `*const [u8]`), and it can't be expected that different types will be formatted the same way. --- library/coretests/tests/fmt/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/coretests/tests/fmt/mod.rs b/library/coretests/tests/fmt/mod.rs index 025c69c4f6236..381615ed39706 100644 --- a/library/coretests/tests/fmt/mod.rs +++ b/library/coretests/tests/fmt/mod.rs @@ -15,8 +15,8 @@ fn test_format_flags() { fn test_pointer_formats_data_pointer() { let b: &[u8] = b""; let s: &str = ""; - assert_eq!(format!("{s:p}"), format!("{:p}", s.as_ptr())); - assert_eq!(format!("{b:p}"), format!("{:p}", b.as_ptr())); + assert_eq!(format!("{s:p}"), format!("{:p}", s as *const _)); + assert_eq!(format!("{b:p}"), format!("{:p}", b as *const _)); } #[test] From 9479b6f0ead1787a895f82473eeb57dd74fded5a Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Fri, 3 Jan 2025 17:51:32 +0100 Subject: [PATCH 2/7] tests: Add regression test for `Debug` impl of raw pointers --- library/Cargo.lock | 26 +++++++++++++++++++++++++ library/coretests/Cargo.toml | 1 + library/coretests/tests/fmt/mod.rs | 31 ++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+) diff --git a/library/Cargo.lock b/library/Cargo.lock index 0be2f9a154939..061c8db4e0225 100644 --- a/library/Cargo.lock +++ b/library/Cargo.lock @@ -79,6 +79,7 @@ version = "0.0.0" dependencies = [ "rand", "rand_xorshift", + "regex", ] [[package]] @@ -297,6 +298,31 @@ dependencies = [ "rand_core", ] +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + [[package]] name = "rustc-demangle" version = "0.1.24" diff --git a/library/coretests/Cargo.toml b/library/coretests/Cargo.toml index e44f01d347b3d..88a7e159c956b 100644 --- a/library/coretests/Cargo.toml +++ b/library/coretests/Cargo.toml @@ -25,3 +25,4 @@ test = true [dev-dependencies] rand = { version = "0.9.0", default-features = false } rand_xorshift = { version = "0.4.0", default-features = false } +regex = { version = "1.11.1", default-features = false } diff --git a/library/coretests/tests/fmt/mod.rs b/library/coretests/tests/fmt/mod.rs index 381615ed39706..13f7bca646fa8 100644 --- a/library/coretests/tests/fmt/mod.rs +++ b/library/coretests/tests/fmt/mod.rs @@ -19,6 +19,37 @@ fn test_pointer_formats_data_pointer() { assert_eq!(format!("{b:p}"), format!("{:p}", b as *const _)); } +#[test] +fn test_fmt_debug_of_raw_pointers() { + use core::fmt::Debug; + + fn check_fmt(t: T, expected: &str) { + use std::sync::LazyLock; + + use regex::Regex; + + static ADDR_REGEX: LazyLock = + LazyLock::new(|| Regex::new(r"0x[0-9a-fA-F]+").unwrap()); + + let formatted = format!("{:?}", t); + let normalized = ADDR_REGEX.replace_all(&formatted, "$$HEX"); + + assert_eq!(normalized, expected); + } + + let plain = &mut 100; + check_fmt(plain as *mut i32, "$HEX"); + check_fmt(plain as *const i32, "$HEX"); + + let slice = &mut [200, 300, 400][..]; + check_fmt(slice as *mut [i32], "$HEX"); + check_fmt(slice as *const [i32], "$HEX"); + + let vtable = &mut 500 as &mut dyn Debug; + check_fmt(vtable as *mut dyn Debug, "$HEX"); + check_fmt(vtable as *const dyn Debug, "$HEX"); +} + #[test] fn test_estimated_capacity() { assert_eq!(format_args!("").estimated_capacity(), 0); From d16da3b8b2be9f1da5a2e9d2b31c499a21d2d7a1 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Fri, 14 Feb 2025 06:42:49 +0100 Subject: [PATCH 3/7] core: Document why Pointee::Metadata can't have 'static bound Co-authored-by: Lukas <26522220+lukas-code@users.noreply.github.com> --- library/core/src/ptr/metadata.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs index 9eee29d485f41..e986b16d116c8 100644 --- a/library/core/src/ptr/metadata.rs +++ b/library/core/src/ptr/metadata.rs @@ -61,6 +61,8 @@ pub trait Pointee { // NOTE: Keep trait bounds in `static_assert_expected_bounds_for_metadata` // in `library/core/src/ptr/metadata.rs` // in sync with those here: + // NOTE: The metadata of `dyn Trait + 'a` is `DynMetadata` + // so a `'static` bound must not be added. type Metadata: fmt::Debug + Copy + Send + Sync + Ord + Hash + Unpin + Freeze; } From 697737a8b18b685270f197ccdd1211e8a010b98b Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Fri, 3 Jan 2025 18:02:33 +0100 Subject: [PATCH 4/7] core: Make `Debug` impl of raw pointers print metadata if present Make Rust pointers less magic by including metadata information in their `Debug` output. This does not break Rust stability guarantees because `Debug` output is explicitly exempted from stability: https://doc.rust-lang.org/std/fmt/trait.Debug.html#stability Co-authored-by: Lukas <26522220+lukas-code@users.noreply.github.com> Co-authored-by: Josh Stone --- library/core/src/fmt/mod.rs | 9 ++++++++- library/core/src/unit.rs | 16 ++++++++++++++++ library/coretests/tests/fmt/mod.rs | 8 ++++---- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index a1bf3a4d7a706..4cfcb412bfd29 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -2776,7 +2776,14 @@ impl Display for char { #[stable(feature = "rust1", since = "1.0.0")] impl Pointer for *const T { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - pointer_fmt_inner(self.expose_provenance(), f) + if <::Metadata as core::unit::IsUnit>::is_unit() { + pointer_fmt_inner(self.expose_provenance(), f) + } else { + f.debug_struct("Pointer") + .field_with("addr", |f| pointer_fmt_inner(self.expose_provenance(), f)) + .field("metadata", &core::ptr::metadata(*self)) + .finish() + } } } diff --git a/library/core/src/unit.rs b/library/core/src/unit.rs index d656005f3d42d..d54816c444bc4 100644 --- a/library/core/src/unit.rs +++ b/library/core/src/unit.rs @@ -17,3 +17,19 @@ impl FromIterator<()> for () { iter.into_iter().for_each(|()| {}) } } + +pub(crate) trait IsUnit { + fn is_unit() -> bool; +} + +impl IsUnit for T { + default fn is_unit() -> bool { + false + } +} + +impl IsUnit for () { + fn is_unit() -> bool { + true + } +} diff --git a/library/coretests/tests/fmt/mod.rs b/library/coretests/tests/fmt/mod.rs index 13f7bca646fa8..cb185dae9de35 100644 --- a/library/coretests/tests/fmt/mod.rs +++ b/library/coretests/tests/fmt/mod.rs @@ -42,12 +42,12 @@ fn test_fmt_debug_of_raw_pointers() { check_fmt(plain as *const i32, "$HEX"); let slice = &mut [200, 300, 400][..]; - check_fmt(slice as *mut [i32], "$HEX"); - check_fmt(slice as *const [i32], "$HEX"); + check_fmt(slice as *mut [i32], "Pointer { addr: $HEX, metadata: 3 }"); + check_fmt(slice as *const [i32], "Pointer { addr: $HEX, metadata: 3 }"); let vtable = &mut 500 as &mut dyn Debug; - check_fmt(vtable as *mut dyn Debug, "$HEX"); - check_fmt(vtable as *const dyn Debug, "$HEX"); + check_fmt(vtable as *mut dyn Debug, "Pointer { addr: $HEX, metadata: DynMetadata($HEX) }"); + check_fmt(vtable as *const dyn Debug, "Pointer { addr: $HEX, metadata: DynMetadata($HEX) }"); } #[test] From 74ec86248a442b64bae3f83443ac72bb5be3d160 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Sun, 23 Feb 2025 18:57:10 +0100 Subject: [PATCH 5/7] libstd: rustdoc: correct note on fds 0/1/2 pre-main Closes: #137490 --- library/std/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs index 938b8c6e4f41b..6b72cb73be02a 100644 --- a/library/std/src/lib.rs +++ b/library/std/src/lib.rs @@ -174,7 +174,9 @@ //! //! - after-main use of thread-locals, which also affects additional features: //! - [`thread::current()`] -//! - before-main stdio file descriptors are not guaranteed to be open on unix platforms +//! - under UNIX, before main, file descriptors 0, 1, and 2 may be unchanged +//! (they are guaranteed to be open during main, +//! and are opened to /dev/null O_RDWR if they weren't open on program start) //! //! //! [I/O]: io From f63981e0913ea2bfa935935595ab04b6cc7a9e42 Mon Sep 17 00:00:00 2001 From: Tapan Prakash Date: Tue, 25 Feb 2025 09:05:09 +0530 Subject: [PATCH 6/7] fix doc path in std::fmt macro --- library/std/src/macros.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index e0f9f0bb5cee4..f008d42804c08 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -41,7 +41,7 @@ macro_rules! panic { /// Use `print!` only for the primary output of your program. Use /// [`eprint!`] instead to print error and progress messages. /// -/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// See the formatting documentation in [`std::fmt`](crate::fmt) /// for details of the macro argument syntax. /// /// [flush]: crate::io::Write::flush @@ -106,7 +106,7 @@ macro_rules! print { /// Use `println!` only for the primary output of your program. Use /// [`eprintln!`] instead to print error and progress messages. /// -/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// See the formatting documentation in [`std::fmt`](crate::fmt) /// for details of the macro argument syntax. /// /// [`std::fmt`]: crate::fmt @@ -156,7 +156,7 @@ macro_rules! println { /// [`io::stderr`]: crate::io::stderr /// [`io::stdout`]: crate::io::stdout /// -/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// See the formatting documentation in [`std::fmt`](crate::fmt) /// for details of the macro argument syntax. /// /// # Panics @@ -190,7 +190,7 @@ macro_rules! eprint { /// Use `eprintln!` only for error and progress messages. Use `println!` /// instead for the primary output of your program. /// -/// See [the formatting documentation in `std::fmt`](../std/fmt/index.html) +/// See the formatting documentation in [`std::fmt`](crate::fmt) /// for details of the macro argument syntax. /// /// [`io::stderr`]: crate::io::stderr From 3d42541313c98e2570672a008117ed8f2fbd81e8 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sat, 15 Mar 2025 19:33:30 -0700 Subject: [PATCH 7/7] Fix the OperandRef type for NullOp::{UbChecks,ContractChecks} --- compiler/rustc_codegen_ssa/src/mir/rvalue.rs | 2 +- compiler/rustc_middle/src/mir/statement.rs | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs index 96be44ee09ff1..72cfd2bffb5d0 100644 --- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs +++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs @@ -747,7 +747,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { let tcx = self.cx.tcx(); OperandRef { val: OperandValue::Immediate(val), - layout: self.cx.layout_of(tcx.types.usize), + layout: self.cx.layout_of(null_op.ty(tcx)), } } diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs index f05a798949b7e..d59b6df44ed5d 100644 --- a/compiler/rustc_middle/src/mir/statement.rs +++ b/compiler/rustc_middle/src/mir/statement.rs @@ -774,6 +774,15 @@ impl BorrowKind { } } +impl<'tcx> NullOp<'tcx> { + pub fn ty(&self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { + match self { + NullOp::SizeOf | NullOp::AlignOf | NullOp::OffsetOf(_) => tcx.types.usize, + NullOp::UbChecks | NullOp::ContractChecks => tcx.types.bool, + } + } +} + impl<'tcx> UnOp { pub fn ty(&self, tcx: TyCtxt<'tcx>, arg_ty: Ty<'tcx>) -> Ty<'tcx> { match self {