Skip to content

Rollup of 6 pull requests #136534

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 22 commits into from
Feb 4, 2025
Merged
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
670d892
add UnsafeCell direct access APIs
pitaj Feb 1, 2025
49ea67a
std::fs: further simplify dirent64 handling
RalfJung Feb 3, 2025
37c77de
For NonZero impl macros, give unsigned impls access to the correspond…
joshtriplett Feb 3, 2025
bda6742
fix `crateresolve*.rs` tests and duplicates for compare modes
lqd Feb 3, 2025
6825f17
fix normalization in `E0271` test for compare-modes
lqd Feb 3, 2025
62d0771
fix `json-*.rs` and `E0462` tests for compare-modes
lqd Feb 3, 2025
f4a92e3
Add `cast_signed` and `cast_unsigned` methods for `NonZero` types
joshtriplett Feb 3, 2025
0825202
Remove unused features from `rustc_middle`.
nnethercote Feb 2, 2025
1fa9200
Remove `dep_node` comment duplication.
nnethercote Feb 2, 2025
f89d509
Remove comment duplication.
nnethercote Feb 2, 2025
6d03fa7
Remove `impl_for_typed_def_id` macro.
nnethercote Feb 2, 2025
0be280e
Simplify `thir_with_elements` macro.
nnethercote Feb 2, 2025
bd6eb05
Update top-level `rustc_middle` comment.
nnethercote Feb 2, 2025
6606bb3
Fix an inconsistent import.
nnethercote Feb 2, 2025
d8d6128
Two minor `use` fixups.
nnethercote Feb 3, 2025
d47cb21
Add note about `FnPtr` being exposed as public bound
Urgau Feb 3, 2025
d89e98d
Rollup merge of #136398 - pitaj:unsafecell_access, r=dtolnay
jhpratt Feb 4, 2025
87af17c
Rollup merge of #136465 - nnethercote:rustc_middle-MORE, r=jieyouxu
jhpratt Feb 4, 2025
1baf59e
Rollup merge of #136479 - RalfJung:dirent64, r=tgross35
jhpratt Feb 4, 2025
9d563bb
Rollup merge of #136504 - lqd:more-compare-modes, r=jieyouxu
jhpratt Feb 4, 2025
5178a36
Rollup merge of #136511 - joshtriplett:nonzero-cast-signed-unsigned, …
jhpratt Feb 4, 2025
af178aa
Rollup merge of #136518 - Urgau:fn_ptr-public-bound, r=Noratrieb
jhpratt Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
146 changes: 35 additions & 111 deletions compiler/rustc_middle/src/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
@@ -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;
@@ -158,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<DefId>;

/// Used in testing
fn from_label_string(
tcx: TyCtxt<'_>,
label: &str,
def_path_hash: DefPathHash,
) -> Result<Self, ()>;

/// Used in testing
fn has_label_string(label: &str) -> bool;
}

@@ -399,52 +329,46 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
}
}

macro_rules! impl_for_typed_def_id {
($Name:ident, $LocalName:ident) => {
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for $Name {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::DefPathHash
}
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> 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<Self> {
DefId::recover(tcx, dep_node).map($Name::new_unchecked)
}
}
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
DefId::recover(tcx, dep_node).map(ModDefId::new_unchecked)
}
}

impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for $LocalName {
#[inline(always)]
fn fingerprint_style() -> FingerprintStyle {
FingerprintStyle::DefPathHash
}
impl<'tcx> DepNodeParams<TyCtxt<'tcx>> 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<Self> {
LocalDefId::recover(tcx, dep_node).map($LocalName::new_unchecked)
}
}
};
#[inline(always)]
fn recover(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> Option<Self> {
LocalDefId::recover(tcx, dep_node).map(LocalModDefId::new_unchecked)
}
}

impl_for_typed_def_id! { ModDefId, LocalModDefId }
7 changes: 3 additions & 4 deletions compiler/rustc_middle/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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
@@ -37,7 +38,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 +50,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)]
16 changes: 3 additions & 13 deletions compiler/rustc_middle/src/thir.rs
Original file line number Diff line number Diff line change
@@ -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)]
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{}",
5 changes: 2 additions & 3 deletions compiler/rustc_middle/src/thir/visit.rs
Original file line number Diff line number Diff line change
@@ -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>;
3 changes: 1 addition & 2 deletions compiler/rustc_middle/src/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -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};

3 changes: 1 addition & 2 deletions compiler/rustc_middle/src/traits/query.rs
Original file line number Diff line number Diff line change
@@ -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 {
39 changes: 26 additions & 13 deletions compiler/rustc_query_system/src/dep_graph/dep_node.rs
Original file line number Diff line number Diff line change
@@ -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;
84 changes: 84 additions & 0 deletions library/core/src/cell.rs
Original file line number Diff line number Diff line change
@@ -2118,6 +2118,35 @@ impl<T> UnsafeCell<T> {
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<T: ?Sized> UnsafeCell<T> {
@@ -2230,6 +2259,61 @@ impl<T: ?Sized> UnsafeCell<T> {
// 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")]
3 changes: 3 additions & 0 deletions library/core/src/marker.rs
Original file line number Diff line number Diff line change
@@ -1077,6 +1077,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",
66 changes: 64 additions & 2 deletions library/core/src/num/nonzero.rs
Original file line number Diff line number Diff line change
@@ -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
@@ -1620,11 +1626,35 @@ 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.
(
Primitive = signed $Int:ident,
SignedPrimitive = $Sint:ty,
UnsignedPrimitive = $Uint:ty,
) => {
/// The smallest value that can be represented by this non-zero
@@ -2035,12 +2065,37 @@ 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()) }
}

};
}

nonzero_integer! {
Self = NonZeroU8,
Primitive = unsigned u8,
SignedPrimitive = i8,
rot = 2,
rot_op = "0x82",
rot_result = "0xa",
@@ -2052,6 +2107,7 @@ nonzero_integer! {
nonzero_integer! {
Self = NonZeroU16,
Primitive = unsigned u16,
SignedPrimitive = i16,
rot = 4,
rot_op = "0xa003",
rot_result = "0x3a",
@@ -2063,6 +2119,7 @@ nonzero_integer! {
nonzero_integer! {
Self = NonZeroU32,
Primitive = unsigned u32,
SignedPrimitive = i32,
rot = 8,
rot_op = "0x10000b3",
rot_result = "0xb301",
@@ -2074,6 +2131,7 @@ nonzero_integer! {
nonzero_integer! {
Self = NonZeroU64,
Primitive = unsigned u64,
SignedPrimitive = i64,
rot = 12,
rot_op = "0xaa00000000006e1",
rot_result = "0x6e10aa",
@@ -2085,6 +2143,7 @@ nonzero_integer! {
nonzero_integer! {
Self = NonZeroU128,
Primitive = unsigned u128,
SignedPrimitive = i128,
rot = 16,
rot_op = "0x13f40000000000000000000000004f76",
rot_result = "0x4f7613f4",
@@ -2097,6 +2156,7 @@ nonzero_integer! {
nonzero_integer! {
Self = NonZeroUsize,
Primitive = unsigned usize,
SignedPrimitive = isize,
rot = 4,
rot_op = "0xa003",
rot_result = "0x3a",
@@ -2109,6 +2169,7 @@ nonzero_integer! {
nonzero_integer! {
Self = NonZeroUsize,
Primitive = unsigned usize,
SignedPrimitive = isize,
rot = 8,
rot_op = "0x10000b3",
rot_result = "0xb301",
@@ -2121,6 +2182,7 @@ nonzero_integer! {
nonzero_integer! {
Self = NonZeroUsize,
Primitive = unsigned usize,
SignedPrimitive = isize,
rot = 12,
rot_op = "0xaa00000000006e1",
rot_result = "0x6e10aa",
14 changes: 6 additions & 8 deletions library/std/src/sys/pal/unix/fs.rs
Original file line number Diff line number Diff line change
@@ -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")]
4 changes: 2 additions & 2 deletions tests/ui/crate-loading/crateresolve1.rs
Original file line number Diff line number Diff line change
@@ -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
2 changes: 1 addition & 1 deletion tests/ui/crate-loading/crateresolve2.rs
Original file line number Diff line number Diff line change
@@ -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;
2 changes: 1 addition & 1 deletion tests/ui/diagnostic-width/E0271.ascii.stderr
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ note: expected this to be `Foo`
LL | type Error = E;
| ^
= note: required for the cast from `Box<Result<..., ()>>` 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
2 changes: 1 addition & 1 deletion tests/ui/diagnostic-width/E0271.rs
Original file line number Diff line number Diff line change
@@ -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;
}
2 changes: 1 addition & 1 deletion tests/ui/diagnostic-width/E0271.unicode.stderr
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ note: expected this to be `Foo`
LL │ type Error = E;
│ ━
├ note: required for the cast from `Box<Result<..., ()>>` 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
2 changes: 1 addition & 1 deletion tests/ui/error-codes/E0462.rs
Original file line number Diff line number Diff line change
@@ -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"

2 changes: 1 addition & 1 deletion tests/ui/error-codes/E0464.rs
Original file line number Diff line number Diff line change
@@ -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"

2 changes: 1 addition & 1 deletion tests/ui/error-codes/E0523.rs
Original file line number Diff line number Diff line change
@@ -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"

1 change: 1 addition & 0 deletions tests/ui/json/json-multiple.rs
Original file line number Diff line number Diff line change
@@ -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"]
1 change: 1 addition & 0 deletions tests/ui/json/json-options.rs
Original file line number Diff line number Diff line change
@@ -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"]