@@ -31,7 +31,7 @@ use crate::LangItem;
3131use crate :: def:: { CtorKind , DefKind , Res } ;
3232use crate :: def_id:: { DefId , LocalDefIdMap } ;
3333pub ( crate ) use crate :: hir_id:: { HirId , ItemLocalId , ItemLocalMap , OwnerId } ;
34- use crate :: intravisit:: FnKind ;
34+ use crate :: intravisit:: { FnKind , VisitorExt } ;
3535
3636#[ derive( Debug , Copy , Clone , HashStable_Generic ) ]
3737pub struct Lifetime {
@@ -263,10 +263,32 @@ impl<'hir> PathSegment<'hir> {
263263/// that are [just paths](ConstArgKind::Path) (currently just bare const params)
264264/// versus const args that are literals or have arbitrary computations (e.g., `{ 1 + 3 }`).
265265#[ derive( Clone , Copy , Debug , HashStable_Generic ) ]
266- pub struct ConstArg < ' hir > {
266+ #[ repr( C ) ]
267+ pub struct ConstArg < ' hir , Unambig = ( ) > {
267268 #[ stable_hasher( ignore) ]
268269 pub hir_id : HirId ,
269- pub kind : ConstArgKind < ' hir > ,
270+ pub kind : ConstArgKind < ' hir , Unambig > ,
271+ }
272+
273+ impl < ' hir > ConstArg < ' hir , AmbigArg > {
274+ pub fn as_unambig_ct ( & self ) -> & ConstArg < ' hir > {
275+ // SAFETY: `ConstArg` is `repr(C)` and `ConstArgKind` is marked `repr(u8)` so that the
276+ // layout is the same across different ZST type arguments.
277+ let ptr = self as * const ConstArg < ' hir , AmbigArg > as * const ConstArg < ' hir , ( ) > ;
278+ unsafe { & * ptr }
279+ }
280+ }
281+
282+ impl < ' hir > ConstArg < ' hir > {
283+ pub fn as_ambig_ct ( & self ) -> & ConstArg < ' hir , AmbigArg > {
284+ assert ! ( !matches!( self . kind, ConstArgKind :: Infer ( _, ( ) ) ) ) ;
285+
286+ // SAFETY: `ConstArg` is `repr(C)` and `ConstArgKind` is marked `repr(u8)` so that the layout is
287+ // the same across different ZST type arguments. We also asserted that the `self` is
288+ // not a `ConstArgKind::Infer` so there is no risk of transmuting a `()` to `AmbigArg`.
289+ let ptr = self as * const ConstArg < ' hir > as * const ConstArg < ' hir , AmbigArg > ;
290+ unsafe { & * ptr }
291+ }
270292}
271293
272294impl < ' hir > ConstArg < ' hir > {
@@ -281,14 +303,15 @@ impl<'hir> ConstArg<'hir> {
281303 match self . kind {
282304 ConstArgKind :: Path ( path) => path. span ( ) ,
283305 ConstArgKind :: Anon ( anon) => anon. span ,
284- ConstArgKind :: Infer ( span) => span,
306+ ConstArgKind :: Infer ( span, _ ) => span,
285307 }
286308 }
287309}
288310
289311/// See [`ConstArg`].
290312#[ derive( Clone , Copy , Debug , HashStable_Generic ) ]
291- pub enum ConstArgKind < ' hir > {
313+ #[ repr( u8 , C ) ]
314+ pub enum ConstArgKind < ' hir , Unambig = ( ) > {
292315 /// **Note:** Currently this is only used for bare const params
293316 /// (`N` where `fn foo<const N: usize>(...)`),
294317 /// not paths to any const (`N` where `const N: usize = ...`).
@@ -300,7 +323,7 @@ pub enum ConstArgKind<'hir> {
300323 /// `ConstArgKind::Infer`. In cases where it is ambiguous whether
301324 /// a generic arg is a type or a const, inference variables are
302325 /// represented as `GenericArg::Infer` instead.
303- Infer ( Span ) ,
326+ Infer ( Span , Unambig ) ,
304327}
305328
306329#[ derive( Clone , Copy , Debug , HashStable_Generic ) ]
@@ -311,15 +334,15 @@ pub struct InferArg {
311334
312335impl InferArg {
313336 pub fn to_ty ( & self ) -> Ty < ' static > {
314- Ty { kind : TyKind :: Infer , span : self . span , hir_id : self . hir_id }
337+ Ty { kind : TyKind :: Infer ( ( ) ) , span : self . span , hir_id : self . hir_id }
315338 }
316339}
317340
318341#[ derive( Debug , Clone , Copy , HashStable_Generic ) ]
319342pub enum GenericArg < ' hir > {
320343 Lifetime ( & ' hir Lifetime ) ,
321- Type ( & ' hir Ty < ' hir > ) ,
322- Const ( & ' hir ConstArg < ' hir > ) ,
344+ Type ( & ' hir Ty < ' hir , AmbigArg > ) ,
345+ Const ( & ' hir ConstArg < ' hir , AmbigArg > ) ,
323346 /// **Note:** Inference variables are only represented as
324347 /// `GenericArg::Infer` in cases where it is ambiguous whether
325348 /// a generic arg is a type or a const. Otherwise, inference variables
@@ -332,7 +355,7 @@ impl GenericArg<'_> {
332355 match self {
333356 GenericArg :: Lifetime ( l) => l. ident . span ,
334357 GenericArg :: Type ( t) => t. span ,
335- GenericArg :: Const ( c) => c. span ( ) ,
358+ GenericArg :: Const ( c) => c. as_unambig_ct ( ) . span ( ) ,
336359 GenericArg :: Infer ( i) => i. span ,
337360 }
338361 }
@@ -351,7 +374,7 @@ impl GenericArg<'_> {
351374 GenericArg :: Lifetime ( _) => "lifetime" ,
352375 GenericArg :: Type ( _) => "type" ,
353376 GenericArg :: Const ( _) => "constant" ,
354- GenericArg :: Infer ( _) => "inferred " ,
377+ GenericArg :: Infer ( _) => "placeholder " ,
355378 }
356379 }
357380
@@ -2869,10 +2892,35 @@ impl<'hir> AssocItemConstraintKind<'hir> {
28692892}
28702893
28712894#[ derive( Debug , Clone , Copy , HashStable_Generic ) ]
2872- pub struct Ty < ' hir > {
2895+ pub enum AmbigArg { }
2896+
2897+ #[ derive( Debug , Clone , Copy , HashStable_Generic ) ]
2898+ #[ repr( C ) ]
2899+ pub struct Ty < ' hir , Unambig = ( ) > {
28732900 pub hir_id : HirId ,
2874- pub kind : TyKind < ' hir > ,
28752901 pub span : Span ,
2902+ pub kind : TyKind < ' hir , Unambig > ,
2903+ }
2904+
2905+ impl < ' hir > Ty < ' hir , AmbigArg > {
2906+ pub fn as_unambig_ty ( & self ) -> & Ty < ' hir > {
2907+ // SAFETY: `Ty` is `repr(C)` and `TyKind` is marked `repr(u8)` so that the layout is
2908+ // the same across different ZST type arguments.
2909+ let ptr = self as * const Ty < ' hir , AmbigArg > as * const Ty < ' hir , ( ) > ;
2910+ unsafe { & * ptr }
2911+ }
2912+ }
2913+
2914+ impl < ' hir > Ty < ' hir > {
2915+ pub fn as_ambig_ty ( & self ) -> & Ty < ' hir , AmbigArg > {
2916+ assert ! ( !matches!( self . kind, TyKind :: Infer ( ( ) ) ) ) ;
2917+
2918+ // SAFETY: `Ty` is `repr(C)` and `TyKind` is marked `repr(u8)` so that the layout is
2919+ // the same across different ZST type arguments. We also asserted that the `self` is
2920+ // not a `TyKind::Infer` so there is no risk of transmuting a `()` to `AmbigArg`.
2921+ let ptr = self as * const Ty < ' hir > as * const Ty < ' hir , AmbigArg > ;
2922+ unsafe { & * ptr }
2923+ }
28762924}
28772925
28782926impl < ' hir > Ty < ' hir > {
@@ -2904,7 +2952,7 @@ impl<'hir> Ty<'hir> {
29042952 use crate :: intravisit:: Visitor ;
29052953 struct MyVisitor ( Vec < Span > ) ;
29062954 impl < ' v > Visitor < ' v > for MyVisitor {
2907- fn visit_ty ( & mut self , t : & ' v Ty < ' v > ) {
2955+ fn visit_ty ( & mut self , t : & ' v Ty < ' v , AmbigArg > ) {
29082956 if matches ! (
29092957 & t. kind,
29102958 TyKind :: Path ( QPath :: Resolved ( _, Path {
@@ -2915,12 +2963,12 @@ impl<'hir> Ty<'hir> {
29152963 self . 0 . push ( t. span ) ;
29162964 return ;
29172965 }
2918- crate :: intravisit:: walk_ty ( self , t) ;
2966+ crate :: intravisit:: walk_ambig_ty ( self , t) ;
29192967 }
29202968 }
29212969
29222970 let mut my_visitor = MyVisitor ( vec ! [ ] ) ;
2923- my_visitor. visit_ty ( self ) ;
2971+ my_visitor. visit_unambig_ty ( self ) ;
29242972 my_visitor. 0
29252973 }
29262974
@@ -2929,14 +2977,14 @@ impl<'hir> Ty<'hir> {
29292977 pub fn is_suggestable_infer_ty ( & self ) -> bool {
29302978 fn are_suggestable_generic_args ( generic_args : & [ GenericArg < ' _ > ] ) -> bool {
29312979 generic_args. iter ( ) . any ( |arg| match arg {
2932- GenericArg :: Type ( ty) => ty. is_suggestable_infer_ty ( ) ,
2980+ GenericArg :: Type ( ty) => ty. as_unambig_ty ( ) . is_suggestable_infer_ty ( ) ,
29332981 GenericArg :: Infer ( _) => true ,
29342982 _ => false ,
29352983 } )
29362984 }
29372985 debug ! ( ?self ) ;
29382986 match & self . kind {
2939- TyKind :: Infer => true ,
2987+ TyKind :: Infer ( ( ) ) => true ,
29402988 TyKind :: Slice ( ty) => ty. is_suggestable_infer_ty ( ) ,
29412989 TyKind :: Array ( ty, length) => {
29422990 ty. is_suggestable_infer_ty ( ) || matches ! ( length. kind, ConstArgKind :: Infer ( ..) )
@@ -3148,7 +3196,9 @@ pub enum InferDelegationKind {
31483196
31493197/// The various kinds of types recognized by the compiler.
31503198#[ derive( Debug , Clone , Copy , HashStable_Generic ) ]
3151- pub enum TyKind < ' hir > {
3199+ // SAFETY: `repr(u8)` is required so that `TyKind<()>` and `TyKind<!>` are layout compatible
3200+ #[ repr( u8 , C ) ]
3201+ pub enum TyKind < ' hir , Unambig = ( ) > {
31523202 /// Actual type should be inherited from `DefId` signature
31533203 InferDelegation ( DefId , InferDelegationKind ) ,
31543204 /// A variable length slice (i.e., `[T]`).
@@ -3184,18 +3234,18 @@ pub enum TyKind<'hir> {
31843234 ) ,
31853235 /// Unused for now.
31863236 Typeof ( & ' hir AnonConst ) ,
3237+ /// Placeholder for a type that has failed to be defined.
3238+ Err ( rustc_span:: ErrorGuaranteed ) ,
3239+ /// Pattern types (`pattern_type!(u32 is 1..)`)
3240+ Pat ( & ' hir Ty < ' hir > , & ' hir Pat < ' hir > ) ,
31873241 /// `TyKind::Infer` means the type should be inferred instead of it having been
31883242 /// specified. This can appear anywhere in a type.
31893243 ///
31903244 /// **Note:** Not all inferred types are represented as
31913245 /// `TyKind::Infer`. In cases where it is ambiguous whether
31923246 /// a generic arg is a type or a const, inference variables are
31933247 /// represented as `GenericArg::Infer` instead.
3194- Infer ,
3195- /// Placeholder for a type that has failed to be defined.
3196- Err ( rustc_span:: ErrorGuaranteed ) ,
3197- /// Pattern types (`pattern_type!(u32 is 1..)`)
3198- Pat ( & ' hir Ty < ' hir > , & ' hir Pat < ' hir > ) ,
3248+ Infer ( Unambig ) ,
31993249}
32003250
32013251#[ derive( Debug , Clone , Copy , HashStable_Generic ) ]
0 commit comments