diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs index fcfc31575f8aa..7525aeb922729 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; @@ -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; - /// 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; } @@ -399,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 } diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index bbe23d8abe8af..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 @@ -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)] diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index 5490f1f53ea14..e2e2029a362bb 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)] 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{}", 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>; 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 { 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; 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")] diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs index 18ada14d101b5..1a8ef20dd7b9d 100644 --- a/library/core/src/marker.rs +++ b/library/core/src/marker.rs @@ -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", diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 61e83ebfad7de..a115acf42b126 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 @@ -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", 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")] 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/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 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/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" 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"]