@@ -104,19 +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) = 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) =>
120
128
{
121
129
// If the def_id we are calling generics_of on is an anon ct default i.e:
122
130
//
@@ -160,36 +168,17 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
160
168
has_self : generics. has_self ,
161
169
has_late_bound_regions : generics. has_late_bound_regions ,
162
170
} ;
163
- } else {
164
- // HACK(eddyb) this provides the correct generics when
165
- // `feature(generic_const_expressions)` is enabled, so that const expressions
166
- // used with const generics, e.g. `Foo<{N+1}>`, can work at all.
167
- //
168
- // Note that we do not supply the parent generics when using
169
- // `min_const_generics`.
170
- Some ( parent_did)
171
171
}
172
- } else {
173
- let parent_node = tcx. parent_hir_node ( hir_id) ;
174
- let parent_node = match parent_node {
175
- Node :: ConstArg ( ca) => tcx. parent_hir_node ( ca. hir_id ) ,
176
- _ => parent_node,
177
- } ;
178
- match parent_node {
179
- // HACK(eddyb) this provides the correct generics for repeat
180
- // expressions' count (i.e. `N` in `[x; N]`), and explicit
181
- // `enum` discriminants (i.e. `D` in `enum Foo { Bar = D }`),
182
- // as they shouldn't be able to cause query cycle errors.
183
- Node :: Expr ( Expr { kind : ExprKind :: Repeat ( _, ct) , .. } )
184
- if ct. anon_const_hir_id ( ) == Some ( hir_id) =>
185
- {
186
- Some ( parent_did)
187
- }
188
- Node :: TyPat ( _) => Some ( parent_did) ,
189
- // Field default values inherit the ADT's generics.
190
- Node :: Field ( _) => Some ( parent_did) ,
191
- _ => 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)
192
179
}
180
+ // Default to no generic parameters for other kinds of anon consts
181
+ ty:: AnonConstKind :: NonTypeSystem => None ,
193
182
}
194
183
}
195
184
Node :: ConstBlock ( _)
0 commit comments