Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 2 additions & 61 deletions compiler/rustc_hir_analysis/src/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
//! crate as a kind of pass. This should eventually be factored away.

use std::cell::Cell;
use std::ops::ControlFlow;
use std::{assert_matches, iter};

use rustc_abi::{ExternAbi, Size};
Expand All @@ -24,13 +23,12 @@ use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_errors::{
Applicability, Diag, DiagCtxtHandle, Diagnostic, E0228, ErrorGuaranteed, Level, StashKey,
};
use rustc_hir::def::{DefKind, Res};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::{self, InferKind, Visitor, VisitorExt};
use rustc_hir::intravisit::{InferKind, Visitor, VisitorExt};
use rustc_hir::{self as hir, GenericParamKind, HirId, Node, PreciseCapturingArgKind, find_attr};
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
use rustc_infer::traits::{DynCompatibilityViolation, ObligationCause};
use rustc_middle::hir::nested_filter;
use rustc_middle::query::Providers;
use rustc_middle::ty::util::{Discr, IntTypeExt};
use rustc_middle::ty::{
Expand Down Expand Up @@ -1636,20 +1634,6 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin
let parent_hir_node = tcx.hir_node(tcx.parent_hir_id(const_arg_id));
if tcx.features().generic_const_exprs() {
ty::AnonConstKind::GCE
} else if tcx.features().generic_const_args() {
// Only anon consts that are the RHS of a const item can be GCA.
// Note: We can't just check tcx.parent because it needs to be EXACTLY
// the RHS, not just part of the RHS.
if !is_anon_const_rhs_of_const_item(tcx, def) {
return ty::AnonConstKind::MCG;
}

let body = tcx.hir_body_owned_by(def);
let mut visitor = GCAParamVisitor(tcx);
match visitor.visit_body(body) {
ControlFlow::Break(UsesParam) => ty::AnonConstKind::GCA,
ControlFlow::Continue(()) => ty::AnonConstKind::MCG,
}
} else if tcx.features().min_generic_const_args() {
ty::AnonConstKind::MCG
} else if let hir::Node::Expr(hir::Expr {
Expand All @@ -1667,49 +1651,6 @@ fn anon_const_kind<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ty::AnonConstKin
}
}

fn is_anon_const_rhs_of_const_item<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
let hir_id = tcx.local_def_id_to_hir_id(def_id);
let Some((_, grandparent_node)) = tcx.hir_parent_iter(hir_id).nth(1) else { return false };
let (Node::Item(hir::Item { kind: hir::ItemKind::Const(_, _, _, ct_rhs), .. })
| Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(_, ct_rhs), .. })
| Node::TraitItem(hir::TraitItem {
kind: hir::TraitItemKind::Const(_, Some(ct_rhs)), ..
})) = grandparent_node
else {
return false;
};
let hir::ConstItemRhs::TypeConst(hir::ConstArg {
kind: hir::ConstArgKind::Anon(rhs_anon), ..
}) = ct_rhs
else {
return false;
};
def_id == rhs_anon.def_id
}

struct GCAParamVisitor<'tcx>(TyCtxt<'tcx>);

struct UsesParam;

impl<'tcx> Visitor<'tcx> for GCAParamVisitor<'tcx> {
type NestedFilter = nested_filter::OnlyBodies;
type Result = ControlFlow<UsesParam>;

fn maybe_tcx(&mut self) -> TyCtxt<'tcx> {
self.0
}

fn visit_path(&mut self, path: &hir::Path<'tcx>, _id: HirId) -> ControlFlow<UsesParam> {
if let Res::Def(DefKind::TyParam | DefKind::ConstParam | DefKind::LifetimeParam, _) =
path.res
{
return ControlFlow::Break(UsesParam);
}

intravisit::walk_path(self, path)
}
}

#[instrument(level = "debug", skip(tcx), ret)]
fn const_of_item<'tcx>(
tcx: TyCtxt<'tcx>,
Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/generics_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
match tcx.anon_const_kind(def_id) {
// Stable: anon consts are not able to use any generic parameters...
ty::AnonConstKind::MCG => None,
// GCA anon consts inherit their parent's generics.
ty::AnonConstKind::GCA => Some(parent_did),
// we provide generics to repeat expr counts as a backwards compatibility hack. #76200
ty::AnonConstKind::RepeatExprCount => Some(parent_did),

Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,7 @@ impl<'tcx> ForbidParamUsesFolder<'tcx> {
}
ForbidParamContext::ConstArgument => {
if self.tcx.features().generic_const_args() {
"generic parameters in const blocks are only allowed as the direct value of a `type const`"
"generic parameters in const blocks are not allowed; use a named `const` item instead"
} else {
"generic parameters may not be used in const operations"
}
Expand Down Expand Up @@ -535,9 +535,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
None
}
}
ty::AnonConstKind::GCE
| ty::AnonConstKind::GCA
| ty::AnonConstKind::RepeatExprCount => None,
ty::AnonConstKind::GCE | ty::AnonConstKind::RepeatExprCount => None,
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_resolve/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ pub(crate) struct SelfInConstGenericTy {
#[derive(Diagnostic)]
#[diag(
"{$is_gca ->
[true] generic parameters in const blocks are only allowed as the direct value of a `type const`
[true] generic parameters in const blocks are not allowed; use a named `const` item instead
*[false] generic parameters may not be used in const operations
}"
)]
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_trait_selection/src/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,8 +688,7 @@ pub fn try_evaluate_const<'tcx>(

(args, typing_env)
}
Some((_, ty::AnonConstKind::GCA))
| Some((_, ty::AnonConstKind::MCG))
Some((_, ty::AnonConstKind::MCG))
| Some((_, ty::AnonConstKind::NonTypeSystem))
| None => {
// We are only dealing with "truly" generic/uninferred constants here:
Expand Down
3 changes: 0 additions & 3 deletions compiler/rustc_type_ir/src/const_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,6 @@ pub enum AnonConstKind {
GCE,
/// stable `min_const_generics` anon consts are not allowed to use any generic parameters
MCG,
/// `feature(generic_const_args)` anon consts are allowed to use arbitrary
/// generic parameters in scope, but only if they syntactically reference them.
GCA,
/// anon consts used as the length of a repeat expr are syntactically allowed to use generic parameters
/// but must not depend on the actual instantiation. See #76200 for more information
RepeatExprCount,
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/const-generics/gca/basic-different-definitions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
#![feature(generic_const_args)]
#![expect(incomplete_features)]

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

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

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

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/const-generics/gca/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#![feature(generic_const_args)]
#![expect(incomplete_features)]

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

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

Expand Down
10 changes: 5 additions & 5 deletions tests/ui/const-generics/gca/coherence-fail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

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

// computing the same value with the same constant item but different generic arguments should fail
type const DIV2<const N: usize>: usize = const { N / 2 };
const DIV2<const N: usize>: usize = N / 2;
trait Trait2 {}
impl Trait2 for [(); DIV2::<2>] {}
impl Trait2 for [(); DIV2::<3>] {}
Expand All @@ -20,8 +20,8 @@ impl Trait2 for [(); DIV2::<3>] {}
// computing the same value with different constant items and different generic arguments should
// fail
trait Trait3 {}
type const ADD1<const N: usize>: usize = const { N + 1 };
type const SUB1<const N: usize>: usize = const { N - 1 };
const ADD1<const N: usize>: usize = N + 1;
const SUB1<const N: usize>: usize = N - 1;
impl Trait3 for [(); ADD1::<1>] {}
impl Trait3 for [(); SUB1::<3>] {}
//~^ ERROR conflicting implementations of trait `Trait3` for type `[(); 2]`
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/const-generics/gca/coherence-ok.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

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

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

trait Trait {}

Expand Down
9 changes: 9 additions & 0 deletions tests/ui/const-generics/gca/gca-anon-const-rejected.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//@ compile-flags: -Znext-solver
// Test that anonymous const blocks using generic parameters are rejected
// under `generic_const_args`. Users should use named const items instead:
// `const FOO<const N: usize>: usize = N + 1;`
#![feature(generic_const_args, min_generic_const_args, generic_const_items)]

type const FOO<const N: usize>: usize = const { N + 1 }; //~ ERROR generic parameters in const blocks are not allowed; use a named `const` item instead

fn main() {}
10 changes: 10 additions & 0 deletions tests/ui/const-generics/gca/gca-anon-const-rejected.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
error: generic parameters in const blocks are not allowed; use a named `const` item instead
--> $DIR/gca-anon-const-rejected.rs:7:49
|
LL | type const FOO<const N: usize>: usize = const { N + 1 };
| ^
|
= help: consider factoring the expression into a `type const` item and use it as the const argument instead

error: aborting due to 1 previous error

2 changes: 1 addition & 1 deletion tests/ui/const-generics/gca/generic-param-rhs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@
fn foo<const N: usize>() {}
fn bar<const N: usize>() {
foo::<const { N + 1 }>();
//~^ ERROR: generic parameters in const blocks are only allowed as the direct value of a `type const`
//~^ ERROR: generic parameters in const blocks are not allowed; use a named `const` item instead
}
fn main(){}
2 changes: 1 addition & 1 deletion tests/ui/const-generics/gca/generic-param-rhs.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: generic parameters in const blocks are only allowed as the direct value of a `type const`
error: generic parameters in const blocks are not allowed; use a named `const` item instead
--> $DIR/generic-param-rhs.rs:7:19
|
LL | foo::<const { N + 1 }>();
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/const-generics/gca/rhs-but-not-root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

// Anon consts must be the root of the RHS to be GCA.
type const FOO<const N: usize>: usize = ID::<const { N + 1 }>;
//~^ ERROR generic parameters in const blocks are only allowed as the direct value of a `type const`
//~^ ERROR generic parameters in const blocks are not allowed; use a named `const` item instead
type const ID<const N: usize>: usize = N;

fn main() {}
2 changes: 1 addition & 1 deletion tests/ui/const-generics/gca/rhs-but-not-root.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error: generic parameters in const blocks are only allowed as the direct value of a `type const`
error: generic parameters in const blocks are not allowed; use a named `const` item instead
--> $DIR/rhs-but-not-root.rs:8:54
|
LL | type const FOO<const N: usize>: usize = ID::<const { N + 1 }>;
Expand Down
Loading