Auto merge of #119955 - kamalesh0406:master, r=WaffleLapkin
Modify GenericArg and Term structs to use strict provenance rules This is the first PR to solve issue #119217 . In this PR, I have modified the GenericArg struct to use the `NonNull` struct as the pointer instead of `NonZeroUsize`. The change were tested by running `./x test compiler/rustc_middle`. Resolves https://github.com/rust-lang/rust/issues/119217 r? `@WaffleLapkin`
This commit is contained in:
commit
d93feccb35
@ -20,6 +20,7 @@
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
use std::ops::{ControlFlow, Deref};
|
use std::ops::{ControlFlow, Deref};
|
||||||
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
/// An entity in the Rust type system, which can be one of
|
/// An entity in the Rust type system, which can be one of
|
||||||
/// several kinds (types, lifetimes, and consts).
|
/// several kinds (types, lifetimes, and consts).
|
||||||
@ -31,10 +32,29 @@
|
|||||||
/// `Region` and `Const` are all interned.
|
/// `Region` and `Const` are all interned.
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct GenericArg<'tcx> {
|
pub struct GenericArg<'tcx> {
|
||||||
ptr: NonZeroUsize,
|
ptr: NonNull<()>,
|
||||||
marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>,
|
marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(parallel_compiler)]
|
||||||
|
unsafe impl<'tcx> rustc_data_structures::sync::DynSend for GenericArg<'tcx> where
|
||||||
|
&'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): rustc_data_structures::sync::DynSend
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#[cfg(parallel_compiler)]
|
||||||
|
unsafe impl<'tcx> rustc_data_structures::sync::DynSync for GenericArg<'tcx> where
|
||||||
|
&'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): rustc_data_structures::sync::DynSync
|
||||||
|
{
|
||||||
|
}
|
||||||
|
unsafe impl<'tcx> Send for GenericArg<'tcx> where
|
||||||
|
&'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): Send
|
||||||
|
{
|
||||||
|
}
|
||||||
|
unsafe impl<'tcx> Sync for GenericArg<'tcx> where
|
||||||
|
&'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): Sync
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> IntoDiagnosticArg for GenericArg<'tcx> {
|
impl<'tcx> IntoDiagnosticArg for GenericArg<'tcx> {
|
||||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||||
self.to_string().into_diagnostic_arg()
|
self.to_string().into_diagnostic_arg()
|
||||||
@ -60,21 +80,21 @@ fn pack(self) -> GenericArg<'tcx> {
|
|||||||
GenericArgKind::Lifetime(lt) => {
|
GenericArgKind::Lifetime(lt) => {
|
||||||
// Ensure we can use the tag bits.
|
// Ensure we can use the tag bits.
|
||||||
assert_eq!(mem::align_of_val(&*lt.0.0) & TAG_MASK, 0);
|
assert_eq!(mem::align_of_val(&*lt.0.0) & TAG_MASK, 0);
|
||||||
(REGION_TAG, lt.0.0 as *const ty::RegionKind<'tcx> as usize)
|
(REGION_TAG, NonNull::from(lt.0.0).cast())
|
||||||
}
|
}
|
||||||
GenericArgKind::Type(ty) => {
|
GenericArgKind::Type(ty) => {
|
||||||
// Ensure we can use the tag bits.
|
// Ensure we can use the tag bits.
|
||||||
assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
|
assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
|
||||||
(TYPE_TAG, ty.0.0 as *const WithCachedTypeInfo<ty::TyKind<'tcx>> as usize)
|
(TYPE_TAG, NonNull::from(ty.0.0).cast())
|
||||||
}
|
}
|
||||||
GenericArgKind::Const(ct) => {
|
GenericArgKind::Const(ct) => {
|
||||||
// Ensure we can use the tag bits.
|
// Ensure we can use the tag bits.
|
||||||
assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
|
assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
|
||||||
(CONST_TAG, ct.0.0 as *const WithCachedTypeInfo<ty::ConstData<'tcx>> as usize)
|
(CONST_TAG, NonNull::from(ct.0.0).cast())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
GenericArg { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData }
|
GenericArg { ptr: ptr.map_addr(|addr| addr | tag), marker: PhantomData }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,20 +143,22 @@ fn from(value: ty::Term<'tcx>) -> Self {
|
|||||||
impl<'tcx> GenericArg<'tcx> {
|
impl<'tcx> GenericArg<'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn unpack(self) -> GenericArgKind<'tcx> {
|
pub fn unpack(self) -> GenericArgKind<'tcx> {
|
||||||
let ptr = self.ptr.get();
|
let ptr = unsafe {
|
||||||
|
self.ptr.map_addr(|addr| NonZeroUsize::new_unchecked(addr.get() & !TAG_MASK))
|
||||||
|
};
|
||||||
// SAFETY: use of `Interned::new_unchecked` here is ok because these
|
// SAFETY: use of `Interned::new_unchecked` here is ok because these
|
||||||
// pointers were originally created from `Interned` types in `pack()`,
|
// pointers were originally created from `Interned` types in `pack()`,
|
||||||
// and this is just going in the other direction.
|
// and this is just going in the other direction.
|
||||||
unsafe {
|
unsafe {
|
||||||
match ptr & TAG_MASK {
|
match self.ptr.addr().get() & TAG_MASK {
|
||||||
REGION_TAG => GenericArgKind::Lifetime(ty::Region(Interned::new_unchecked(
|
REGION_TAG => GenericArgKind::Lifetime(ty::Region(Interned::new_unchecked(
|
||||||
&*((ptr & !TAG_MASK) as *const ty::RegionKind<'tcx>),
|
ptr.cast::<ty::RegionKind<'tcx>>().as_ref(),
|
||||||
))),
|
))),
|
||||||
TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked(
|
TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked(
|
||||||
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::TyKind<'tcx>>),
|
ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(),
|
||||||
))),
|
))),
|
||||||
CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked(
|
CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked(
|
||||||
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::ConstData<'tcx>>),
|
ptr.cast::<WithCachedTypeInfo<ty::ConstData<'tcx>>>().as_ref(),
|
||||||
))),
|
))),
|
||||||
_ => intrinsics::unreachable(),
|
_ => intrinsics::unreachable(),
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
use std::ops::ControlFlow;
|
use std::ops::ControlFlow;
|
||||||
|
use std::ptr::NonNull;
|
||||||
use std::{fmt, str};
|
use std::{fmt, str};
|
||||||
|
|
||||||
pub use crate::ty::diagnostics::*;
|
pub use crate::ty::diagnostics::*;
|
||||||
@ -848,10 +849,23 @@ pub struct CoercePredicate<'tcx> {
|
|||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct Term<'tcx> {
|
pub struct Term<'tcx> {
|
||||||
ptr: NonZeroUsize,
|
ptr: NonNull<()>,
|
||||||
marker: PhantomData<(Ty<'tcx>, Const<'tcx>)>,
|
marker: PhantomData<(Ty<'tcx>, Const<'tcx>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(parallel_compiler)]
|
||||||
|
unsafe impl<'tcx> rustc_data_structures::sync::DynSend for Term<'tcx> where
|
||||||
|
&'tcx (Ty<'tcx>, Const<'tcx>): rustc_data_structures::sync::DynSend
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#[cfg(parallel_compiler)]
|
||||||
|
unsafe impl<'tcx> rustc_data_structures::sync::DynSync for Term<'tcx> where
|
||||||
|
&'tcx (Ty<'tcx>, Const<'tcx>): rustc_data_structures::sync::DynSync
|
||||||
|
{
|
||||||
|
}
|
||||||
|
unsafe impl<'tcx> Send for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Send {}
|
||||||
|
unsafe impl<'tcx> Sync for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Sync {}
|
||||||
|
|
||||||
impl Debug for Term<'_> {
|
impl Debug for Term<'_> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
let data = if let Some(ty) = self.ty() {
|
let data = if let Some(ty) = self.ty() {
|
||||||
@ -914,17 +928,19 @@ fn decode(d: &mut D) -> Self {
|
|||||||
impl<'tcx> Term<'tcx> {
|
impl<'tcx> Term<'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn unpack(self) -> TermKind<'tcx> {
|
pub fn unpack(self) -> TermKind<'tcx> {
|
||||||
let ptr = self.ptr.get();
|
let ptr = unsafe {
|
||||||
|
self.ptr.map_addr(|addr| NonZeroUsize::new_unchecked(addr.get() & !TAG_MASK))
|
||||||
|
};
|
||||||
// SAFETY: use of `Interned::new_unchecked` here is ok because these
|
// SAFETY: use of `Interned::new_unchecked` here is ok because these
|
||||||
// pointers were originally created from `Interned` types in `pack()`,
|
// pointers were originally created from `Interned` types in `pack()`,
|
||||||
// and this is just going in the other direction.
|
// and this is just going in the other direction.
|
||||||
unsafe {
|
unsafe {
|
||||||
match ptr & TAG_MASK {
|
match self.ptr.addr().get() & TAG_MASK {
|
||||||
TYPE_TAG => TermKind::Ty(Ty(Interned::new_unchecked(
|
TYPE_TAG => TermKind::Ty(Ty(Interned::new_unchecked(
|
||||||
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::TyKind<'tcx>>),
|
ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(),
|
||||||
))),
|
))),
|
||||||
CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked(
|
CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked(
|
||||||
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::ConstData<'tcx>>),
|
ptr.cast::<WithCachedTypeInfo<ty::ConstData<'tcx>>>().as_ref(),
|
||||||
))),
|
))),
|
||||||
_ => core::intrinsics::unreachable(),
|
_ => core::intrinsics::unreachable(),
|
||||||
}
|
}
|
||||||
@ -986,16 +1002,16 @@ fn pack(self) -> Term<'tcx> {
|
|||||||
TermKind::Ty(ty) => {
|
TermKind::Ty(ty) => {
|
||||||
// Ensure we can use the tag bits.
|
// Ensure we can use the tag bits.
|
||||||
assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
|
assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
|
||||||
(TYPE_TAG, ty.0.0 as *const WithCachedTypeInfo<ty::TyKind<'tcx>> as usize)
|
(TYPE_TAG, NonNull::from(ty.0.0).cast())
|
||||||
}
|
}
|
||||||
TermKind::Const(ct) => {
|
TermKind::Const(ct) => {
|
||||||
// Ensure we can use the tag bits.
|
// Ensure we can use the tag bits.
|
||||||
assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
|
assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
|
||||||
(CONST_TAG, ct.0.0 as *const WithCachedTypeInfo<ty::ConstData<'tcx>> as usize)
|
(CONST_TAG, NonNull::from(ct.0.0).cast())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Term { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData }
|
Term { ptr: ptr.map_addr(|addr| addr | tag), marker: PhantomData }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user