From 670d892dc9f1b6f74b7103a6602262f383197d20 Mon Sep 17 00:00:00 2001
From: Peter Jaszkowiak
Date: Sat, 1 Feb 2025 13:09:28 -0700
Subject: [PATCH 01/16] add UnsafeCell direct access APIs
---
library/core/src/cell.rs | 84 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 84 insertions(+)
diff --git a/library/core/src/cell.rs b/library/core/src/cell.rs
index 20187e478aac5..320d8176011fd 100644
--- a/library/core/src/cell.rs
+++ b/library/core/src/cell.rs
@@ -2118,6 +2118,35 @@ impl UnsafeCell {
pub const fn into_inner(self) -> T {
self.value
}
+
+ /// Replace the value in this `UnsafeCell` and return the old value.
+ ///
+ /// # Safety
+ ///
+ /// The caller must take care to avoid aliasing and data races.
+ ///
+ /// - It is Undefined Behavior to allow calls to race with
+ /// any other access to the wrapped value.
+ /// - It is Undefined Behavior to call this while any other
+ /// reference(s) to the wrapped value are alive.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(unsafe_cell_access)]
+ /// use std::cell::UnsafeCell;
+ ///
+ /// let uc = UnsafeCell::new(5);
+ ///
+ /// let old = unsafe { uc.replace(10) };
+ /// assert_eq!(old, 5);
+ /// ```
+ #[inline]
+ #[unstable(feature = "unsafe_cell_access", issue = "136327")]
+ pub const unsafe fn replace(&self, value: T) -> T {
+ // SAFETY: pointer comes from `&self` so naturally satisfies invariants.
+ unsafe { ptr::replace(self.get(), value) }
+ }
}
impl UnsafeCell {
@@ -2230,6 +2259,61 @@ impl UnsafeCell {
// no guarantee for user code that this will work in future versions of the compiler!
this as *const T as *mut T
}
+
+ /// Get a shared reference to the value within the `UnsafeCell`.
+ ///
+ /// # Safety
+ ///
+ /// - It is Undefined Behavior to call this while any mutable
+ /// reference to the wrapped value is alive.
+ /// - Mutating the wrapped value while the returned
+ /// reference is alive is Undefined Behavior.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(unsafe_cell_access)]
+ /// use std::cell::UnsafeCell;
+ ///
+ /// let uc = UnsafeCell::new(5);
+ ///
+ /// let val = unsafe { uc.as_ref_unchecked() };
+ /// assert_eq!(val, &5);
+ /// ```
+ #[inline]
+ #[unstable(feature = "unsafe_cell_access", issue = "136327")]
+ pub const unsafe fn as_ref_unchecked(&self) -> &T {
+ // SAFETY: pointer comes from `&self` so naturally satisfies ptr-to-ref invariants.
+ unsafe { self.get().as_ref_unchecked() }
+ }
+
+ /// Get an exclusive reference to the value within the `UnsafeCell`.
+ ///
+ /// # Safety
+ ///
+ /// - It is Undefined Behavior to call this while any other
+ /// reference(s) to the wrapped value are alive.
+ /// - Mutating the wrapped value through other means while the
+ /// returned reference is alive is Undefined Behavior.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(unsafe_cell_access)]
+ /// use std::cell::UnsafeCell;
+ ///
+ /// let uc = UnsafeCell::new(5);
+ ///
+ /// unsafe { *uc.as_mut_unchecked() += 1; }
+ /// assert_eq!(uc.into_inner(), 6);
+ /// ```
+ #[inline]
+ #[unstable(feature = "unsafe_cell_access", issue = "136327")]
+ #[allow(clippy::mut_from_ref)]
+ pub const unsafe fn as_mut_unchecked(&self) -> &mut T {
+ // SAFETY: pointer comes from `&self` so naturally satisfies ptr-to-ref invariants.
+ unsafe { self.get().as_mut_unchecked() }
+ }
}
#[stable(feature = "unsafe_cell_default", since = "1.10.0")]
From 49ea67aa91642708435cb344d0c32fc839e1c4f3 Mon Sep 17 00:00:00 2001
From: Ralf Jung
Date: Mon, 3 Feb 2025 12:05:23 +0100
Subject: [PATCH 02/16] std::fs: further simplify dirent64 handling
---
library/std/src/sys/pal/unix/fs.rs | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index fdf011c19482a..6c41781fe850c 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -740,29 +740,27 @@ impl Iterator for ReadDir {
// to `byte_offset` and thus does not require the full extent of `*entry_ptr`
// to be in bounds of the same allocation, only the offset of the field
// being referenced.
- macro_rules! entry_field_ptr {
- ($field:ident) => {
- &raw const (*entry_ptr).$field
- };
- }
// d_name is guaranteed to be null-terminated.
- let name = CStr::from_ptr(entry_field_ptr!(d_name).cast());
+ let name = CStr::from_ptr((&raw const (*entry_ptr).d_name).cast());
let name_bytes = name.to_bytes();
if name_bytes == b"." || name_bytes == b".." {
continue;
}
+ // When loading from a field, we can skip the `&raw const`; `(*entry_ptr).d_ino` as
+ // a value expression will do the right thing: `byte_offset` to the field and then
+ // only access those bytes.
#[cfg(not(target_os = "vita"))]
let entry = dirent64_min {
- d_ino: *entry_field_ptr!(d_ino) as u64,
+ d_ino: (*entry_ptr).d_ino as u64,
#[cfg(not(any(
target_os = "solaris",
target_os = "illumos",
target_os = "aix",
target_os = "nto",
)))]
- d_type: *entry_field_ptr!(d_type) as u8,
+ d_type: (*entry_ptr).d_type as u8,
};
#[cfg(target_os = "vita")]
From 37c77defb4fa327abc7377f5f6e8fc9692afe52a Mon Sep 17 00:00:00 2001
From: Josh Triplett
Date: Mon, 3 Feb 2025 16:37:59 +0100
Subject: [PATCH 03/16] For NonZero impl macros, give unsigned impls access to
the corresponding signed type
There was a macro parameter giving signed impls access to the
corresponding unsigned type, but not the other way around.
This will allow implementing methods converting in both directions.
---
library/core/src/num/nonzero.rs | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 61e83ebfad7de..3becbc9bade30 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -474,6 +474,7 @@ macro_rules! nonzero_integer {
#[$stability:meta]
Self = $Ty:ident,
Primitive = $signedness:ident $Int:ident,
+ SignedPrimitive = $Sint:ty,
UnsignedPrimitive = $Uint:ty,
// Used in doc comments.
@@ -905,6 +906,7 @@ macro_rules! nonzero_integer {
nonzero_integer_signedness_dependent_methods! {
Primitive = $signedness $Int,
+ SignedPrimitive = $Sint,
UnsignedPrimitive = $Uint,
}
@@ -1128,6 +1130,7 @@ macro_rules! nonzero_integer {
(
Self = $Ty:ident,
Primitive = unsigned $Int:ident,
+ SignedPrimitive = $Sint:ident,
rot = $rot:literal,
rot_op = $rot_op:literal,
rot_result = $rot_result:literal,
@@ -1140,6 +1143,7 @@ macro_rules! nonzero_integer {
#[stable(feature = "nonzero", since = "1.28.0")]
Self = $Ty,
Primitive = unsigned $Int,
+ SignedPrimitive = $Sint,
UnsignedPrimitive = $Int,
rot = $rot,
rot_op = $rot_op,
@@ -1154,7 +1158,7 @@ macro_rules! nonzero_integer {
(
Self = $Ty:ident,
Primitive = signed $Int:ident,
- UnsignedPrimitive = $UInt:ident,
+ UnsignedPrimitive = $Uint:ident,
rot = $rot:literal,
rot_op = $rot_op:literal,
rot_result = $rot_result:literal,
@@ -1166,7 +1170,8 @@ macro_rules! nonzero_integer {
#[stable(feature = "signed_nonzero", since = "1.34.0")]
Self = $Ty,
Primitive = signed $Int,
- UnsignedPrimitive = $UInt,
+ SignedPrimitive = $Int,
+ UnsignedPrimitive = $Uint,
rot = $rot,
rot_op = $rot_op,
rot_result = $rot_result,
@@ -1286,6 +1291,7 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
// Associated items for unsigned nonzero types only.
(
Primitive = unsigned $Int:ident,
+ SignedPrimitive = $Sint:ty,
UnsignedPrimitive = $Uint:ty,
) => {
/// The smallest value that can be represented by this non-zero
@@ -1625,6 +1631,7 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
// Associated items for signed nonzero types only.
(
Primitive = signed $Int:ident,
+ SignedPrimitive = $Sint:ty,
UnsignedPrimitive = $Uint:ty,
) => {
/// The smallest value that can be represented by this non-zero
@@ -2041,6 +2048,7 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
nonzero_integer! {
Self = NonZeroU8,
Primitive = unsigned u8,
+ SignedPrimitive = i8,
rot = 2,
rot_op = "0x82",
rot_result = "0xa",
@@ -2052,6 +2060,7 @@ nonzero_integer! {
nonzero_integer! {
Self = NonZeroU16,
Primitive = unsigned u16,
+ SignedPrimitive = i16,
rot = 4,
rot_op = "0xa003",
rot_result = "0x3a",
@@ -2063,6 +2072,7 @@ nonzero_integer! {
nonzero_integer! {
Self = NonZeroU32,
Primitive = unsigned u32,
+ SignedPrimitive = i32,
rot = 8,
rot_op = "0x10000b3",
rot_result = "0xb301",
@@ -2074,6 +2084,7 @@ nonzero_integer! {
nonzero_integer! {
Self = NonZeroU64,
Primitive = unsigned u64,
+ SignedPrimitive = i64,
rot = 12,
rot_op = "0xaa00000000006e1",
rot_result = "0x6e10aa",
@@ -2085,6 +2096,7 @@ nonzero_integer! {
nonzero_integer! {
Self = NonZeroU128,
Primitive = unsigned u128,
+ SignedPrimitive = i128,
rot = 16,
rot_op = "0x13f40000000000000000000000004f76",
rot_result = "0x4f7613f4",
@@ -2097,6 +2109,7 @@ nonzero_integer! {
nonzero_integer! {
Self = NonZeroUsize,
Primitive = unsigned usize,
+ SignedPrimitive = isize,
rot = 4,
rot_op = "0xa003",
rot_result = "0x3a",
@@ -2109,6 +2122,7 @@ nonzero_integer! {
nonzero_integer! {
Self = NonZeroUsize,
Primitive = unsigned usize,
+ SignedPrimitive = isize,
rot = 8,
rot_op = "0x10000b3",
rot_result = "0xb301",
@@ -2121,6 +2135,7 @@ nonzero_integer! {
nonzero_integer! {
Self = NonZeroUsize,
Primitive = unsigned usize,
+ SignedPrimitive = isize,
rot = 12,
rot_op = "0xaa00000000006e1",
rot_result = "0x6e10aa",
From bda6742797ada7b095697eb7d8671e2a7ac10731 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Rakic?=
Date: Mon, 3 Feb 2025 19:02:26 +0000
Subject: [PATCH 04/16] fix `crateresolve*.rs` tests and duplicates for compare
modes
- duplicates of crateresolve1 are used in a couple error-codes tests
- also fix the note in crateresolve1 to link to these other duplicates,
now that E0523 has been merged into E0464
---
tests/ui/crate-loading/crateresolve1.rs | 4 ++--
tests/ui/crate-loading/crateresolve2.rs | 2 +-
tests/ui/error-codes/E0464.rs | 2 +-
tests/ui/error-codes/E0523.rs | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/tests/ui/crate-loading/crateresolve1.rs b/tests/ui/crate-loading/crateresolve1.rs
index 9200b6a623140..91c34c82558ec 100644
--- a/tests/ui/crate-loading/crateresolve1.rs
+++ b/tests/ui/crate-loading/crateresolve1.rs
@@ -2,11 +2,11 @@
//@ aux-build:crateresolve1-2.rs
//@ aux-build:crateresolve1-3.rs
-//@ normalize-stderr: "\.nll/" -> "/"
+//@ normalize-stderr: "crateresolve1\..+/auxiliary/" -> "crateresolve1/auxiliary/"
//@ normalize-stderr: "\\\?\\" -> ""
//@ normalize-stderr: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib"
-// NOTE: This test is duplicated at `tests/ui/error-codes/E0464.rs`.
+// NOTE: This test is duplicated at `tests/ui/error-codes/E0464.rs` and `E0523.rs`.
extern crate crateresolve1;
//~^ ERROR multiple candidates for `rlib` dependency `crateresolve1` found
diff --git a/tests/ui/crate-loading/crateresolve2.rs b/tests/ui/crate-loading/crateresolve2.rs
index bec692eb8d2b9..6446740a32108 100644
--- a/tests/ui/crate-loading/crateresolve2.rs
+++ b/tests/ui/crate-loading/crateresolve2.rs
@@ -4,7 +4,7 @@
//@ aux-build:crateresolve2-2.rs
//@ aux-build:crateresolve2-3.rs
-//@ normalize-stderr: "\.nll/" -> "/"
+//@ normalize-stderr: "crateresolve2\..+/auxiliary/" -> "crateresolve2/auxiliary/"
//@ normalize-stderr: "\\\?\\" -> ""
extern crate crateresolve2;
diff --git a/tests/ui/error-codes/E0464.rs b/tests/ui/error-codes/E0464.rs
index aaf4d3a8f5007..d1303ae91b1d9 100644
--- a/tests/ui/error-codes/E0464.rs
+++ b/tests/ui/error-codes/E0464.rs
@@ -2,7 +2,7 @@
//@ aux-build:crateresolve1-2.rs
//@ aux-build:crateresolve1-3.rs
-//@ normalize-stderr: "\.nll/" -> "/"
+//@ normalize-stderr: "E0464\..+/auxiliary/" -> "E0464/auxiliary/"
//@ normalize-stderr: "\\\?\\" -> ""
//@ normalize-stderr: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib"
diff --git a/tests/ui/error-codes/E0523.rs b/tests/ui/error-codes/E0523.rs
index aaf4d3a8f5007..7c1869c055b22 100644
--- a/tests/ui/error-codes/E0523.rs
+++ b/tests/ui/error-codes/E0523.rs
@@ -2,7 +2,7 @@
//@ aux-build:crateresolve1-2.rs
//@ aux-build:crateresolve1-3.rs
-//@ normalize-stderr: "\.nll/" -> "/"
+//@ normalize-stderr: "E0523\..+/auxiliary/" -> "E0523/auxiliary/"
//@ normalize-stderr: "\\\?\\" -> ""
//@ normalize-stderr: "(lib)?crateresolve1-([123])\.[a-z]+" -> "libcrateresolve1-$2.somelib"
From 6825f176d657df5d73287c71421aef10c5b23e89 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Rakic?=
Date: Mon, 3 Feb 2025 19:08:21 +0000
Subject: [PATCH 05/16] fix normalization in `E0271` test for compare-modes
---
tests/ui/diagnostic-width/E0271.ascii.stderr | 2 +-
tests/ui/diagnostic-width/E0271.rs | 2 +-
tests/ui/diagnostic-width/E0271.unicode.stderr | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/tests/ui/diagnostic-width/E0271.ascii.stderr b/tests/ui/diagnostic-width/E0271.ascii.stderr
index 93555b336a66f..9a9c12a938f68 100644
--- a/tests/ui/diagnostic-width/E0271.ascii.stderr
+++ b/tests/ui/diagnostic-width/E0271.ascii.stderr
@@ -15,7 +15,7 @@ note: expected this to be `Foo`
LL | type Error = E;
| ^
= note: required for the cast from `Box>` to `Box<...>`
- = note: the full name for the type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271.ascii/E0271.long-type-hash.txt'
+ = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
= note: consider using `--verbose` to print the full type name to the console
error: aborting due to 1 previous error
diff --git a/tests/ui/diagnostic-width/E0271.rs b/tests/ui/diagnostic-width/E0271.rs
index 2faf09d46c6ea..0618772104143 100644
--- a/tests/ui/diagnostic-width/E0271.rs
+++ b/tests/ui/diagnostic-width/E0271.rs
@@ -1,7 +1,7 @@
//@ revisions: ascii unicode
//@[ascii] compile-flags: --diagnostic-width=40 -Zwrite-long-types-to-disk=yes
//@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40 -Zwrite-long-types-to-disk=yes
-//@ normalize-stderr: "long-type-\d+" -> "long-type-hash"
+//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
trait Future {
type Error;
}
diff --git a/tests/ui/diagnostic-width/E0271.unicode.stderr b/tests/ui/diagnostic-width/E0271.unicode.stderr
index 1e9acf603b2bd..9c3deae66608c 100644
--- a/tests/ui/diagnostic-width/E0271.unicode.stderr
+++ b/tests/ui/diagnostic-width/E0271.unicode.stderr
@@ -15,7 +15,7 @@ note: expected this to be `Foo`
LL │ type Error = E;
│ ━
├ note: required for the cast from `Box>` to `Box<...>`
- ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/diagnostic-width/E0271.unicode/E0271.long-type-hash.txt'
+ ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
╰ note: consider using `--verbose` to print the full type name to the console
error: aborting due to 1 previous error
From 62d0771ad43cd0b04e0d790dd64e35f702d4637a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9my=20Rakic?=
Date: Mon, 3 Feb 2025 19:15:37 +0000
Subject: [PATCH 06/16] fix `json-*.rs` and `E0462` tests for compare-modes
---
tests/ui/error-codes/E0462.rs | 2 +-
tests/ui/json/json-multiple.rs | 1 +
tests/ui/json/json-options.rs | 1 +
3 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/tests/ui/error-codes/E0462.rs b/tests/ui/error-codes/E0462.rs
index 12214331445ff..45d35c345cb5b 100644
--- a/tests/ui/error-codes/E0462.rs
+++ b/tests/ui/error-codes/E0462.rs
@@ -1,6 +1,6 @@
//@ aux-build:found-staticlib.rs
-//@ normalize-stderr: "\.nll/" -> "/"
+//@ normalize-stderr: "E0462\..+/auxiliary/" -> "E0462/auxiliary/"
//@ normalize-stderr: "\\\?\\" -> ""
//@ normalize-stderr: "(lib)?found_staticlib\.[a-z]+" -> "libfound_staticlib.somelib"
diff --git a/tests/ui/json/json-multiple.rs b/tests/ui/json/json-multiple.rs
index 296a60d24537b..8ad57939d5d16 100644
--- a/tests/ui/json/json-multiple.rs
+++ b/tests/ui/json/json-multiple.rs
@@ -1,5 +1,6 @@
//@ build-pass
//@ ignore-pass (different metadata emitted in different modes)
//@ compile-flags: --json=diagnostic-short --json artifacts --error-format=json
+//@ normalize-stderr: "json-multiple\..+/libjson_multiple.rlib" -> "json-multiple/libjson_multiple.rlib"
#![crate_type = "lib"]
diff --git a/tests/ui/json/json-options.rs b/tests/ui/json/json-options.rs
index 33df25e27b6a3..a6654bfcac6fa 100644
--- a/tests/ui/json/json-options.rs
+++ b/tests/ui/json/json-options.rs
@@ -1,5 +1,6 @@
//@ build-pass
//@ ignore-pass (different metadata emitted in different modes)
//@ compile-flags: --json=diagnostic-short,artifacts --error-format=json
+//@ normalize-stderr: "json-options\..+/libjson_options.rlib" -> "json-options/libjson_options.rlib"
#![crate_type = "lib"]
From f4a92e3262dbf98304758c5f778ddd6528b47f44 Mon Sep 17 00:00:00 2001
From: Josh Triplett
Date: Mon, 3 Feb 2025 16:55:34 +0100
Subject: [PATCH 07/16] Add `cast_signed` and `cast_unsigned` methods for
`NonZero` types
---
library/core/src/num/nonzero.rs | 47 +++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 3becbc9bade30..a115acf42b126 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -1626,6 +1626,29 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
// results will be sqrt(1), which is 1, so a result can't be zero.
unsafe { Self::new_unchecked(result) }
}
+
+ /// Returns the bit pattern of `self` reinterpreted as a signed integer of the same size.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(integer_sign_cast)]
+ /// # use std::num::NonZero;
+ ///
+ #[doc = concat!("let n = NonZero::<", stringify!($Int), ">::MAX;")]
+ ///
+ #[doc = concat!("assert_eq!(n.cast_signed(), NonZero::new(-1", stringify!($Sint), ").unwrap());")]
+ /// ```
+ #[unstable(feature = "integer_sign_cast", issue = "125882")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline(always)]
+ pub const fn cast_signed(self) -> NonZero<$Sint> {
+ // SAFETY: `self.get()` can't be zero
+ unsafe { NonZero::new_unchecked(self.get().cast_signed()) }
+ }
};
// Associated items for signed nonzero types only.
@@ -2042,6 +2065,30 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
// SAFETY: negation of nonzero cannot yield zero values.
unsafe { Self::new_unchecked(result) }
}
+
+ /// Returns the bit pattern of `self` reinterpreted as an unsigned integer of the same size.
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// #![feature(integer_sign_cast)]
+ /// # use std::num::NonZero;
+ ///
+ #[doc = concat!("let n = NonZero::new(-1", stringify!($Int), ").unwrap();")]
+ ///
+ #[doc = concat!("assert_eq!(n.cast_unsigned(), NonZero::<", stringify!($Uint), ">::MAX);")]
+ /// ```
+ #[unstable(feature = "integer_sign_cast", issue = "125882")]
+ #[must_use = "this returns the result of the operation, \
+ without modifying the original"]
+ #[inline(always)]
+ pub const fn cast_unsigned(self) -> NonZero<$Uint> {
+ // SAFETY: `self.get()` can't be zero
+ unsafe { NonZero::new_unchecked(self.get().cast_unsigned()) }
+ }
+
};
}
From 0825202cf296d319e9bbfdbf445723f92d618fc0 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote
Date: Mon, 3 Feb 2025 10:20:33 +1100
Subject: [PATCH 08/16] Remove unused features from `rustc_middle`.
---
compiler/rustc_middle/src/lib.rs | 2 --
1 file changed, 2 deletions(-)
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index bbe23d8abe8af..9d2aae1477b51 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -37,7 +37,6 @@
#![feature(box_as_ptr)]
#![feature(box_patterns)]
#![feature(closure_track_caller)]
-#![feature(const_type_name)]
#![feature(core_intrinsics)]
#![feature(coroutines)]
#![feature(debug_closure_helpers)]
@@ -50,7 +49,6 @@
#![feature(intra_doc_pointers)]
#![feature(iter_from_coroutine)]
#![feature(let_chains)]
-#![feature(macro_metavar_expr)]
#![feature(min_specialization)]
#![feature(negative_impls)]
#![feature(never_type)]
From 1fa9200475dae485dadf90845249f58395a33168 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote
Date: Sun, 2 Feb 2025 19:23:34 +1100
Subject: [PATCH 09/16] Remove `dep_node` comment duplication.
`rustc_middle` and `rustc_query_system` both have a file called
`dep_node.rs` with a big comment at the top, and the comments are very
similar. The one in `rustc_query_system` looks like the original, and
the one in `rustc_middle` is a copy with some improvements.
This commit removes the comment from `rustc_middle` and updates the one
in `rustc_query_system` to include the improvements. I did it this way
because `rustc_query_system` is the crate that defines `DepNode`, and so
seems like the right place for the comment.
---
.../rustc_middle/src/dep_graph/dep_node.rs | 58 -------------------
.../src/dep_graph/dep_node.rs | 39 ++++++++-----
2 files changed, 26 insertions(+), 71 deletions(-)
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index fcfc31575f8aa..9afba83a4f8dd 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -1,61 +1,3 @@
-//! Nodes in the dependency graph.
-//!
-//! A node in the [dependency graph] is represented by a [`DepNode`].
-//! A `DepNode` consists of a [`DepKind`] (which
-//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc.)
-//! and a [`Fingerprint`], a 128-bit hash value, the exact meaning of which
-//! depends on the node's `DepKind`. Together, the kind and the fingerprint
-//! fully identify a dependency node, even across multiple compilation sessions.
-//! In other words, the value of the fingerprint does not depend on anything
-//! that is specific to a given compilation session, like an unpredictable
-//! interning key (e.g., `NodeId`, `DefId`, `Symbol`) or the numeric value of a
-//! pointer. The concept behind this could be compared to how git commit hashes
-//! uniquely identify a given commit. The fingerprinting approach has
-//! a few advantages:
-//!
-//! * A `DepNode` can simply be serialized to disk and loaded in another session
-//! without the need to do any "rebasing" (like we have to do for Spans and
-//! NodeIds) or "retracing" (like we had to do for `DefId` in earlier
-//! implementations of the dependency graph).
-//! * A `Fingerprint` is just a bunch of bits, which allows `DepNode` to
-//! implement `Copy`, `Sync`, `Send`, `Freeze`, etc.
-//! * Since we just have a bit pattern, `DepNode` can be mapped from disk into
-//! memory without any post-processing (e.g., "abomination-style" pointer
-//! reconstruction).
-//! * Because a `DepNode` is self-contained, we can instantiate `DepNodes` that
-//! refer to things that do not exist anymore. In previous implementations
-//! `DepNode` contained a `DefId`. A `DepNode` referring to something that
-//! had been removed between the previous and the current compilation session
-//! could not be instantiated because the current compilation session
-//! contained no `DefId` for thing that had been removed.
-//!
-//! `DepNode` definition happens in the `define_dep_nodes!()` macro. This macro
-//! defines the `DepKind` enum. Each `DepKind` has its own parameters that are
-//! needed at runtime in order to construct a valid `DepNode` fingerprint.
-//! However, only `CompileCodegenUnit` and `CompileMonoItem` are constructed
-//! explicitly (with `make_compile_codegen_unit` cq `make_compile_mono_item`).
-//!
-//! Because the macro sees what parameters a given `DepKind` requires, it can
-//! "infer" some properties for each kind of `DepNode`:
-//!
-//! * Whether a `DepNode` of a given kind has any parameters at all. Some
-//! `DepNode`s could represent global concepts with only one value.
-//! * Whether it is possible, in principle, to reconstruct a query key from a
-//! given `DepNode`. Many `DepKind`s only require a single `DefId` parameter,
-//! in which case it is possible to map the node's fingerprint back to the
-//! `DefId` it was computed from. In other cases, too much information gets
-//! lost during fingerprint computation.
-//!
-//! `make_compile_codegen_unit` and `make_compile_mono_items`, together with
-//! `DepNode::new()`, ensures that only valid `DepNode` instances can be
-//! constructed. For example, the API does not allow for constructing
-//! parameterless `DepNode`s with anything other than a zeroed out fingerprint.
-//! More generally speaking, it relieves the user of the `DepNode` API of
-//! having to know how to compute the expected fingerprint for a given set of
-//! node parameters.
-//!
-//! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html
-
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId};
use rustc_hir::definitions::DefPathHash;
diff --git a/compiler/rustc_query_system/src/dep_graph/dep_node.rs b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
index 2902d17d68730..9d3368607a21c 100644
--- a/compiler/rustc_query_system/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_query_system/src/dep_graph/dep_node.rs
@@ -1,19 +1,20 @@
-//! This module defines the `DepNode` type which the compiler uses to represent
-//! nodes in the dependency graph. A `DepNode` consists of a `DepKind` (which
-//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc)
-//! and a `Fingerprint`, a 128 bit hash value the exact meaning of which
+//! This module defines the [`DepNode`] type which the compiler uses to represent
+//! nodes in the [dependency graph]. A `DepNode` consists of a [`DepKind`] (which
+//! specifies the kind of thing it represents, like a piece of HIR, MIR, etc.)
+//! and a [`Fingerprint`], a 128-bit hash value, the exact meaning of which
//! depends on the node's `DepKind`. Together, the kind and the fingerprint
//! fully identify a dependency node, even across multiple compilation sessions.
//! In other words, the value of the fingerprint does not depend on anything
//! that is specific to a given compilation session, like an unpredictable
-//! interning key (e.g., NodeId, DefId, Symbol) or the numeric value of a
+//! interning key (e.g., `NodeId`, `DefId`, `Symbol`) or the numeric value of a
//! pointer. The concept behind this could be compared to how git commit hashes
-//! uniquely identify a given commit and has a few advantages:
+//! uniquely identify a given commit. The fingerprinting approach has
+//! a few advantages:
//!
//! * A `DepNode` can simply be serialized to disk and loaded in another session
-//! without the need to do any "rebasing (like we have to do for Spans and
-//! NodeIds) or "retracing" like we had to do for `DefId` in earlier
-//! implementations of the dependency graph.
+//! without the need to do any "rebasing" (like we have to do for Spans and
+//! NodeIds) or "retracing" (like we had to do for `DefId` in earlier
+//! implementations of the dependency graph).
//! * A `Fingerprint` is just a bunch of bits, which allows `DepNode` to
//! implement `Copy`, `Sync`, `Send`, `Freeze`, etc.
//! * Since we just have a bit pattern, `DepNode` can be mapped from disk into
@@ -26,10 +27,12 @@
//! could not be instantiated because the current compilation session
//! contained no `DefId` for thing that had been removed.
//!
-//! `DepNode` definition happens in `rustc_middle` with the `define_dep_nodes!()` macro.
-//! This macro defines the `DepKind` enum and a corresponding `DepConstructor` enum. The
-//! `DepConstructor` enum links a `DepKind` to the parameters that are needed at runtime in order
-//! to construct a valid `DepNode` fingerprint.
+//! `DepNode` definition happens in `rustc_middle` with the
+//! `define_dep_nodes!()` macro. This macro defines the `DepKind` enum. Each
+//! `DepKind` has its own parameters that are needed at runtime in order to
+//! construct a valid `DepNode` fingerprint. However, only `CompileCodegenUnit`
+//! and `CompileMonoItem` are constructed explicitly (with
+//! `make_compile_codegen_unit` and `make_compile_mono_item`).
//!
//! Because the macro sees what parameters a given `DepKind` requires, it can
//! "infer" some properties for each kind of `DepNode`:
@@ -41,6 +44,16 @@
//! in which case it is possible to map the node's fingerprint back to the
//! `DefId` it was computed from. In other cases, too much information gets
//! lost during fingerprint computation.
+//!
+//! `make_compile_codegen_unit` and `make_compile_mono_items`, together with
+//! `DepNode::new()`, ensure that only valid `DepNode` instances can be
+//! constructed. For example, the API does not allow for constructing
+//! parameterless `DepNode`s with anything other than a zeroed out fingerprint.
+//! More generally speaking, it relieves the user of the `DepNode` API of
+//! having to know how to compute the expected fingerprint for a given set of
+//! node parameters.
+//!
+//! [dependency graph]: https://rustc-dev-guide.rust-lang.org/query.html
use std::fmt;
use std::hash::Hash;
From f89d509eb19d7f53cba39454a446b73d0ecc2fdb Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote
Date: Sun, 2 Feb 2025 19:36:16 +1100
Subject: [PATCH 10/16] Remove comment duplication.
The same comments are on the `DepNodeExt` trait and the single impl of
that trait, immediately below. This commit eliminates the duplication.
---
compiler/rustc_middle/src/dep_graph/dep_node.rs | 12 ------------
1 file changed, 12 deletions(-)
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index 9afba83a4f8dd..14c72a61acd91 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -100,26 +100,14 @@ pub(crate) fn make_compile_mono_item<'tcx>(
}
pub trait DepNodeExt: Sized {
- /// Extracts the DefId corresponding to this DepNode. This will work
- /// if two conditions are met:
- ///
- /// 1. The Fingerprint of the DepNode actually is a DefPathHash, and
- /// 2. the item that the DefPath refers to exists in the current tcx.
- ///
- /// Condition (1) is determined by the DepKind variant of the
- /// DepNode. Condition (2) might not be fulfilled if a DepNode
- /// refers to something from the previous compilation session that
- /// has been removed.
fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option;
- /// Used in testing
fn from_label_string(
tcx: TyCtxt<'_>,
label: &str,
def_path_hash: DefPathHash,
) -> Result;
- /// Used in testing
fn has_label_string(label: &str) -> bool;
}
From 6d03fa75192d4915c3b79ea2e4909aacd4881ebf Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote
Date: Sun, 2 Feb 2025 19:51:37 +1100
Subject: [PATCH 11/16] Remove `impl_for_typed_def_id` macro.
It has a single call site and removing it makes the code simpler.
Perhaps there were more uses at some point in the past?
---
.../rustc_middle/src/dep_graph/dep_node.rs | 76 +++++++++----------
1 file changed, 35 insertions(+), 41 deletions(-)
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index 14c72a61acd91..7525aeb922729 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -329,52 +329,46 @@ impl<'tcx> DepNodeParams> for HirId {
}
}
-macro_rules! impl_for_typed_def_id {
- ($Name:ident, $LocalName:ident) => {
- impl<'tcx> DepNodeParams> for $Name {
- #[inline(always)]
- fn fingerprint_style() -> FingerprintStyle {
- FingerprintStyle::DefPathHash
- }
+impl<'tcx> DepNodeParams> for ModDefId {
+ #[inline(always)]
+ fn fingerprint_style() -> FingerprintStyle {
+ FingerprintStyle::DefPathHash
+ }
- #[inline(always)]
- fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
- self.to_def_id().to_fingerprint(tcx)
- }
+ #[inline(always)]
+ fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
+ self.to_def_id().to_fingerprint(tcx)
+ }
- #[inline(always)]
- fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
- self.to_def_id().to_debug_str(tcx)
- }
+ #[inline(always)]
+ fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
+ self.to_def_id().to_debug_str(tcx)
+ }
- #[inline(always)]
- fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option {
- DefId::recover(tcx, dep_node).map($Name::new_unchecked)
- }
- }
+ #[inline(always)]
+ fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option {
+ DefId::recover(tcx, dep_node).map(ModDefId::new_unchecked)
+ }
+}
- impl<'tcx> DepNodeParams> for $LocalName {
- #[inline(always)]
- fn fingerprint_style() -> FingerprintStyle {
- FingerprintStyle::DefPathHash
- }
+impl<'tcx> DepNodeParams> for LocalModDefId {
+ #[inline(always)]
+ fn fingerprint_style() -> FingerprintStyle {
+ FingerprintStyle::DefPathHash
+ }
- #[inline(always)]
- fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
- self.to_def_id().to_fingerprint(tcx)
- }
+ #[inline(always)]
+ fn to_fingerprint(&self, tcx: TyCtxt<'tcx>) -> Fingerprint {
+ self.to_def_id().to_fingerprint(tcx)
+ }
- #[inline(always)]
- fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
- self.to_def_id().to_debug_str(tcx)
- }
+ #[inline(always)]
+ fn to_debug_str(&self, tcx: TyCtxt<'tcx>) -> String {
+ self.to_def_id().to_debug_str(tcx)
+ }
- #[inline(always)]
- fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option {
- LocalDefId::recover(tcx, dep_node).map($LocalName::new_unchecked)
- }
- }
- };
+ #[inline(always)]
+ fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option {
+ LocalDefId::recover(tcx, dep_node).map(LocalModDefId::new_unchecked)
+ }
}
-
-impl_for_typed_def_id! { ModDefId, LocalModDefId }
From 0be280e52f43b65e1f32b5f10687ce440f77070e Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote
Date: Mon, 3 Feb 2025 08:04:54 +1100
Subject: [PATCH 12/16] Simplify `thir_with_elements` macro.
The `field_name`/`field_ty` don't need to be parameters, they can be
hardcoded.
---
compiler/rustc_middle/src/thir.rs | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index d56046136c7a9..0236136af3f36 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -37,9 +37,6 @@ pub mod visit;
macro_rules! thir_with_elements {
(
- $($field_name:ident: $field_ty:ty,)*
-
- @elements:
$($name:ident: $id:ty => $value:ty => $format:literal,)*
) => {
$(
@@ -55,20 +52,16 @@ macro_rules! thir_with_elements {
/// This can be indexed directly by any THIR index (e.g. [`ExprId`]).
#[derive(Debug, HashStable, Clone)]
pub struct Thir<'tcx> {
- $(
- pub $field_name: $field_ty,
- )*
+ pub body_type: BodyTy<'tcx>,
$(
pub $name: IndexVec<$id, $value>,
)*
}
impl<'tcx> Thir<'tcx> {
- pub fn new($($field_name: $field_ty,)*) -> Thir<'tcx> {
+ pub fn new(body_type: BodyTy<'tcx>) -> Thir<'tcx> {
Thir {
- $(
- $field_name,
- )*
+ body_type,
$(
$name: IndexVec::new(),
)*
@@ -88,9 +81,6 @@ macro_rules! thir_with_elements {
}
thir_with_elements! {
- body_type: BodyTy<'tcx>,
-
-@elements:
arms: ArmId => Arm<'tcx> => "a{}",
blocks: BlockId => Block => "b{}",
exprs: ExprId => Expr<'tcx> => "e{}",
From bd6eb05ccd3eaff622992255144a55ddbaf328e2 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote
Date: Mon, 3 Feb 2025 08:20:34 +1100
Subject: [PATCH 13/16] Update top-level `rustc_middle` comment.
- Mention THIR.
- Removed mentions of non-existent READMEs.
---
compiler/rustc_middle/src/lib.rs | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index 9d2aae1477b51..7a6d329fd4753 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -1,10 +1,11 @@
//! The "main crate" of the Rust compiler. This crate contains common
//! type definitions that are used by the other crates in the rustc
-//! "family". Some prominent examples (note that each of these modules
-//! has their own README with further details).
+//! "family". The following are some prominent examples.
//!
//! - **HIR.** The "high-level (H) intermediate representation (IR)" is
//! defined in the [`hir`] module.
+//! - **THIR.** The "typed high-level (H) intermediate representation (IR)"
+//! is defined in the [`thir`] module.
//! - **MIR.** The "mid-level (M) intermediate representation (IR)" is
//! defined in the [`mir`] module. This module contains only the
//! *definition* of the MIR; the passes that transform and operate
From 6606bb35a97ebe14dab0ad51e234a3cd3c91fece Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote
Date: Mon, 3 Feb 2025 10:11:54 +1100
Subject: [PATCH 14/16] Fix an inconsistent import.
---
compiler/rustc_middle/src/thir/visit.rs | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index 2aeb13942a382..13b8af55e518e 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -1,8 +1,7 @@
use super::{
- AdtExpr, Arm, Block, ClosureExpr, Expr, ExprKind, InlineAsmExpr, InlineAsmOperand, Pat,
- PatKind, Stmt, StmtKind, Thir,
+ AdtExpr, AdtExprBase, Arm, Block, ClosureExpr, Expr, ExprKind, InlineAsmExpr, InlineAsmOperand,
+ Pat, PatKind, Stmt, StmtKind, Thir,
};
-use crate::thir::AdtExprBase;
pub trait Visitor<'thir, 'tcx: 'thir>: Sized {
fn thir(&self) -> &'thir Thir<'tcx>;
From d8d6128026cc09707b7520fda7d5669ad0833251 Mon Sep 17 00:00:00 2001
From: Nicholas Nethercote
Date: Mon, 3 Feb 2025 13:39:38 +1100
Subject: [PATCH 15/16] Two minor `use` fixups.
I *think* this addresses what the `FIXME` comments are asking for.
---
compiler/rustc_middle/src/traits/mod.rs | 3 +--
compiler/rustc_middle/src/traits/query.rs | 3 +--
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 28a6eba75aa56..d0ce4e6242ea6 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -21,13 +21,12 @@ use rustc_macros::{
};
use rustc_span::def_id::{CRATE_DEF_ID, LocalDefId};
use rustc_span::{DUMMY_SP, Span, Symbol};
-// FIXME: Remove this import and import via `solve::`
-pub use rustc_type_ir::solve::BuiltinImplSource;
use smallvec::{SmallVec, smallvec};
use thin_vec::ThinVec;
pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache};
use crate::mir::ConstraintCategory;
+pub use crate::traits::solve::BuiltinImplSource;
use crate::ty::abstract_const::NotConstEvaluatable;
use crate::ty::{self, AdtKind, GenericArgsRef, Ty};
diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs
index f049da95f29ae..8cd04a6f5e406 100644
--- a/compiler/rustc_middle/src/traits/query.rs
+++ b/compiler/rustc_middle/src/traits/query.rs
@@ -7,11 +7,10 @@
use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
use rustc_span::Span;
-// FIXME: Remove this import and import via `traits::solve`.
-pub use rustc_type_ir::solve::NoSolution;
use crate::error::DropCheckOverflow;
use crate::infer::canonical::{Canonical, CanonicalQueryInput, QueryResponse};
+pub use crate::traits::solve::NoSolution;
use crate::ty::{self, GenericArg, Ty, TyCtxt};
pub mod type_op {
From d47cb21188ad1356fa7305ab2b87a7108c86abcd Mon Sep 17 00:00:00 2001
From: Urgau
Date: Mon, 3 Feb 2025 23:59:43 +0100
Subject: [PATCH 16/16] Add note about `FnPtr` being exposed as public bound
---
library/core/src/marker.rs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 01af964a83e26..c99feaca055a4 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -1070,6 +1070,9 @@ marker_impls! {
}
/// A common trait implemented by all function pointers.
+//
+// Note that while the trait is internal and unstable it is nevertheless
+// exposed as a public bound of the stable `core::ptr::fn_addr_eq` function.
#[unstable(
feature = "fn_ptr_trait",
issue = "none",