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
16 changes: 9 additions & 7 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1760,13 +1760,15 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
let tcx = self.tcx();
let maybe_uneval = match constant.const_ {
Const::Ty(_, ct) => match ct.kind() {
ty::ConstKind::Unevaluated(_, uv) => match uv.kind {
ty::UnevaluatedConstKind::Projection { def_id }
| ty::UnevaluatedConstKind::Inherent { def_id }
| ty::UnevaluatedConstKind::Free { def_id }
| ty::UnevaluatedConstKind::Anon { def_id } => {
Some(UnevaluatedConst { def: def_id, args: uv.args, promoted: None })
}
ty::ConstKind::Alias(_, alias_const) => match alias_const.kind {
ty::AliasConstKind::Projection { def_id }
| ty::AliasConstKind::Inherent { def_id }
| ty::AliasConstKind::Free { def_id }
| ty::AliasConstKind::Anon { def_id } => Some(UnevaluatedConst {
def: def_id,
args: alias_const.args,
promoted: None,
}),
},
_ => None,
},
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_const_eval/src/check_consts/qualifs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,13 +344,13 @@ where
let uneval = match constant.const_ {
Const::Ty(_, ct) => match ct.kind() {
ty::ConstKind::Param(_) | ty::ConstKind::Error(_) => None,
// Unevaluated consts in MIR bodies don't have associated MIR (e.g. `type const`).
ty::ConstKind::Unevaluated(_, _) => None,
// Alias consts in MIR bodies don't have associated MIR (e.g. `type const`).
ty::ConstKind::Alias(_, _) => None,
// FIXME(mgca): Investigate whether using `None` for `ConstKind::Value` is overly
// strict, and if instead we should be doing some kind of value-based analysis.
ty::ConstKind::Value(_) => None,
_ => bug!(
"expected ConstKind::Param, ConstKind::Value, ConstKind::Unevaluated, or ConstKind::Error here, found {:?}",
"expected ConstKind::Param, ConstKind::Value, ConstKind::Alias, or ConstKind::Error here, found {:?}",
ct
),
},
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -778,8 +778,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
if has_default {
// need to store default and type of default
let ct = tcx.const_param_default(param.def_id).skip_binder();
if let ty::ConstKind::Unevaluated(_, uv) = ct.kind()
&& let Some(def_id) = uv.kind.opt_def_id()
if let ty::ConstKind::Alias(_, alias_const) = ct.kind()
&& let Some(def_id) = alias_const.kind.opt_def_id()
{
tcx.ensure_ok().type_of(def_id);
}
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1488,7 +1488,7 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id:
// be sure if it will error or not as user might always specify the other.
// FIXME(generic_const_exprs): This is incorrect when dealing with unused const params.
// E.g: `struct Foo<const N: usize, const M: usize = { 1 - 2 }>;`. Here, we should
// eagerly error but we don't as we have `ConstKind::Unevaluated(.., [N, M])`.
// eagerly error but we don't as we have `ConstKind::Alias(.., [N, M])`.
if !default.has_param() {
wfcx.register_wf_obligation(
tcx.def_span(param.def_id),
Expand All @@ -1509,7 +1509,9 @@ pub(super) fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, def_id:
| ty::ConstKind::Bound(_, _) => unreachable!(),
ty::ConstKind::Error(_) | ty::ConstKind::Expr(_) => continue,
ty::ConstKind::Value(cv) => cv.ty,
ty::ConstKind::Unevaluated(_, uv) => uv.type_of(infcx.tcx).skip_norm_wip(),
ty::ConstKind::Alias(_, alias_const) => {
alias_const.type_of(infcx.tcx).skip_norm_wip()
}
ty::ConstKind::Param(param_ct) => {
param_ct.find_const_ty_from_env(wfcx.param_env)
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/collect/generics_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,11 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
// ^ parent_def_id
//
// then we only want to return generics for params to the left of `N`. If we don't do that we
// end up with that const looking like: `ty::ConstKind::Unevaluated(def_id, args: [N#0])`.
// end up with that const looking like: `ty::ConstKind::Alias(def_id, args: [N#0])`.
//
// This causes ICEs (#86580) when building the args for Foo in `fn foo() -> Foo { .. }` as
// we instantiate the defaults with the partially built args when we build the args. Instantiating
// the `N#0` on the unevaluated const indexes into the empty args we're in the process of building.
// the `N#0` on the alias const indexes into the empty args we're in the process of building.
//
// We fix this by having this function return the parent's generics ourselves and truncating the
// generics to only include non-forward declared params (with the exception of the `Self` ty)
Expand Down
12 changes: 6 additions & 6 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -415,8 +415,8 @@ fn const_evaluatable_predicates_of<'tcx>(
preds: FxIndexSet<(ty::Clause<'tcx>, Span)>,
}

fn is_const_param_default(tcx: TyCtxt<'_>, kind: ty::UnevaluatedConstKind<'_>) -> bool {
let ty::UnevaluatedConstKind::Anon { def_id } = kind else { return false };
fn is_const_param_default(tcx: TyCtxt<'_>, kind: ty::AliasConstKind<'_>) -> bool {
let ty::AliasConstKind::Anon { def_id } = kind else { return false };
let Some(local) = def_id.as_local() else { return false };

let hir_id = tcx.local_def_id_to_hir_id(local);
Expand All @@ -433,8 +433,8 @@ fn const_evaluatable_predicates_of<'tcx>(

impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ConstCollector<'tcx> {
fn visit_const(&mut self, c: ty::Const<'tcx>) {
if let ty::ConstKind::Unevaluated(_, uv) = c.kind() {
if is_const_param_default(self.tcx, uv.kind) {
if let ty::ConstKind::Alias(_, alias_const) = c.kind() {
if is_const_param_default(self.tcx, alias_const.kind) {
// Do not look into const param defaults,
// these get checked when they are actually instantiated.
//
Expand All @@ -446,11 +446,11 @@ fn const_evaluatable_predicates_of<'tcx>(
}

// Skip type consts as mGCA doesn't support evaluatable clauses.
if uv.kind.is_type_const(self.tcx) {
if alias_const.kind.is_type_const(self.tcx) {
return;
}

let span = uv.kind.def_span(self.tcx);
let span = alias_const.kind.def_span(self.tcx);
self.preds.insert((ty::ClauseKind::ConstEvaluatable(c).upcast(self.tcx), span));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParameterCollector {

fn visit_const(&mut self, c: ty::Const<'tcx>) {
match c.kind() {
ty::ConstKind::Unevaluated(..) if !self.include_nonconstraining => {
ty::ConstKind::Alias(..) if !self.include_nonconstraining => {
// Constant expressions are not injective in general.
return;
}
Expand Down
24 changes: 10 additions & 14 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1402,7 +1402,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
if let Some(def_id) = alias_ct.kind.opt_def_id() {
self.require_type_const_attribute(def_id, span)?;
}
let ct = Const::new_unevaluated(tcx, ty::IsRigid::No, alias_ct);
let ct = Const::new_alias(tcx, ty::IsRigid::No, alias_ct);
let ct = self.check_param_uses_if_mcg(ct, span, false);
Ok(ct)
}
Expand Down Expand Up @@ -1865,12 +1865,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
ty::AssocTag::Const,
)?;
self.require_type_const_attribute(item_def_id, span)?;
let uv = ty::UnevaluatedConst::new(
let alias_const = ty::AliasConst::new(
tcx,
ty::UnevaluatedConstKind::new_from_def_id(tcx, item_def_id),
ty::AliasConstKind::new_from_def_id(tcx, item_def_id),
item_args,
);
Ok(Const::new_unevaluated(tcx, ty::IsRigid::No, uv))
Ok(Const::new_alias(tcx, ty::IsRigid::No, alias_const))
}

/// Lower a [resolved][hir::QPath::Resolved] (type-level) associated item path.
Expand Down Expand Up @@ -2772,14 +2772,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
let _ = self
.prohibit_generic_args(leading_segments.iter(), GenericsArgsErrExtend::None);
let args = self.lower_generic_args_of_path_segment(span, did, segment);
ty::Const::new_unevaluated(
ty::Const::new_alias(
tcx,
ty::IsRigid::No,
ty::UnevaluatedConst::new(
tcx,
ty::UnevaluatedConstKind::new_from_def_id(tcx, did),
args,
),
ty::AliasConst::new(tcx, ty::AliasConstKind::new_from_def_id(tcx, did), args),
)
}
Res::Def(kind @ DefKind::Ctor(ctor_of, CtorKind::Const), did) => {
Expand Down Expand Up @@ -2915,7 +2911,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
self.check_param_uses_if_mcg(ct, span, false)
}

/// Literals are eagerly converted to a constant, everything else becomes `Unevaluated`.
/// Literals are eagerly converted to a constant, everything else becomes `ConstKind::Alias`.
#[instrument(skip(self), level = "debug")]
fn lower_const_arg_anon(&self, anon: &AnonConst) -> Const<'tcx> {
let tcx = self.tcx();
Expand All @@ -2930,12 +2926,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {

match self.try_lower_anon_const_lit(ty, expr) {
Some(v) => v,
None => ty::Const::new_unevaluated(
None => ty::Const::new_alias(
tcx,
ty::IsRigid::No,
ty::UnevaluatedConst::new(
ty::AliasConst::new(
tcx,
ty::UnevaluatedConstKind::Anon { def_id: anon.def_id.to_def_id() },
ty::AliasConstKind::Anon { def_id: anon.def_id.to_def_id() },
ty::GenericArgs::identity_for_item(tcx, anon.def_id.to_def_id()),
),
),
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_analysis/src/variance/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
debug!("add_constraints_from_const(c={:?}, variance={:?})", c, variance);

match &c.kind() {
ty::ConstKind::Unevaluated(_, uv) => {
self.add_constraints_from_invariant_args(current, uv.args, variance);
ty::ConstKind::Alias(_, alias_const) => {
self.add_constraints_from_invariant_args(current, alias_const.args, variance);
}
_ => {}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1453,7 +1453,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let ct = self.resolve_vars_with_obligations(ct);

if self.next_trait_solver()
&& let ty::ConstKind::Unevaluated(..) = ct.kind()
&& let ty::ConstKind::Alias(..) = ct.kind()
{
// We need to use a separate variable here as otherwise the temporary for
// `self.fulfillment_cx.borrow_mut()` is alive in the `Err` branch, resulting
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::ConstKind::Param(_)
| ty::ConstKind::Expr(_)
| ty::ConstKind::Placeholder(_)
| ty::ConstKind::Unevaluated(_, _) => enforce_copy_bound(element, element_ty),
| ty::ConstKind::Alias(_, _) => enforce_copy_bound(element, element_ty),

ty::ConstKind::Bound(_, _) | ty::ConstKind::Infer(_) | ty::ConstKind::Error(_) => {
unreachable!()
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/freshen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> {

ty::ConstKind::Param(_)
| ty::ConstKind::Value(_)
| ty::ConstKind::Unevaluated(..)
| ty::ConstKind::Alias(..)
| ty::ConstKind::Expr(..)
| ty::ConstKind::Error(_) => ct.super_fold_with(self),
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,7 @@ impl<'tcx> InferCtxt<'tcx> {
ty::ConstKind::Param(_)
| ty::ConstKind::Bound(_, _)
| ty::ConstKind::Placeholder(_)
| ty::ConstKind::Unevaluated(_, _)
| ty::ConstKind::Alias(_, _)
| ty::ConstKind::Value(_)
| ty::ConstKind::Error(_)
| ty::ConstKind::Expr(_) => ct,
Expand Down
20 changes: 10 additions & 10 deletions compiler/rustc_infer/src/infer/relate/generalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ impl<'tcx> InferCtxt<'tcx> {
/// would result in an infinite type as we continuously replace an inference variable
/// in `ct` with `ct` itself.
///
/// This is especially important as unevaluated consts use their parents generics.
/// This is especially important as alias consts use their parents generics.
/// They therefore often contain unused args, making these errors far more likely.
///
/// A good example of this is the following:
Expand All @@ -95,7 +95,7 @@ impl<'tcx> InferCtxt<'tcx> {
/// }
/// ```
///
/// Here `3 + 4` ends up as `ConstKind::Unevaluated` which uses the generics
/// Here `3 + 4` ends up as `ConstKind::Alias` which uses the generics
/// of `fn bind` (meaning that its args contain `N`).
///
/// `bind(arr)` now infers that the type of `arr` must be `[u8; N]`.
Expand All @@ -112,8 +112,8 @@ impl<'tcx> InferCtxt<'tcx> {
target_vid: ty::ConstVid,
source_ct: ty::Const<'tcx>,
) -> RelateResult<'tcx, ()> {
// FIXME(generic_const_exprs): Occurs check failures for unevaluated
// constants and generic expressions are not yet handled correctly.
// FIXME(generic_const_exprs): Occurs check failures for alias consts
// and generic expressions are not yet handled correctly.
debug_assert!(
self.inner.borrow_mut().const_unification_table().probe_value(target_vid).is_unknown()
);
Expand Down Expand Up @@ -752,34 +752,34 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
}
}
}
// FIXME: Unevaluated constants are also not rigid, so the current
// FIXME: Alias consts are also not rigid, so the current
// approach of always relating them structurally is incomplete.
//
// FIXME: replace the StructurallyRelateAliases::Yes branch with
// `structurally_relate_consts` once it is fully structural.
//
// We only need to be careful with potentially normalizeable
// aliases here. See `generalize_alias_term` for more information.
ty::ConstKind::Unevaluated(ty::IsRigid::No, uv) => {
ty::ConstKind::Alias(ty::IsRigid::No, alias_const) => {
match self.structurally_relate_aliases {
// Hack: Fall back to old behavior if GCE is enabled (it used to just be the Yes
// path), as doing this new No path breaks some GCE things. I expect GCE to be
// ripped out soon so this shouldn't matter soon.
StructurallyRelateAliases::No if !tcx.features().generic_const_exprs() => {
self.generalize_alias_term(uv.into()).map(|v| v.expect_const())
self.generalize_alias_term(alias_const.into()).map(|v| v.expect_const())
}
_ => {
let ty::UnevaluatedConst { kind, args, .. } = uv;
let ty::AliasConst { kind, args, .. } = alias_const;
let args = self.relate_with_variance(
ty::Invariant,
ty::VarianceDiagInfo::default(),
args,
args,
)?;
Ok(ty::Const::new_unevaluated(
Ok(ty::Const::new_alias(
tcx,
ty::IsRigid::No,
ty::UnevaluatedConst::new(tcx, kind, args),
ty::AliasConst::new(tcx, kind, args),
))
}
}
Expand Down
10 changes: 3 additions & 7 deletions compiler/rustc_middle/src/mir/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ pub enum Const<'tcx> {

/// An unevaluated mir constant which is not part of the type system.
///
/// Note that `Ty(ty::ConstKind::Unevaluated)` and this variant are *not* identical! `Ty` will
/// Note that `Ty(ty::ConstKind::Alias)` and this variant are *not* identical! `Ty` will
/// always flow through a valtree, so all data not captured in the valtree is lost. This variant
/// directly uses the evaluated result of the given constant, including e.g. data stored in
/// padding.
Expand Down Expand Up @@ -472,13 +472,9 @@ pub struct UnevaluatedConst<'tcx> {

impl<'tcx> UnevaluatedConst<'tcx> {
#[inline]
pub fn shrink(self, tcx: TyCtxt<'tcx>) -> ty::UnevaluatedConst<'tcx> {
pub fn shrink(self, tcx: TyCtxt<'tcx>) -> ty::AliasConst<'tcx> {
assert_eq!(self.promoted, None);
ty::UnevaluatedConst::new(
tcx,
ty::UnevaluatedConstKind::new_from_def_id(tcx, self.def),
self.args,
)
ty::AliasConst::new(tcx, ty::AliasConstKind::new_from_def_id(tcx, self.def), self.args)
}
}

Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_middle/src/mir/interpret/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn const_eval_resolve_for_typeck(
self,
typing_env: ty::TypingEnv<'tcx>,
ct: ty::UnevaluatedConst<'tcx>,
ct: ty::AliasConst<'tcx>,
span: Span,
) -> ConstToValTreeResult<'tcx> {
// Cannot resolve `Unevaluated` constants that contain inference
Expand All @@ -104,10 +104,10 @@ impl<'tcx> TyCtxt<'tcx> {
}

let def_id = match ct.kind {
ty::UnevaluatedConstKind::Projection { def_id }
| ty::UnevaluatedConstKind::Inherent { def_id }
| ty::UnevaluatedConstKind::Free { def_id }
| ty::UnevaluatedConstKind::Anon { def_id } => def_id,
ty::AliasConstKind::Projection { def_id }
| ty::AliasConstKind::Inherent { def_id }
| ty::AliasConstKind::Free { def_id }
| ty::AliasConstKind::Anon { def_id } => def_id,
};

let cid = match ty::Instance::try_resolve(self, typing_env, def_id, ct.args) {
Expand Down
Loading
Loading