Skip to content

Commit d93fecc

Browse files
committed
Auto merge of rust-lang#119955 - kamalesh0406:master, r=WaffleLapkin
Modify GenericArg and Term structs to use strict provenance rules This is the first PR to solve issue rust-lang#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 rust-lang#119217 r? `@WaffleLapkin`
2 parents 039d887 + d0dea83 commit d93fecc

File tree

2 files changed

+56
-18
lines changed

2 files changed

+56
-18
lines changed

compiler/rustc_middle/src/ty/generic_args.rs

+32-10
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use std::marker::PhantomData;
2020
use std::mem;
2121
use std::num::NonZeroUsize;
2222
use std::ops::{ControlFlow, Deref};
23+
use std::ptr::NonNull;
2324

2425
/// An entity in the Rust type system, which can be one of
2526
/// several kinds (types, lifetimes, and consts).
@@ -31,10 +32,29 @@ use std::ops::{ControlFlow, Deref};
3132
/// `Region` and `Const` are all interned.
3233
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
3334
pub struct GenericArg<'tcx> {
34-
ptr: NonZeroUsize,
35+
ptr: NonNull<()>,
3536
marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>,
3637
}
3738

39+
#[cfg(parallel_compiler)]
40+
unsafe impl<'tcx> rustc_data_structures::sync::DynSend for GenericArg<'tcx> where
41+
&'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): rustc_data_structures::sync::DynSend
42+
{
43+
}
44+
#[cfg(parallel_compiler)]
45+
unsafe impl<'tcx> rustc_data_structures::sync::DynSync for GenericArg<'tcx> where
46+
&'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): rustc_data_structures::sync::DynSync
47+
{
48+
}
49+
unsafe impl<'tcx> Send for GenericArg<'tcx> where
50+
&'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): Send
51+
{
52+
}
53+
unsafe impl<'tcx> Sync for GenericArg<'tcx> where
54+
&'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): Sync
55+
{
56+
}
57+
3858
impl<'tcx> IntoDiagnosticArg for GenericArg<'tcx> {
3959
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
4060
self.to_string().into_diagnostic_arg()
@@ -60,21 +80,21 @@ impl<'tcx> GenericArgKind<'tcx> {
6080
GenericArgKind::Lifetime(lt) => {
6181
// Ensure we can use the tag bits.
6282
assert_eq!(mem::align_of_val(&*lt.0.0) & TAG_MASK, 0);
63-
(REGION_TAG, lt.0.0 as *const ty::RegionKind<'tcx> as usize)
83+
(REGION_TAG, NonNull::from(lt.0.0).cast())
6484
}
6585
GenericArgKind::Type(ty) => {
6686
// Ensure we can use the tag bits.
6787
assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
68-
(TYPE_TAG, ty.0.0 as *const WithCachedTypeInfo<ty::TyKind<'tcx>> as usize)
88+
(TYPE_TAG, NonNull::from(ty.0.0).cast())
6989
}
7090
GenericArgKind::Const(ct) => {
7191
// Ensure we can use the tag bits.
7292
assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
73-
(CONST_TAG, ct.0.0 as *const WithCachedTypeInfo<ty::ConstData<'tcx>> as usize)
93+
(CONST_TAG, NonNull::from(ct.0.0).cast())
7494
}
7595
};
7696

77-
GenericArg { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData }
97+
GenericArg { ptr: ptr.map_addr(|addr| addr | tag), marker: PhantomData }
7898
}
7999
}
80100

@@ -123,20 +143,22 @@ impl<'tcx> From<ty::Term<'tcx>> for GenericArg<'tcx> {
123143
impl<'tcx> GenericArg<'tcx> {
124144
#[inline]
125145
pub fn unpack(self) -> GenericArgKind<'tcx> {
126-
let ptr = self.ptr.get();
146+
let ptr = unsafe {
147+
self.ptr.map_addr(|addr| NonZeroUsize::new_unchecked(addr.get() & !TAG_MASK))
148+
};
127149
// SAFETY: use of `Interned::new_unchecked` here is ok because these
128150
// pointers were originally created from `Interned` types in `pack()`,
129151
// and this is just going in the other direction.
130152
unsafe {
131-
match ptr & TAG_MASK {
153+
match self.ptr.addr().get() & TAG_MASK {
132154
REGION_TAG => GenericArgKind::Lifetime(ty::Region(Interned::new_unchecked(
133-
&*((ptr & !TAG_MASK) as *const ty::RegionKind<'tcx>),
155+
ptr.cast::<ty::RegionKind<'tcx>>().as_ref(),
134156
))),
135157
TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked(
136-
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::TyKind<'tcx>>),
158+
ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(),
137159
))),
138160
CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked(
139-
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::ConstData<'tcx>>),
161+
ptr.cast::<WithCachedTypeInfo<ty::ConstData<'tcx>>>().as_ref(),
140162
))),
141163
_ => intrinsics::unreachable(),
142164
}

compiler/rustc_middle/src/ty/mod.rs

+24-8
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ use std::marker::PhantomData;
6363
use std::mem;
6464
use std::num::NonZeroUsize;
6565
use std::ops::ControlFlow;
66+
use std::ptr::NonNull;
6667
use std::{fmt, str};
6768

6869
pub use crate::ty::diagnostics::*;
@@ -848,10 +849,23 @@ pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
848849

849850
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
850851
pub struct Term<'tcx> {
851-
ptr: NonZeroUsize,
852+
ptr: NonNull<()>,
852853
marker: PhantomData<(Ty<'tcx>, Const<'tcx>)>,
853854
}
854855

856+
#[cfg(parallel_compiler)]
857+
unsafe impl<'tcx> rustc_data_structures::sync::DynSend for Term<'tcx> where
858+
&'tcx (Ty<'tcx>, Const<'tcx>): rustc_data_structures::sync::DynSend
859+
{
860+
}
861+
#[cfg(parallel_compiler)]
862+
unsafe impl<'tcx> rustc_data_structures::sync::DynSync for Term<'tcx> where
863+
&'tcx (Ty<'tcx>, Const<'tcx>): rustc_data_structures::sync::DynSync
864+
{
865+
}
866+
unsafe impl<'tcx> Send for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Send {}
867+
unsafe impl<'tcx> Sync for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Sync {}
868+
855869
impl Debug for Term<'_> {
856870
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
857871
let data = if let Some(ty) = self.ty() {
@@ -914,17 +928,19 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for Term<'tcx> {
914928
impl<'tcx> Term<'tcx> {
915929
#[inline]
916930
pub fn unpack(self) -> TermKind<'tcx> {
917-
let ptr = self.ptr.get();
931+
let ptr = unsafe {
932+
self.ptr.map_addr(|addr| NonZeroUsize::new_unchecked(addr.get() & !TAG_MASK))
933+
};
918934
// SAFETY: use of `Interned::new_unchecked` here is ok because these
919935
// pointers were originally created from `Interned` types in `pack()`,
920936
// and this is just going in the other direction.
921937
unsafe {
922-
match ptr & TAG_MASK {
938+
match self.ptr.addr().get() & TAG_MASK {
923939
TYPE_TAG => TermKind::Ty(Ty(Interned::new_unchecked(
924-
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::TyKind<'tcx>>),
940+
ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(),
925941
))),
926942
CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked(
927-
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::ConstData<'tcx>>),
943+
ptr.cast::<WithCachedTypeInfo<ty::ConstData<'tcx>>>().as_ref(),
928944
))),
929945
_ => core::intrinsics::unreachable(),
930946
}
@@ -986,16 +1002,16 @@ impl<'tcx> TermKind<'tcx> {
9861002
TermKind::Ty(ty) => {
9871003
// Ensure we can use the tag bits.
9881004
assert_eq!(mem::align_of_val(&*ty.0.0) & TAG_MASK, 0);
989-
(TYPE_TAG, ty.0.0 as *const WithCachedTypeInfo<ty::TyKind<'tcx>> as usize)
1005+
(TYPE_TAG, NonNull::from(ty.0.0).cast())
9901006
}
9911007
TermKind::Const(ct) => {
9921008
// Ensure we can use the tag bits.
9931009
assert_eq!(mem::align_of_val(&*ct.0.0) & TAG_MASK, 0);
994-
(CONST_TAG, ct.0.0 as *const WithCachedTypeInfo<ty::ConstData<'tcx>> as usize)
1010+
(CONST_TAG, NonNull::from(ct.0.0).cast())
9951011
}
9961012
};
9971013

998-
Term { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData }
1014+
Term { ptr: ptr.map_addr(|addr| addr | tag), marker: PhantomData }
9991015
}
10001016
}
10011017

0 commit comments

Comments
 (0)