@@ -7,6 +7,7 @@ use crate::ty::visit::{TypeVisitable, TypeVisitableExt, TypeVisitor};
77use crate :: ty:: { self , Lift , List , ParamConst , Ty , TyCtxt } ;
88
99use rustc_data_structures:: intern:: Interned ;
10+ use rustc_data_structures:: sync:: { DynSend , DynSync } ;
1011use rustc_errors:: { DiagnosticArgValue , IntoDiagnosticArg } ;
1112use rustc_hir:: def_id:: DefId ;
1213use rustc_macros:: HashStable ;
@@ -20,6 +21,7 @@ use std::marker::PhantomData;
2021use std:: mem;
2122use std:: num:: NonZeroUsize ;
2223use 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,27 @@ use std::ops::{ControlFlow, Deref};
3133/// `Region` and `Const` are all interned.
3234#[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
3335pub struct GenericArg < ' tcx > {
34- ptr : NonZeroUsize ,
36+ ptr : NonNull < ( ) > ,
3537 marker : PhantomData < ( Ty < ' tcx > , ty:: Region < ' tcx > , ty:: Const < ' tcx > ) > ,
3638}
3739
40+ unsafe impl < ' tcx > DynSend for GenericArg < ' tcx > where
41+ & ' tcx ( Ty < ' tcx > , ty:: Region < ' tcx > , ty:: Const < ' tcx > ) : DynSend
42+ {
43+ }
44+ unsafe impl < ' tcx > DynSync for GenericArg < ' tcx > where
45+ & ' tcx ( Ty < ' tcx > , ty:: Region < ' tcx > , ty:: Const < ' tcx > ) : DynSync
46+ {
47+ }
48+ unsafe impl < ' tcx > Send for GenericArg < ' tcx > where
49+ & ' tcx ( Ty < ' tcx > , ty:: Region < ' tcx > , ty:: Const < ' tcx > ) : Send
50+ {
51+ }
52+ unsafe impl < ' tcx > Sync for GenericArg < ' tcx > where
53+ & ' tcx ( Ty < ' tcx > , ty:: Region < ' tcx > , ty:: Const < ' tcx > ) : Sync
54+ {
55+ }
56+
3857impl < ' tcx > IntoDiagnosticArg for GenericArg < ' tcx > {
3958 fn into_diagnostic_arg ( self ) -> DiagnosticArgValue < ' static > {
4059 self . to_string ( ) . into_diagnostic_arg ( )
@@ -60,21 +79,21 @@ impl<'tcx> GenericArgKind<'tcx> {
6079 GenericArgKind :: Lifetime ( lt) => {
6180 // Ensure we can use the tag bits.
6281 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 )
82+ ( REGION_TAG , NonNull :: from ( lt. 0 . 0 ) . cast ( ) )
6483 }
6584 GenericArgKind :: Type ( ty) => {
6685 // Ensure we can use the tag bits.
6786 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 )
87+ ( TYPE_TAG , NonNull :: from ( ty. 0 . 0 ) . cast ( ) )
6988 }
7089 GenericArgKind :: Const ( ct) => {
7190 // Ensure we can use the tag bits.
7291 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 )
92+ ( CONST_TAG , NonNull :: from ( ct. 0 . 0 ) . cast ( ) )
7493 }
7594 } ;
7695
77- GenericArg { ptr : unsafe { NonZeroUsize :: new_unchecked ( ptr | tag) } , marker : PhantomData }
96+ GenericArg { ptr : ptr. map_addr ( |addr| addr | tag) , marker : PhantomData }
7897 }
7998}
8099
@@ -123,20 +142,22 @@ impl<'tcx> From<ty::Term<'tcx>> for GenericArg<'tcx> {
123142impl < ' tcx > GenericArg < ' tcx > {
124143 #[ inline]
125144 pub fn unpack ( self ) -> GenericArgKind < ' tcx > {
126- let ptr = self . ptr . get ( ) ;
145+ let ptr = unsafe {
146+ self . ptr . map_addr ( |addr| NonZeroUsize :: new_unchecked ( addr. get ( ) & !TAG_MASK ) )
147+ } ;
127148 // SAFETY: use of `Interned::new_unchecked` here is ok because these
128149 // pointers were originally created from `Interned` types in `pack()`,
129150 // and this is just going in the other direction.
130151 unsafe {
131- match ptr & TAG_MASK {
152+ match self . ptr . addr ( ) . get ( ) & TAG_MASK {
132153 REGION_TAG => GenericArgKind :: Lifetime ( ty:: Region ( Interned :: new_unchecked (
133- & * ( ( ptr & ! TAG_MASK ) as * const ty:: RegionKind < ' tcx > ) ,
154+ ptr. cast :: < ty:: RegionKind < ' tcx > > ( ) . as_ref ( ) ,
134155 ) ) ) ,
135156 TYPE_TAG => GenericArgKind :: Type ( Ty ( Interned :: new_unchecked (
136- & * ( ( ptr & ! TAG_MASK ) as * const WithCachedTypeInfo < ty:: TyKind < ' tcx > > ) ,
157+ ptr. cast :: < WithCachedTypeInfo < ty:: TyKind < ' tcx > > > ( ) . as_ref ( ) ,
137158 ) ) ) ,
138159 CONST_TAG => GenericArgKind :: Const ( ty:: Const ( Interned :: new_unchecked (
139- & * ( ( ptr & ! TAG_MASK ) as * const WithCachedTypeInfo < ty:: ConstData < ' tcx > > ) ,
160+ ptr. cast :: < WithCachedTypeInfo < ty:: ConstData < ' tcx > > > ( ) . as_ref ( ) ,
140161 ) ) ) ,
141162 _ => intrinsics:: unreachable ( ) ,
142163 }
0 commit comments