GitHub

@@ -104,19 +104,27 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {

104104

}

105105

}

106106107-

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) =>

120128

{

121129

// If the def_id we are calling generics_of on is an anon ct default i.e:

122130

//

@@ -160,36 +168,17 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {

160168

has_self: generics.has_self,

161169

has_late_bound_regions: generics.has_late_bound_regions,

162170

};

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)

171171

}

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)

192179

}

180+

// Default to no generic parameters for other kinds of anon consts

181+

ty::AnonConstKind::NonTypeSystem => None,

193182

}

194183

}

195184

Node::ConstBlock(_)

Read the original on github.com ↗