@@ -104,20 +104,27 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
104
104
}
105
105
}
106
106
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) =>
121
128
{
122
129
// If the def_id we are calling generics_of on is an anon ct default i.e:
123
130
//
@@ -161,36 +168,17 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
161
168
has_self : generics. has_self ,
162
169
has_late_bound_regions : generics. has_late_bound_regions ,
163
170
} ;
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)
172
171
}
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)
193
179
}
180
+ // Default to no generic parameters for other kinds of anon consts
181
+ ty:: AnonConstKind :: NonTypeSystem => None ,
194
182
}
195
183
}
196
184
Node :: ConstBlock ( _)
0 commit comments