Skip to content

Commit dcc13b2

Browse files
committed
Modify GenericArg and Term structs to use strict provenance rules
1 parent 6ae4cfb commit dcc13b2

File tree

2 files changed

+52
-18
lines changed

2 files changed

+52
-18
lines changed

compiler/rustc_middle/src/ty/generic_args.rs

+33-10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::ty::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor};
77
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
88

99
use rustc_data_structures::intern::Interned;
10+
use rustc_data_structures::sync::{DynSend, DynSync};
1011
use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
1112
use rustc_hir::def_id::DefId;
1213
use rustc_macros::HashStable;
@@ -20,6 +21,7 @@ use std::marker::PhantomData;
2021
use std::mem;
2122
use std::num::NonZeroUsize;
2223
use std::ops::{ControlFlow, Deref};
24+
use std::ptr::NonNull;
2325

2426
/// An entity in the Rust type system, which can be one of
2527
/// several kinds (types, lifetimes, and consts).
@@ -31,10 +33,29 @@ use std::ops::{ControlFlow, Deref};
3133
/// `Region` and `Const` are all interned.
3234
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
3335
pub struct GenericArg<'tcx> {
34-
ptr: NonZeroUsize,
36+
ptr: NonNull<()>,
3537
marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>,
3638
}
3739

40+
#[cfg(parallel_compiler)]
41+
unsafe impl<'tcx> DynSend for GenericArg<'tcx> where
42+
&'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): DynSend
43+
{
44+
}
45+
#[cfg(parallel_compiler)]
46+
unsafe impl<'tcx> DynSync for GenericArg<'tcx> where
47+
&'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): DynSync
48+
{
49+
}
50+
unsafe impl<'tcx> Send for GenericArg<'tcx> where
51+
&'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): Send
52+
{
53+
}
54+
unsafe impl<'tcx> Sync for GenericArg<'tcx> where
55+
&'tcx (Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>): Sync
56+
{
57+
}
58+
3859
impl<'tcx> IntoDiagnosticArg for GenericArg<'tcx> {
3960
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
4061
self.to_string().into_diagnostic_arg()
@@ -60,21 +81,21 @@ impl<'tcx> GenericArgKind<'tcx> {
6081
GenericArgKind::Lifetime(lt) => {
6182
// Ensure we can use the tag bits.
6283
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)
84+
(REGION_TAG, NonNull::from(lt.0.0).cast())
6485
}
6586
GenericArgKind::Type(ty) => {
6687
// Ensure we can use the tag bits.
6788
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)
89+
(TYPE_TAG, NonNull::from(ty.0.0).cast())
6990
}
7091
GenericArgKind::Const(ct) => {
7192
// Ensure we can use the tag bits.
7293
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)
94+
(CONST_TAG, NonNull::from(ct.0.0).cast())
7495
}
7596
};
7697

77-
GenericArg { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData }
98+
GenericArg { ptr: ptr.map_addr(|addr| addr | tag), marker: PhantomData }
7899
}
79100
}
80101

@@ -123,20 +144,22 @@ impl<'tcx> From<ty::Term<'tcx>> for GenericArg<'tcx> {
123144
impl<'tcx> GenericArg<'tcx> {
124145
#[inline]
125146
pub fn unpack(self) -> GenericArgKind<'tcx> {
126-
let ptr = self.ptr.get();
147+
let ptr = unsafe {
148+
self.ptr.map_addr(|addr| NonZeroUsize::new_unchecked(addr.get() & !TAG_MASK))
149+
};
127150
// SAFETY: use of `Interned::new_unchecked` here is ok because these
128151
// pointers were originally created from `Interned` types in `pack()`,
129152
// and this is just going in the other direction.
130153
unsafe {
131-
match ptr & TAG_MASK {
154+
match self.ptr.addr().get() & TAG_MASK {
132155
REGION_TAG => GenericArgKind::Lifetime(ty::Region(Interned::new_unchecked(
133-
&*((ptr & !TAG_MASK) as *const ty::RegionKind<'tcx>),
156+
ptr.cast::<ty::RegionKind<'tcx>>().as_ref(),
134157
))),
135158
TYPE_TAG => GenericArgKind::Type(Ty(Interned::new_unchecked(
136-
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::TyKind<'tcx>>),
159+
ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(),
137160
))),
138161
CONST_TAG => GenericArgKind::Const(ty::Const(Interned::new_unchecked(
139-
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::ConstData<'tcx>>),
162+
ptr.cast::<WithCachedTypeInfo<ty::ConstData<'tcx>>>().as_ref(),
140163
))),
141164
_ => intrinsics::unreachable(),
142165
}

compiler/rustc_middle/src/ty/mod.rs

+19-8
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
3737
use rustc_data_structures::intern::Interned;
3838
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
3939
use rustc_data_structures::steal::Steal;
40+
use rustc_data_structures::sync::{DynSend, DynSync};
4041
use rustc_data_structures::tagged_ptr::CopyTaggedPtr;
4142
use rustc_data_structures::unord::UnordMap;
4243
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, StashKey};
@@ -63,6 +64,7 @@ use std::marker::PhantomData;
6364
use std::mem;
6465
use std::num::NonZeroUsize;
6566
use std::ops::ControlFlow;
67+
use std::ptr::NonNull;
6668
use std::{fmt, str};
6769

6870
pub use crate::ty::diagnostics::*;
@@ -848,10 +850,17 @@ pub type PolyCoercePredicate<'tcx> = ty::Binder<'tcx, CoercePredicate<'tcx>>;
848850

849851
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
850852
pub struct Term<'tcx> {
851-
ptr: NonZeroUsize,
853+
ptr: NonNull<()>,
852854
marker: PhantomData<(Ty<'tcx>, Const<'tcx>)>,
853855
}
854856

857+
#[cfg(parallel_compiler)]
858+
unsafe impl<'tcx> DynSend for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): DynSend {}
859+
#[cfg(parallel_compiler)]
860+
unsafe impl<'tcx> DynSync for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): DynSync {}
861+
unsafe impl<'tcx> Send for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Send {}
862+
unsafe impl<'tcx> Sync for Term<'tcx> where &'tcx (Ty<'tcx>, Const<'tcx>): Sync {}
863+
855864
impl Debug for Term<'_> {
856865
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
857866
let data = if let Some(ty) = self.ty() {
@@ -914,17 +923,19 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for Term<'tcx> {
914923
impl<'tcx> Term<'tcx> {
915924
#[inline]
916925
pub fn unpack(self) -> TermKind<'tcx> {
917-
let ptr = self.ptr.get();
926+
let ptr = unsafe {
927+
self.ptr.map_addr(|addr| NonZeroUsize::new_unchecked(addr.get() & !TAG_MASK))
928+
};
918929
// SAFETY: use of `Interned::new_unchecked` here is ok because these
919930
// pointers were originally created from `Interned` types in `pack()`,
920931
// and this is just going in the other direction.
921932
unsafe {
922-
match ptr & TAG_MASK {
933+
match self.ptr.addr().get() & TAG_MASK {
923934
TYPE_TAG => TermKind::Ty(Ty(Interned::new_unchecked(
924-
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::TyKind<'tcx>>),
935+
ptr.cast::<WithCachedTypeInfo<ty::TyKind<'tcx>>>().as_ref(),
925936
))),
926937
CONST_TAG => TermKind::Const(ty::Const(Interned::new_unchecked(
927-
&*((ptr & !TAG_MASK) as *const WithCachedTypeInfo<ty::ConstData<'tcx>>),
938+
ptr.cast::<WithCachedTypeInfo<ty::ConstData<'tcx>>>().as_ref(),
928939
))),
929940
_ => core::intrinsics::unreachable(),
930941
}
@@ -986,16 +997,16 @@ impl<'tcx> TermKind<'tcx> {
986997
TermKind::Ty(ty) => {
987998
// Ensure we can use the tag bits.
988999
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)
1000+
(TYPE_TAG, NonNull::from(ty.0.0).cast())
9901001
}
9911002
TermKind::Const(ct) => {
9921003
// Ensure we can use the tag bits.
9931004
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)
1005+
(CONST_TAG, NonNull::from(ct.0.0).cast())
9951006
}
9961007
};
9971008

998-
Term { ptr: unsafe { NonZeroUsize::new_unchecked(ptr | tag) }, marker: PhantomData }
1009+
Term { ptr: ptr.map_addr(|addr| addr | tag), marker: PhantomData }
9991010
}
10001011
}
10011012

0 commit comments

Comments
 (0)