Rollup merge of #140467 - BoxyUwU:no_fcw_assoc_consts, r=lcnr

Don't FCW assoc consts in patterns

Fixes #140447

See comment in added test. We could also check that the anon const is a const arg by looking at the HIR. I'm not sure that's necessary though 🤔 The only consts that are evaluated "for the type system" are const args (which *should* get FCWs) and const patterns (which cant be anon consts afaik).
This commit is contained in:
Matthias Krüger 2025-04-30 22:36:40 +02:00 committed by GitHub
commit 372b15e55e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 33 additions and 9 deletions

View file

@ -115,15 +115,16 @@ impl<'tcx> TyCtxt<'tcx> {
// @lcnr believes that successfully evaluating even though there are
// used generic parameters is a bug of evaluation, so checking for it
// here does feel somewhat sensible.
if !self.features().generic_const_exprs() && ct.args.has_non_region_param() {
let def_kind = self.def_kind(instance.def_id());
assert!(
matches!(
def_kind,
DefKind::InlineConst | DefKind::AnonConst | DefKind::AssocConst
),
"{cid:?} is {def_kind:?}",
);
if !self.features().generic_const_exprs()
&& ct.args.has_non_region_param()
// We only FCW for anon consts as repeat expr counts with anon consts are the only place
// that we have a back compat hack for. We don't need to check this is a const argument
// as only anon consts as const args should get evaluated "for the type system".
//
// If we don't *only* FCW anon consts we can wind up incorrectly FCW'ing uses of assoc
// consts in pattern positions. #140447
&& self.def_kind(instance.def_id()) == DefKind::AnonConst
{
let mir_body = self.mir_for_ctfe(instance.def_id());
if mir_body.is_polymorphic {
let Some(local_def_id) = ct.def.as_local() else { return };

View file

@ -0,0 +1,23 @@
//@ check-pass
// Previously the `CONST_EVALUATABLE_UNCHECKED` FCW would fire on const evaluation of
// associated consts. This is unnecessary as the FCW only needs to apply for repeat expr
// counts which are anon consts with generic parameters provided. #140447
pub struct Foo<const N: usize>;
impl<const N: usize> Foo<N> {
const UNUSED_PARAM: usize = {
let _: [(); N];
3
};
pub fn bar() {
match 1 {
Self::UNUSED_PARAM => (),
_ => (),
}
}
}
fn main() {}