@@ -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