@@ -104,20 +104,27 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
104104                } 
105105            } 
106106
107-             if  in_param_ty { 
108-                 // We do not allow generic parameters in anon consts if we are inside 
109-                 // of a const parameter type, e.g. `struct Foo<const N: usize, const M: [u8; N]>` is not allowed. 
110-                 None 
111-             }  else  if  tcx. features ( ) . generic_const_exprs ( )  { 
112-                 let  parent_node = tcx. parent_hir_node ( hir_id) ; 
113-                 debug ! ( ?parent_node) ; 
114-                 if  let  Node :: Variant ( Variant  {  disr_expr :  Some ( constant) ,  .. } )  = parent_node
115-                     && constant. hir_id  == hir_id
116-                 { 
117-                     // enum variant discriminants are not allowed to use any kind of generics 
118-                     None 
119-                 }  else  if  let  Some ( param_id)  =
120-                     tcx. hir ( ) . opt_const_param_default_param_def_id ( hir_id) 
107+             match  tcx. anon_const_kind ( def_id)  { 
108+                 // Stable: anon consts are not able to use any generic parameters... 
109+                 ty:: AnonConstKind :: MCGConst  => None , 
110+                 // we provide generics to repeat expr counts as a backwards compatibility hack. #76200 
111+                 ty:: AnonConstKind :: RepeatExprCount  => Some ( parent_did) , 
112+ 
113+                 // Even GCE anon const should not be allowed to use generic parameters as it would be 
114+                 // trivially forward declared uses once desugared. E.g. `const N: [u8; ANON::<N>]`. 
115+                 // 
116+                 // We could potentially mirror the hack done for defaults of generic parameters but 
117+                 // this case just doesn't come up much compared to `const N: u32 = ...`. Long term the 
118+                 // hack for defaulted parameters should be removed eventually anyway. 
119+                 ty:: AnonConstKind :: GCEConst  if  in_param_ty => None , 
120+                 // GCE anon consts as a default for a generic parameter should have their provided generics 
121+                 // "truncated" up to whatever generic parameter this anon const is within the default of. 
122+                 // 
123+                 // FIXME(generic_const_exprs): This only handles `const N: usize = /*defid*/` but not type 
124+                 // parameter defaults, e.g. `T = Foo</*defid*/>`. 
125+                 ty:: AnonConstKind :: GCEConst 
126+                     if  let  Some ( param_id)  =
127+                         tcx. hir ( ) . opt_const_param_default_param_def_id ( hir_id)  =>
121128                { 
122129                    // If the def_id we are calling generics_of on is an anon ct default i.e: 
123130                    // 
@@ -161,36 +168,17 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
161168                        has_self :  generics. has_self , 
162169                        has_late_bound_regions :  generics. has_late_bound_regions , 
163170                    } ; 
164-                 }  else  { 
165-                     // HACK(eddyb) this provides the correct generics when 
166-                     // `feature(generic_const_expressions)` is enabled, so that const expressions 
167-                     // used with const generics, e.g. `Foo<{N+1}>`, can work at all. 
168-                     // 
169-                     // Note that we do not supply the parent generics when using 
170-                     // `min_const_generics`. 
171-                     Some ( parent_did) 
172171                } 
173-             }  else  { 
174-                 let  parent_node = tcx. parent_hir_node ( hir_id) ; 
175-                 let  parent_node = match  parent_node { 
176-                     Node :: ConstArg ( ca)  => tcx. parent_hir_node ( ca. hir_id ) , 
177-                     _ => parent_node, 
178-                 } ; 
179-                 match  parent_node { 
180-                     // HACK(eddyb) this provides the correct generics for repeat 
181-                     // expressions' count (i.e. `N` in `[x; N]`), and explicit 
182-                     // `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`), 
183-                     // as they shouldn't be able to cause query cycle errors. 
184-                     Node :: Expr ( Expr  {  kind :  ExprKind :: Repeat ( _,  ct) ,  .. } ) 
185-                         if  ct. anon_const_hir_id ( )  == Some ( hir_id)  =>
186-                     { 
187-                         Some ( parent_did) 
188-                     } 
189-                     Node :: TyPat ( _)  => Some ( parent_did) , 
190-                     // Field default values inherit the ADT's generics. 
191-                     Node :: Field ( _)  => Some ( parent_did) , 
192-                     _ => None , 
172+                 ty:: AnonConstKind :: GCEConst  => Some ( parent_did) , 
173+ 
174+                 // Field defaults are allowed to use generic parameters, e.g. `field: u32 = /*defid: N + 1*/` 
175+                 ty:: AnonConstKind :: NonTypeSystem 
176+                     if  matches ! ( tcx. parent_hir_node( hir_id) ,  Node :: TyPat ( _)  | Node :: Field ( _) )  =>
177+                 { 
178+                     Some ( parent_did) 
193179                } 
180+                 // Default to no generic parameters for other kinds of anon consts 
181+                 ty:: AnonConstKind :: NonTypeSystem  => None , 
194182            } 
195183        } 
196184        Node :: ConstBlock ( _) 
0 commit comments