@@ -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,34 @@ 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 try_as_ambig_ct ( & self ) -> Option < & ConstArg < ' hir , AmbigArg > > {
284+ if let ConstArgKind :: Infer ( _, ( ) ) = self . kind {
285+ return None ;
286+ }
287+
288+ // SAFETY: `ConstArg` is `repr(C)` and `ConstArgKind` is marked `repr(u8)` so that the layout is
289+ // the same across different ZST type arguments. We also asserted that the `self` is
290+ // not a `ConstArgKind::Infer` so there is no risk of transmuting a `()` to `AmbigArg`.
291+ let ptr = self as * const ConstArg < ' hir > as * const ConstArg < ' hir , AmbigArg > ;
292+ Some ( unsafe { & * ptr } )
293+ }
270294}
271295
272296impl < ' hir > ConstArg < ' hir > {
@@ -281,14 +305,15 @@ impl<'hir> ConstArg<'hir> {
281305 match self . kind {
282306 ConstArgKind :: Path ( path) => path. span ( ) ,
283307 ConstArgKind :: Anon ( anon) => anon. span ,
284- ConstArgKind :: Infer ( span) => span,
308+ ConstArgKind :: Infer ( span, _ ) => span,
285309 }
286310 }
287311}
288312
289313/// See [`ConstArg`].
290314#[ derive( Clone , Copy , Debug , HashStable_Generic ) ]
291- pub enum ConstArgKind < ' hir > {
315+ #[ repr( u8 , C ) ]
316+ pub enum ConstArgKind < ' hir , Unambig = ( ) > {
292317 /// **Note:** Currently this is only used for bare const params
293318 /// (`N` where `fn foo<const N: usize>(...)`),
294319 /// not paths to any const (`N` where `const N: usize = ...`).
@@ -300,7 +325,7 @@ pub enum ConstArgKind<'hir> {
300325 /// `ConstArgKind::Infer`. In cases where it is ambiguous whether
301326 /// a generic arg is a type or a const, inference variables are
302327 /// represented as `GenericArg::Infer` instead.
303- Infer ( Span ) ,
328+ Infer ( Span , Unambig ) ,
304329}
305330
306331#[ derive( Clone , Copy , Debug , HashStable_Generic ) ]
@@ -311,15 +336,15 @@ pub struct InferArg {
311336
312337impl InferArg {
313338 pub fn to_ty ( & self ) -> Ty < ' static > {
314- Ty { kind : TyKind :: Infer , span : self . span , hir_id : self . hir_id }
339+ Ty { kind : TyKind :: Infer ( ( ) ) , span : self . span , hir_id : self . hir_id }
315340 }
316341}
317342
318343#[ derive( Debug , Clone , Copy , HashStable_Generic ) ]
319344pub enum GenericArg < ' hir > {
320345 Lifetime ( & ' hir Lifetime ) ,
321- Type ( & ' hir Ty < ' hir > ) ,
322- Const ( & ' hir ConstArg < ' hir > ) ,
346+ Type ( & ' hir Ty < ' hir , AmbigArg > ) ,
347+ Const ( & ' hir ConstArg < ' hir , AmbigArg > ) ,
323348 /// **Note:** Inference variables are only represented as
324349 /// `GenericArg::Infer` in cases where it is ambiguous whether
325350 /// a generic arg is a type or a const. Otherwise, inference variables
@@ -332,7 +357,7 @@ impl GenericArg<'_> {
332357 match self {
333358 GenericArg :: Lifetime ( l) => l. ident . span ,
334359 GenericArg :: Type ( t) => t. span ,
335- GenericArg :: Const ( c) => c. span ( ) ,
360+ GenericArg :: Const ( c) => c. as_unambig_ct ( ) . span ( ) ,
336361 GenericArg :: Infer ( i) => i. span ,
337362 }
338363 }
@@ -351,7 +376,7 @@ impl GenericArg<'_> {
351376 GenericArg :: Lifetime ( _) => "lifetime" ,
352377 GenericArg :: Type ( _) => "type" ,
353378 GenericArg :: Const ( _) => "constant" ,
354- GenericArg :: Infer ( _) => "inferred " ,
379+ GenericArg :: Infer ( _) => "placeholder " ,
355380 }
356381 }
357382
@@ -2904,10 +2929,37 @@ impl<'hir> AssocItemConstraintKind<'hir> {
29042929}
29052930
29062931#[ derive( Debug , Clone , Copy , HashStable_Generic ) ]
2907- pub struct Ty < ' hir > {
2932+ pub enum AmbigArg { }
2933+
2934+ #[ derive( Debug , Clone , Copy , HashStable_Generic ) ]
2935+ #[ repr( C ) ]
2936+ pub struct Ty < ' hir , Unambig = ( ) > {
29082937 pub hir_id : HirId ,
2909- pub kind : TyKind < ' hir > ,
29102938 pub span : Span ,
2939+ pub kind : TyKind < ' hir , Unambig > ,
2940+ }
2941+
2942+ impl < ' hir > Ty < ' hir , AmbigArg > {
2943+ pub fn as_unambig_ty ( & self ) -> & Ty < ' hir > {
2944+ // SAFETY: `Ty` is `repr(C)` and `TyKind` is marked `repr(u8)` so that the layout is
2945+ // the same across different ZST type arguments.
2946+ let ptr = self as * const Ty < ' hir , AmbigArg > as * const Ty < ' hir , ( ) > ;
2947+ unsafe { & * ptr }
2948+ }
2949+ }
2950+
2951+ impl < ' hir > Ty < ' hir > {
2952+ pub fn try_as_ambig_ty ( & self ) -> Option < & Ty < ' hir , AmbigArg > > {
2953+ if let TyKind :: Infer ( ( ) ) = self . kind {
2954+ return None ;
2955+ }
2956+
2957+ // SAFETY: `Ty` is `repr(C)` and `TyKind` is marked `repr(u8)` so that the layout is
2958+ // the same across different ZST type arguments. We also asserted that the `self` is
2959+ // not a `TyKind::Infer` so there is no risk of transmuting a `()` to `AmbigArg`.
2960+ let ptr = self as * const Ty < ' hir > as * const Ty < ' hir , AmbigArg > ;
2961+ Some ( unsafe { & * ptr } )
2962+ }
29112963}
29122964
29132965impl < ' hir > Ty < ' hir > {
@@ -2939,7 +2991,7 @@ impl<'hir> Ty<'hir> {
29392991 use crate :: intravisit:: Visitor ;
29402992 struct MyVisitor ( Vec < Span > ) ;
29412993 impl < ' v > Visitor < ' v > for MyVisitor {
2942- fn visit_ty ( & mut self , t : & ' v Ty < ' v > ) {
2994+ fn visit_ty ( & mut self , t : & ' v Ty < ' v , AmbigArg > ) {
29432995 if matches ! (
29442996 & t. kind,
29452997 TyKind :: Path ( QPath :: Resolved ( _, Path {
@@ -2955,7 +3007,7 @@ impl<'hir> Ty<'hir> {
29553007 }
29563008
29573009 let mut my_visitor = MyVisitor ( vec ! [ ] ) ;
2958- my_visitor. visit_ty ( self ) ;
3010+ my_visitor. visit_unambig_ty ( self ) ;
29593011 my_visitor. 0
29603012 }
29613013
@@ -2964,14 +3016,14 @@ impl<'hir> Ty<'hir> {
29643016 pub fn is_suggestable_infer_ty ( & self ) -> bool {
29653017 fn are_suggestable_generic_args ( generic_args : & [ GenericArg < ' _ > ] ) -> bool {
29663018 generic_args. iter ( ) . any ( |arg| match arg {
2967- GenericArg :: Type ( ty) => ty. is_suggestable_infer_ty ( ) ,
3019+ GenericArg :: Type ( ty) => ty. as_unambig_ty ( ) . is_suggestable_infer_ty ( ) ,
29683020 GenericArg :: Infer ( _) => true ,
29693021 _ => false ,
29703022 } )
29713023 }
29723024 debug ! ( ?self ) ;
29733025 match & self . kind {
2974- TyKind :: Infer => true ,
3026+ TyKind :: Infer ( ( ) ) => true ,
29753027 TyKind :: Slice ( ty) => ty. is_suggestable_infer_ty ( ) ,
29763028 TyKind :: Array ( ty, length) => {
29773029 ty. is_suggestable_infer_ty ( ) || matches ! ( length. kind, ConstArgKind :: Infer ( ..) )
@@ -3183,7 +3235,9 @@ pub enum InferDelegationKind {
31833235
31843236/// The various kinds of types recognized by the compiler.
31853237#[ derive( Debug , Clone , Copy , HashStable_Generic ) ]
3186- pub enum TyKind < ' hir > {
3238+ // SAFETY: `repr(u8)` is required so that `TyKind<()>` and `TyKind<!>` are layout compatible
3239+ #[ repr( u8 , C ) ]
3240+ pub enum TyKind < ' hir , Unambig = ( ) > {
31873241 /// Actual type should be inherited from `DefId` signature
31883242 InferDelegation ( DefId , InferDelegationKind ) ,
31893243 /// A variable length slice (i.e., `[T]`).
@@ -3219,18 +3273,18 @@ pub enum TyKind<'hir> {
32193273 ) ,
32203274 /// Unused for now.
32213275 Typeof ( & ' hir AnonConst ) ,
3276+ /// Placeholder for a type that has failed to be defined.
3277+ Err ( rustc_span:: ErrorGuaranteed ) ,
3278+ /// Pattern types (`pattern_type!(u32 is 1..)`)
3279+ Pat ( & ' hir Ty < ' hir > , & ' hir Pat < ' hir > ) ,
32223280 /// `TyKind::Infer` means the type should be inferred instead of it having been
32233281 /// specified. This can appear anywhere in a type.
32243282 ///
32253283 /// **Note:** Not all inferred types are represented as
32263284 /// `TyKind::Infer`. In cases where it is ambiguous whether
32273285 /// a generic arg is a type or a const, inference variables are
32283286 /// represented as `GenericArg::Infer` instead.
3229- Infer ,
3230- /// Placeholder for a type that has failed to be defined.
3231- Err ( rustc_span:: ErrorGuaranteed ) ,
3232- /// Pattern types (`pattern_type!(u32 is 1..)`)
3233- Pat ( & ' hir Ty < ' hir > , & ' hir Pat < ' hir > ) ,
3287+ Infer ( Unambig ) ,
32343288}
32353289
32363290#[ derive( Debug , Clone , Copy , HashStable_Generic ) ]
0 commit comments