@@ -31,7 +31,7 @@ use crate::LangItem;
31
31
use crate :: def:: { CtorKind , DefKind , Res } ;
32
32
use crate :: def_id:: { DefId , LocalDefIdMap } ;
33
33
pub ( crate ) use crate :: hir_id:: { HirId , ItemLocalId , ItemLocalMap , OwnerId } ;
34
- use crate :: intravisit:: FnKind ;
34
+ use crate :: intravisit:: { FnKind , VisitorExt } ;
35
35
36
36
#[ derive( Debug , Copy , Clone , HashStable_Generic ) ]
37
37
pub struct Lifetime {
@@ -263,10 +263,32 @@ impl<'hir> PathSegment<'hir> {
263
263
/// that are [just paths](ConstArgKind::Path) (currently just bare const params)
264
264
/// versus const args that are literals or have arbitrary computations (e.g., `{ 1 + 3 }`).
265
265
#[ derive( Clone , Copy , Debug , HashStable_Generic ) ]
266
- pub struct ConstArg < ' hir > {
266
+ #[ repr( C ) ]
267
+ pub struct ConstArg < ' hir , Unambig = ( ) > {
267
268
#[ stable_hasher( ignore) ]
268
269
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
+ }
270
292
}
271
293
272
294
impl < ' hir > ConstArg < ' hir > {
@@ -281,14 +303,15 @@ impl<'hir> ConstArg<'hir> {
281
303
match self . kind {
282
304
ConstArgKind :: Path ( path) => path. span ( ) ,
283
305
ConstArgKind :: Anon ( anon) => anon. span ,
284
- ConstArgKind :: Infer ( span) => span,
306
+ ConstArgKind :: Infer ( span, _ ) => span,
285
307
}
286
308
}
287
309
}
288
310
289
311
/// See [`ConstArg`].
290
312
#[ derive( Clone , Copy , Debug , HashStable_Generic ) ]
291
- pub enum ConstArgKind < ' hir > {
313
+ #[ repr( u8 , C ) ]
314
+ pub enum ConstArgKind < ' hir , Unambig = ( ) > {
292
315
/// **Note:** Currently this is only used for bare const params
293
316
/// (`N` where `fn foo<const N: usize>(...)`),
294
317
/// not paths to any const (`N` where `const N: usize = ...`).
@@ -300,7 +323,7 @@ pub enum ConstArgKind<'hir> {
300
323
/// `ConstArgKind::Infer`. In cases where it is ambiguous whether
301
324
/// a generic arg is a type or a const, inference variables are
302
325
/// represented as `GenericArg::Infer` instead.
303
- Infer ( Span ) ,
326
+ Infer ( Span , Unambig ) ,
304
327
}
305
328
306
329
#[ derive( Clone , Copy , Debug , HashStable_Generic ) ]
@@ -311,15 +334,15 @@ pub struct InferArg {
311
334
312
335
impl InferArg {
313
336
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 }
315
338
}
316
339
}
317
340
318
341
#[ derive( Debug , Clone , Copy , HashStable_Generic ) ]
319
342
pub enum GenericArg < ' hir > {
320
343
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 > ) ,
323
346
/// **Note:** Inference variables are only represented as
324
347
/// `GenericArg::Infer` in cases where it is ambiguous whether
325
348
/// a generic arg is a type or a const. Otherwise, inference variables
@@ -332,7 +355,7 @@ impl GenericArg<'_> {
332
355
match self {
333
356
GenericArg :: Lifetime ( l) => l. ident . span ,
334
357
GenericArg :: Type ( t) => t. span ,
335
- GenericArg :: Const ( c) => c. span ( ) ,
358
+ GenericArg :: Const ( c) => c. as_unambig_ct ( ) . span ( ) ,
336
359
GenericArg :: Infer ( i) => i. span ,
337
360
}
338
361
}
@@ -351,7 +374,7 @@ impl GenericArg<'_> {
351
374
GenericArg :: Lifetime ( _) => "lifetime" ,
352
375
GenericArg :: Type ( _) => "type" ,
353
376
GenericArg :: Const ( _) => "constant" ,
354
- GenericArg :: Infer ( _) => "inferred " ,
377
+ GenericArg :: Infer ( _) => "placeholder " ,
355
378
}
356
379
}
357
380
@@ -2869,10 +2892,35 @@ impl<'hir> AssocItemConstraintKind<'hir> {
2869
2892
}
2870
2893
2871
2894
#[ 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 = ( ) > {
2873
2900
pub hir_id : HirId ,
2874
- pub kind : TyKind < ' hir > ,
2875
2901
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
+ }
2876
2924
}
2877
2925
2878
2926
impl < ' hir > Ty < ' hir > {
@@ -2904,7 +2952,7 @@ impl<'hir> Ty<'hir> {
2904
2952
use crate :: intravisit:: Visitor ;
2905
2953
struct MyVisitor ( Vec < Span > ) ;
2906
2954
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 > ) {
2908
2956
if matches ! (
2909
2957
& t. kind,
2910
2958
TyKind :: Path ( QPath :: Resolved ( _, Path {
@@ -2915,12 +2963,12 @@ impl<'hir> Ty<'hir> {
2915
2963
self . 0 . push ( t. span ) ;
2916
2964
return ;
2917
2965
}
2918
- crate :: intravisit:: walk_ty ( self , t) ;
2966
+ crate :: intravisit:: walk_ambig_ty ( self , t) ;
2919
2967
}
2920
2968
}
2921
2969
2922
2970
let mut my_visitor = MyVisitor ( vec ! [ ] ) ;
2923
- my_visitor. visit_ty ( self ) ;
2971
+ my_visitor. visit_unambig_ty ( self ) ;
2924
2972
my_visitor. 0
2925
2973
}
2926
2974
@@ -2929,14 +2977,14 @@ impl<'hir> Ty<'hir> {
2929
2977
pub fn is_suggestable_infer_ty ( & self ) -> bool {
2930
2978
fn are_suggestable_generic_args ( generic_args : & [ GenericArg < ' _ > ] ) -> bool {
2931
2979
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 ( ) ,
2933
2981
GenericArg :: Infer ( _) => true ,
2934
2982
_ => false ,
2935
2983
} )
2936
2984
}
2937
2985
debug ! ( ?self ) ;
2938
2986
match & self . kind {
2939
- TyKind :: Infer => true ,
2987
+ TyKind :: Infer ( ( ) ) => true ,
2940
2988
TyKind :: Slice ( ty) => ty. is_suggestable_infer_ty ( ) ,
2941
2989
TyKind :: Array ( ty, length) => {
2942
2990
ty. is_suggestable_infer_ty ( ) || matches ! ( length. kind, ConstArgKind :: Infer ( ..) )
@@ -3148,7 +3196,9 @@ pub enum InferDelegationKind {
3148
3196
3149
3197
/// The various kinds of types recognized by the compiler.
3150
3198
#[ 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 = ( ) > {
3152
3202
/// Actual type should be inherited from `DefId` signature
3153
3203
InferDelegation ( DefId , InferDelegationKind ) ,
3154
3204
/// A variable length slice (i.e., `[T]`).
@@ -3184,18 +3234,18 @@ pub enum TyKind<'hir> {
3184
3234
) ,
3185
3235
/// Unused for now.
3186
3236
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 > ) ,
3187
3241
/// `TyKind::Infer` means the type should be inferred instead of it having been
3188
3242
/// specified. This can appear anywhere in a type.
3189
3243
///
3190
3244
/// **Note:** Not all inferred types are represented as
3191
3245
/// `TyKind::Infer`. In cases where it is ambiguous whether
3192
3246
/// a generic arg is a type or a const, inference variables are
3193
3247
/// 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 ) ,
3199
3249
}
3200
3250
3201
3251
#[ derive( Debug , Clone , Copy , HashStable_Generic ) ]
0 commit comments