@@ -7,6 +7,7 @@ use crate::ty::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor};
7
7
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
8
8
9
9
use rustc_data_structures::intern::Interned;
10
+ use rustc_data_structures::sync::{DynSend, DynSync};
10
11
use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
11
12
use rustc_hir::def_id::DefId;
12
13
use rustc_macros::HashStable;
@@ -20,6 +21,7 @@ use std::marker::PhantomData;
20
21
use std::mem;
21
22
use std::num::NonZeroUsize;
22
23
use std::ops::{ControlFlow, Deref};
24
+ use std::ptr::NonNull;
23
25
24
26
/// An entity in the Rust type system, which can be one of
25
27
/// several kinds (types, lifetimes, and consts).
@@ -31,10 +33,29 @@ use std::ops::{ControlFlow, Deref};
31
33
/// `Region` and `Const` are all interned.
32
34
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
33
35
pub struct GenericArg<'tcx> {
34
- ptr: NonZeroUsize ,
36
+ ptr: NonNull<()> ,
35
37
marker: PhantomData<(Ty<'tcx>, ty::Region<'tcx>, ty::Const<'tcx>)>,
36
38
}
37
39
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
+
38
59
impl<'tcx> IntoDiagnosticArg for GenericArg<'tcx> {
39
60
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
40
61
self.to_string().into_diagnostic_arg()
@@ -60,21 +81,21 @@ impl<'tcx> GenericArgKind<'tcx> {
60
81
GenericArgKind::Lifetime(lt) => {
61
82
// Ensure we can use the tag bits.
62
83
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() )
64
85
}
65
86
GenericArgKind::Type(ty) => {
66
87
// Ensure we can use the tag bits.
67
88
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() )
69
90
}
70
91
GenericArgKind::Const(ct) => {
71
92
// Ensure we can use the tag bits.
72
93
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() )
74
95
}
75
96
};
76
97
77
- GenericArg { ptr: unsafe { NonZeroUsize::new_unchecked( ptr | tag) } , marker: PhantomData }
98
+ GenericArg { ptr: ptr.map_addr(|addr| addr | tag), marker: PhantomData }
78
99
}
79
100
}
80
101
@@ -123,20 +144,22 @@ impl<'tcx> From<ty::Term<'tcx>> for GenericArg<'tcx> {
123
144
impl<'tcx> GenericArg<'tcx> {
124
145
#[inline]
125
146
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
+ };
127
150
// SAFETY: use of `Interned::new_unchecked` here is ok because these
128
151
// pointers were originally created from `Interned` types in `pack()`,
129
152
// and this is just going in the other direction.
130
153
unsafe {
131
- match ptr & TAG_MASK {
154
+ match self. ptr.addr().get() & TAG_MASK {
132
155
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( ),
134
157
))),
135
158
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( ),
137
160
))),
138
161
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( ),
140
163
))),
141
164
_ => intrinsics::unreachable(),
142
165
}
0 commit comments