@@ -6,81 +6,83 @@ use rustc_middle::ty::{self, Representability, Ty, TyCtxt};
66use rustc_span:: def_id:: LocalDefId ;
77
88pub ( crate ) fn provide ( providers : & mut Providers ) {
9- * providers =
10- Providers { representability, representability_adt_ty, params_in_repr, ..* providers } ;
11- }
12-
13- macro_rules! rtry {
14- ( $e: expr) => {
15- match $e {
16- e @ Representability :: Infinite ( _) => return e,
17- Representability :: Representable => { }
18- }
9+ * providers = Providers {
10+ check_representability,
11+ check_representability_adt_ty,
12+ params_in_repr,
13+ ..* providers
1914 } ;
2015}
2116
22- fn representability ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> Representability {
17+ fn check_representability ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> Representability {
2318 match tcx. def_kind ( def_id) {
2419 DefKind :: Struct | DefKind :: Union | DefKind :: Enum => {
2520 for variant in tcx. adt_def ( def_id) . variants ( ) {
2621 for field in variant. fields . iter ( ) {
27- rtry ! ( tcx. representability ( field. did. expect_local( ) ) ) ;
22+ let _ = tcx. check_representability ( field. did . expect_local ( ) ) ;
2823 }
2924 }
30- Representability :: Representable
3125 }
32- DefKind :: Field => representability_ty ( tcx, tcx. type_of ( def_id) . instantiate_identity ( ) ) ,
26+ DefKind :: Field => {
27+ check_representability_ty ( tcx, tcx. type_of ( def_id) . instantiate_identity ( ) ) ;
28+ }
3329 def_kind => bug ! ( "unexpected {def_kind:?}" ) ,
3430 }
31+ Representability
3532}
3633
37- fn representability_ty < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> Representability {
34+ fn check_representability_ty < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) {
3835 match * ty. kind ( ) {
39- ty:: Adt ( ..) => tcx. representability_adt_ty ( ty) ,
36+ // This one must be a query rather than a vanilla `check_representability_adt_ty` call. See
37+ // the comment on `check_representability_adt_ty` below for why.
38+ ty:: Adt ( ..) => {
39+ let _ = tcx. check_representability_adt_ty ( ty) ;
40+ }
4041 // FIXME(#11924) allow zero-length arrays?
41- ty:: Array ( ty, _) => representability_ty ( tcx, ty) ,
42+ ty:: Array ( ty, _) => {
43+ check_representability_ty ( tcx, ty) ;
44+ }
4245 ty:: Tuple ( tys) => {
4346 for ty in tys {
44- rtry ! ( representability_ty ( tcx, ty) ) ;
47+ check_representability_ty ( tcx, ty) ;
4548 }
46- Representability :: Representable
4749 }
48- _ => Representability :: Representable ,
50+ _ => { }
4951 }
5052}
5153
52- /*
53- The reason for this being a separate query is very subtle:
54- Consider this infinitely sized struct: `struct Foo(Box<Foo>, Bar<Foo>)` :
55- When calling representability(Foo), a query cycle will occur:
56- representability (Foo)
57- -> representability_adt_ty (Bar<Foo>)
58- -> representability (Foo)
59- For the diagnostic output (in `Value::from_cycle_error`), we want to detect that
60- the `Foo` in the *second* field of the struct is culpable. This requires
61- traversing the HIR of the struct and calling `params_in_repr(Bar)`. But we can't
62- call params_in_repr for a given type unless it is known to be representable .
63- params_in_repr will cycle/panic on infinitely sized types. Looking at the query
64- cycle above, we know that `Bar` is representable because
65- representability_adt_ty(Bar<..>) is in the cycle and representability( Bar) is
66- *not* in the cycle.
67- */
68- fn representability_adt_ty < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> Representability {
54+ // The reason for this being a separate query is very subtle. Consider this
55+ // infinitely sized struct: `struct Foo(Box<Foo>, Bar<Foo>)`. When calling
56+ // check_representability(Foo), a query cycle will occur :
57+ //
58+ // check_representability (Foo)
59+ // -> check_representability_adt_ty (Bar<Foo>)
60+ // -> check_representability (Foo)
61+ //
62+ // For the diagnostic output (in `Value::from_cycle_error`), we want to detect
63+ // that the `Foo` in the *second* field of the struct is culpable. This
64+ // requires traversing the HIR of the struct and calling `params_in_repr(Bar)` .
65+ // But we can't call params_in_repr for a given type unless it is known to be
66+ // representable. params_in_repr will cycle/panic on infinitely sized types.
67+ // Looking at the query cycle above, we know that ` Bar` is representable
68+ // because `check_representability_adt_ty(Bar<..>)` is in the cycle and
69+ // `check_representability(Bar)` is *not* in the cycle.
70+ fn check_representability_adt_ty < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> Representability {
6971 let ty:: Adt ( adt, args) = ty. kind ( ) else { bug ! ( "expected adt" ) } ;
7072 if let Some ( def_id) = adt. did ( ) . as_local ( ) {
71- rtry ! ( tcx. representability ( def_id) ) ;
73+ let _ = tcx. check_representability ( def_id) ;
7274 }
7375 // At this point, we know that the item of the ADT type is representable;
7476 // but the type parameters may cause a cycle with an upstream type
7577 let params_in_repr = tcx. params_in_repr ( adt. did ( ) ) ;
7678 for ( i, arg) in args. iter ( ) . enumerate ( ) {
7779 if let ty:: GenericArgKind :: Type ( ty) = arg. kind ( ) {
7880 if params_in_repr. contains ( i as u32 ) {
79- rtry ! ( representability_ty ( tcx, ty) ) ;
81+ check_representability_ty ( tcx, ty) ;
8082 }
8183 }
8284 }
83- Representability :: Representable
85+ Representability
8486}
8587
8688fn params_in_repr ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> DenseBitSet < u32 > {
0 commit comments