Skip to content

Commit 3a19397

Browse files
committed
Only use AnonConstKind::OGCA for const item RHS's
1 parent 057b38b commit 3a19397

3 files changed

Lines changed: 50 additions & 1 deletion

File tree

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1513,6 +1513,13 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin
15131513
if tcx.features().generic_const_exprs() {
15141514
ty::AnonConstKind::GCE
15151515
} else if tcx.features().opaque_generic_const_args() {
1516+
// Only anon consts that are the RHS of a const item can be OGCA.
1517+
// Note: We can't just check tcx.parent because it needs to be EXACTLY
1518+
// the RHS, not just part of the RHS.
1519+
if !is_anon_const_rhs_of_const_item(tcx, def) {
1520+
return ty::AnonConstKind::MCG;
1521+
}
1522+
15161523
let body = tcx.hir_body_owned_by(def);
15171524
let mut visitor = OGCAParamVisitor(tcx);
15181525
match visitor.visit_body(body) {
@@ -1536,6 +1543,26 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin
15361543
}
15371544
}
15381545

1546+
fn is_anon_const_rhs_of_const_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
1547+
let hir_id = tcx.local_def_id_to_hir_id(def_id);
1548+
let Some((_, grandparent_node)) = tcx.hir_parent_iter(hir_id).nth(1) else { return false };
1549+
let (Node::Item(hir::Item { kind: hir::ItemKind::Const(_, _, _, ct_rhs), .. })
1550+
| Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(_, ct_rhs), .. })
1551+
| Node::TraitItem(hir::TraitItem {
1552+
kind: hir::TraitItemKind::Const(_, Some(ct_rhs)), ..
1553+
})) = grandparent_node
1554+
else {
1555+
return false;
1556+
};
1557+
let hir::ConstItemRhs::TypeConst(hir::ConstArg {
1558+
kind: hir::ConstArgKind::Anon(rhs_anon), ..
1559+
}) = ct_rhs
1560+
else {
1561+
return false;
1562+
};
1563+
def_id == rhs_anon.def_id
1564+
}
1565+
15391566
struct OGCAParamVisitor<'tcx>(TyCtxt<'tcx>);
15401567

15411568
struct UsesParam;
@@ -1548,7 +1575,7 @@ impl<'tcx> Visitor<'tcx> for OGCAParamVisitor<'tcx> {
15481575
self.0
15491576
}
15501577

1551-
fn visit_path(&mut self, path: &crate::hir::Path<'tcx>, _id: HirId) -> ControlFlow<UsesParam> {
1578+
fn visit_path(&mut self, path: &hir::Path<'tcx>, _id: HirId) -> ControlFlow<UsesParam> {
15521579
if let Res::Def(DefKind::TyParam | DefKind::ConstParam | DefKind::LifetimeParam, _) =
15531580
path.res
15541581
{
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#![feature(generic_const_items)]
2+
#![feature(min_generic_const_args)]
3+
#![feature(opaque_generic_const_args)]
4+
#![expect(incomplete_features)]
5+
6+
// Anon consts must be the root of the RHS to be OGCA.
7+
#[type_const]
8+
const FOO<const N: usize>: usize = ID::<const { N + 1 }>;
9+
//~^ ERROR generic parameters may not be used in const operations
10+
11+
#[type_const]
12+
const ID<const N: usize>: usize = N;
13+
14+
fn main() {}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: generic parameters may not be used in const operations
2+
--> $DIR/rhs-but-not-root.rs:8:49
3+
|
4+
LL | const FOO<const N: usize>: usize = ID::<const { N + 1 }>;
5+
| ^
6+
7+
error: aborting due to 1 previous error
8+

0 commit comments

Comments
 (0)