Skip to content

Commit a5e1bb2

Browse files
Rollup merge of rust-lang#157773 - LaneAsade:generic_anon_consts, r=BoxyUwU
Remove AnonConstKind::GCA and reject generic anon consts Previously, a `GCA` type const (`type const FOO<const N: usize>: usize = const { N + 1 };`) was a type-system-transparent type const whose body immediately thunked out to an opaque regular const (albeit an anon const). The fact that there was a transparent wrapper wasn't providing anything of value, now that the user can write and rust-lang#155341. With this PR, `GCA` variant is removed from `AnonConstKind` so that generic anon consts are rejected. Related: rust-lang/project-const-generics#113
2 parents b29de6d + 71523aa commit a5e1bb2

16 files changed

Lines changed: 38 additions & 86 deletions

File tree

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 2 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
//! crate as a kind of pass. This should eventually be factored away.
1616
1717
use std::cell::Cell;
18-
use std::ops::ControlFlow;
1918
use std::{assert_matches, iter};
2019

2120
use rustc_abi::{ExternAbi, Size};
@@ -24,13 +23,12 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
2423
use rustc_errors::{
2524
Applicability, Diag, DiagCtxtHandle, Diagnostic, E0228, ErrorGuaranteed, Level, StashKey,
2625
};
27-
use rustc_hir::def::{DefKind, Res};
26+
use rustc_hir::def::DefKind;
2827
use rustc_hir::def_id::{DefId, LocalDefId};
29-
use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt};
28+
use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt};
3029
use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind, find_attr};
3130
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
3231
use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause};
33-
use rustc_middle::hir::nested_filter;
3432
use rustc_middle::query::Providers;
3533
use rustc_middle::ty::util::{Discr, IntTypeExt};
3634
use rustc_middle::ty::{
@@ -1636,20 +1634,6 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin
16361634
let parent_hir_node = tcx.hir_node(tcx.parent_hir_id(const_arg_id));
16371635
if tcx.features().generic_const_exprs() {
16381636
ty::AnonConstKind::GCE
1639-
} else if tcx.features().generic_const_args() {
1640-
// Only anon consts that are the RHS of a const item can be GCA.
1641-
// Note: We can't just check tcx.parent because it needs to be EXACTLY
1642-
// the RHS, not just part of the RHS.
1643-
if !is_anon_const_rhs_of_const_item(tcx, def) {
1644-
return ty::AnonConstKind::MCG;
1645-
}
1646-
1647-
let body = tcx.hir_body_owned_by(def);
1648-
let mut visitor = GCAParamVisitor(tcx);
1649-
match visitor.visit_body(body) {
1650-
ControlFlow::Break(UsesParam) => ty::AnonConstKind::GCA,
1651-
ControlFlow::Continue(()) => ty::AnonConstKind::MCG,
1652-
}
16531637
} else if tcx.features().min_generic_const_args() {
16541638
ty::AnonConstKind::MCG
16551639
} else if let hir::Node::Expr(hir::Expr {
@@ -1667,49 +1651,6 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin
16671651
}
16681652
}
16691653

1670-
fn is_anon_const_rhs_of_const_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
1671-
let hir_id = tcx.local_def_id_to_hir_id(def_id);
1672-
let Some((_, grandparent_node)) = tcx.hir_parent_iter(hir_id).nth(1) else { return false };
1673-
let (Node::Item(hir::Item { kind: hir::ItemKind::Const(_, _, _, ct_rhs), .. })
1674-
| Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(_, ct_rhs), .. })
1675-
| Node::TraitItem(hir::TraitItem {
1676-
kind: hir::TraitItemKind::Const(_, Some(ct_rhs)), ..
1677-
})) = grandparent_node
1678-
else {
1679-
return false;
1680-
};
1681-
let hir::ConstItemRhs::TypeConst(hir::ConstArg {
1682-
kind: hir::ConstArgKind::Anon(rhs_anon), ..
1683-
}) = ct_rhs
1684-
else {
1685-
return false;
1686-
};
1687-
def_id == rhs_anon.def_id
1688-
}
1689-
1690-
struct GCAParamVisitor<'tcx>(TyCtxt<'tcx>);
1691-
1692-
struct UsesParam;
1693-
1694-
impl<'tcx> Visitor<'tcx> for GCAParamVisitor<'tcx> {
1695-
type NestedFilter = nested_filter::OnlyBodies;
1696-
type Result = ControlFlow<UsesParam>;
1697-
1698-
fn maybe_tcx(&mut self) -> TyCtxt<'tcx> {
1699-
self.0
1700-
}
1701-
1702-
fn visit_path(&mut self, path: &hir::Path<'tcx>, _id: HirId) -> ControlFlow<UsesParam> {
1703-
if let Res::Def(DefKind::TyParam | DefKind::ConstParam | DefKind::LifetimeParam, _) =
1704-
path.res
1705-
{
1706-
return ControlFlow::Break(UsesParam);
1707-
}
1708-
1709-
intravisit::walk_path(self, path)
1710-
}
1711-
}
1712-
17131654
#[instrument(level = "debug", skip(tcx), ret)]
17141655
fn const_of_item<'tcx>(
17151656
tcx: TyCtxt<'tcx>,

compiler/rustc_hir_analysis/src/collect/generics_of.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
9797
match tcx.anon_const_kind(def_id) {
9898
// Stable: anon consts are not able to use any generic parameters...
9999
ty::AnonConstKind::MCG => None,
100-
// GCA anon consts inherit their parent's generics.
101-
ty::AnonConstKind::GCA => Some(parent_did),
102100
// we provide generics to repeat expr counts as a backwards compatibility hack. #76200
103101
ty::AnonConstKind::RepeatExprCount => Some(parent_did),
104102

compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ impl<'tcx> ForbidParamUsesFolder<'tcx> {
409409
}
410410
ForbidParamContext::ConstArgument => {
411411
if self.tcx.features().generic_const_args() {
412-
"generic parameters in const blocks are only allowed as the direct value of a `type const`"
412+
"generic parameters in const blocks are not allowed; use a named `const` item instead"
413413
} else {
414414
"generic parameters may not be used in const operations"
415415
}
@@ -535,9 +535,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
535535
None
536536
}
537537
}
538-
ty::AnonConstKind::GCE
539-
| ty::AnonConstKind::GCA
540-
| ty::AnonConstKind::RepeatExprCount => None,
538+
ty::AnonConstKind::GCE | ty::AnonConstKind::RepeatExprCount => None,
541539
}
542540
}
543541

compiler/rustc_resolve/src/errors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ pub(crate) struct SelfInConstGenericTy {
389389
#[derive(Diagnostic)]
390390
#[diag(
391391
"{$is_gca ->
392-
[true] generic parameters in const blocks are only allowed as the direct value of a `type const`
392+
[true] generic parameters in const blocks are not allowed; use a named `const` item instead
393393
*[false] generic parameters may not be used in const operations
394394
}"
395395
)]

compiler/rustc_trait_selection/src/traits/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -688,8 +688,7 @@ pub fn try_evaluate_const<'tcx>(
688688

689689
(args, typing_env)
690690
}
691-
Some((_, ty::AnonConstKind::GCA))
692-
| Some((_, ty::AnonConstKind::MCG))
691+
Some((_, ty::AnonConstKind::MCG))
693692
| Some((_, ty::AnonConstKind::NonTypeSystem))
694693
| None => {
695694
// We are only dealing with "truly" generic/uninferred constants here:

compiler/rustc_type_ir/src/const_kind.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,9 +289,6 @@ pub enum AnonConstKind {
289289
GCE,
290290
/// stable `min_const_generics` anon consts are not allowed to use any generic parameters
291291
MCG,
292-
/// `feature(generic_const_args)` anon consts are allowed to use arbitrary
293-
/// generic parameters in scope, but only if they syntactically reference them.
294-
GCA,
295292
/// anon consts used as the length of a repeat expr are syntactically allowed to use generic parameters
296293
/// but must not depend on the actual instantiation. See #76200 for more information
297294
RepeatExprCount,

tests/ui/const-generics/gca/basic-different-definitions.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
#![feature(generic_const_args)]
77
#![expect(incomplete_features)]
88

9-
type const ADD1<const N: usize>: usize = const { N + 1 };
9+
const ADD1<const N: usize>: usize = N + 1;
1010

11-
type const INC<const N: usize>: usize = const { N + 1 };
11+
const INC<const N: usize>: usize = N + 1;
1212

1313
type const ONE: usize = ADD1::<0>;
1414

tests/ui/const-generics/gca/basic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#![feature(generic_const_args)]
77
#![expect(incomplete_features)]
88

9-
type const ADD1<const N: usize>: usize = const { N + 1 };
9+
const ADD1<const N: usize>: usize = N + 1;
1010

1111
type const INC<const N: usize>: usize = ADD1::<N>;
1212

tests/ui/const-generics/gca/coherence-fail.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44

55
// computing the same value with different constant items but same generic arguments should fail
66
trait Trait1 {}
7-
type const FOO<const N: usize>: usize = const { N + 1 };
8-
type const BAR<const N: usize>: usize = const { N + 1 };
7+
const FOO<const N: usize>: usize = N + 1;
8+
const BAR<const N: usize>: usize = N + 1;
99
impl Trait1 for [(); FOO::<1>] {}
1010
impl Trait1 for [(); BAR::<1>] {}
1111
//~^ ERROR conflicting implementations of trait `Trait1` for type `[(); 2]`
1212

1313
// computing the same value with the same constant item but different generic arguments should fail
14-
type const DIV2<const N: usize>: usize = const { N / 2 };
14+
const DIV2<const N: usize>: usize = N / 2;
1515
trait Trait2 {}
1616
impl Trait2 for [(); DIV2::<2>] {}
1717
impl Trait2 for [(); DIV2::<3>] {}
@@ -20,8 +20,8 @@ impl Trait2 for [(); DIV2::<3>] {}
2020
// computing the same value with different constant items and different generic arguments should
2121
// fail
2222
trait Trait3 {}
23-
type const ADD1<const N: usize>: usize = const { N + 1 };
24-
type const SUB1<const N: usize>: usize = const { N - 1 };
23+
const ADD1<const N: usize>: usize = N + 1;
24+
const SUB1<const N: usize>: usize = N - 1;
2525
impl Trait3 for [(); ADD1::<1>] {}
2626
impl Trait3 for [(); SUB1::<3>] {}
2727
//~^ ERROR conflicting implementations of trait `Trait3` for type `[(); 2]`

tests/ui/const-generics/gca/coherence-ok.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
// computing different values with the same type const item should be fine
77

8-
type const ADD1<const N: usize>: usize = const { N + 1 };
8+
const ADD1<const N: usize>: usize = N + 1;
99

1010
trait Trait {}
1111

0 commit comments

Comments
 (0)