Skip to content

Commit 2960124

Browse files
committed
Only use AnonConstKind::OGCA for const item RHS's
1 parent 0fbe68a commit 2960124

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
@@ -1512,6 +1512,13 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin
15121512
if tcx.features().generic_const_exprs() {
15131513
ty::AnonConstKind::GCE
15141514
} else if tcx.features().opaque_generic_const_args() {
1515+
// Only anon consts that are the RHS of a const item can be OGCA.
1516+
// Note: We can't just check tcx.parent because it needs to be EXACTLY
1517+
// the RHS, not just part of the RHS.
1518+
if !is_anon_const_rhs_of_const_item(tcx, def) {
1519+
return ty::AnonConstKind::MCG;
1520+
}
1521+
15151522
let body = tcx.hir_body_owned_by(def);
15161523
let mut visitor = OGCAParamVisitor(tcx);
15171524
match visitor.visit_body(body) {
@@ -1535,6 +1542,26 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin
15351542
}
15361543
}
15371544

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

15401567
struct UsesParam;
@@ -1547,7 +1574,7 @@ impl<'tcx> Visitor<'tcx> for OGCAParamVisitor<'tcx> {
15471574
self.0
15481575
}
15491576

1550-
fn visit_path(&mut self, path: &crate::hir::Path<'tcx>, _id: HirId) -> ControlFlow<UsesParam> {
1577+
fn visit_path(&mut self, path: &hir::Path<'tcx>, _id: HirId) -> ControlFlow<UsesParam> {
15511578
if let Res::Def(DefKind::TyParam | DefKind::ConstParam | DefKind::LifetimeParam, _) =
15521579
path.res
15531580
{
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)