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
8 changes: 5 additions & 3 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1760,9 +1760,11 @@ 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) => {
Some(UnevaluatedConst { def: uv.def, args: uv.args, promoted: None })
}
ty::ConstKind::Unevaluated(uv) => Some(UnevaluatedConst {
def: uv.kind.def_id(),
args: uv.args,
promoted: None,
}),
_ => None,
},
Const::Unevaluated(uv, _) => Some(uv),
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_codegen_ssa/src/mir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
&self,
constant: &mir::ConstOperand<'tcx>,
) -> Result<Result<ty::ValTree<'tcx>, Ty<'tcx>>, ErrorHandled> {
let tcx = self.cx.tcx();
let uv = match self.monomorphize(constant.const_) {
mir::Const::Unevaluated(uv, _) => uv.shrink(),
mir::Const::Unevaluated(uv, _) => uv.shrink(tcx),
mir::Const::Ty(_, c) => match c.kind() {
// A constant that came from a const generic but was then used as an argument to
// old-style simd_shuffle (passing as argument instead of as a generic param).
Expand All @@ -57,7 +58,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
other => span_bug!(constant.span, "{other:#?}"),
};
let uv = self.monomorphize(uv);
self.cx.tcx().const_eval_resolve_for_typeck(self.cx.typing_env(), uv, constant.span)
tcx.const_eval_resolve_for_typeck(self.cx.typing_env(), uv, constant.span)
}

/// process constant containing SIMD shuffle indices & constant vectors
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(),
// 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() {
tcx.ensure_ok().type_of(uv.def);
tcx.ensure_ok().type_of(uv.kind.def_id());
}
}
}
Expand Down
8 changes: 5 additions & 3 deletions compiler/rustc_hir_analysis/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1535,9 +1535,11 @@ 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) => {
infcx.tcx.type_of(uv.def).instantiate(infcx.tcx, uv.args).skip_norm_wip()
}
ty::ConstKind::Unevaluated(uv) => infcx
.tcx
.type_of(uv.kind.def_id())
.instantiate(infcx.tcx, uv.args)
.skip_norm_wip(),
ty::ConstKind::Param(param_ct) => {
param_ct.find_const_ty_from_env(wfcx.param_env)
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ 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 let Some(local) = uv.def.as_local()
if let Some(local) = uv.kind.def_id().as_local()
&& is_const_param_default(self.tcx, local)
{
// Do not look into const param defaults,
Expand All @@ -449,11 +449,11 @@ fn const_evaluatable_predicates_of<'tcx>(
}

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

let span = self.tcx.def_span(uv.def);
let span = self.tcx.def_span(uv.kind.def_id());
self.preds.insert((ty::ClauseKind::ConstEvaluatable(c).upcast(self.tcx), span));
}
}
Expand Down
36 changes: 28 additions & 8 deletions compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1518,7 +1518,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
)? {
TypeRelativePath::AssocItem(def_id, args) => {
self.require_type_const_attribute(def_id, span)?;
let ct = Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(def_id, args));
let ct = Const::new_unevaluated(
tcx,
ty::UnevaluatedConst::new(
tcx,
ty::UnevaluatedConstKind::new_from_def_id(tcx, def_id),
args,
),
);
let ct = self.check_param_uses_if_mcg(ct, span, false);
Ok(ct)
}
Expand Down Expand Up @@ -2008,6 +2015,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
trait_segment: Option<&hir::PathSegment<'tcx>>,
item_segment: &hir::PathSegment<'tcx>,
) -> Result<Const<'tcx>, ErrorGuaranteed> {
let tcx = self.tcx();
let (item_def_id, item_args) = self.lower_resolved_assoc_item_path(
span,
opt_self_ty,
Expand All @@ -2017,8 +2025,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
ty::AssocTag::Const,
)?;
self.require_type_const_attribute(item_def_id, span)?;
let uv = ty::UnevaluatedConst::new(item_def_id, item_args);
Ok(Const::new_unevaluated(self.tcx(), uv))
let uv = ty::UnevaluatedConst::new(
tcx,
ty::UnevaluatedConstKind::new_from_def_id(tcx, item_def_id),
item_args,
);
Ok(Const::new_unevaluated(tcx, uv))
}

/// Lower a [resolved][hir::QPath::Resolved] (type-level) associated item path.
Expand Down Expand Up @@ -2860,7 +2872,14 @@ 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(tcx, ty::UnevaluatedConst::new(did, args))
ty::Const::new_unevaluated(
tcx,
ty::UnevaluatedConst::new(
tcx,
ty::UnevaluatedConstKind::new_from_def_id(tcx, did),
args,
),
)
}
Res::Def(DefKind::Ctor(ctor_of, CtorKind::Const), did) => {
assert_eq!(opt_self_ty, None);
Expand Down Expand Up @@ -2984,10 +3003,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
Some(v) => v,
None => ty::Const::new_unevaluated(
tcx,
ty::UnevaluatedConst {
def: anon.def_id.to_def_id(),
args: ty::GenericArgs::identity_for_item(tcx, anon.def_id.to_def_id()),
},
ty::UnevaluatedConst::new(
tcx,
ty::UnevaluatedConstKind::Anon { def_id: anon.def_id.to_def_id() },
ty::GenericArgs::identity_for_item(tcx, anon.def_id.to_def_id()),
),
),
}
}
Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_infer/src/infer/relate/generalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ impl<'tcx> InferCtxt<'tcx> {

relation.register_predicates([ty::PredicateKind::AliasRelate(lhs, rhs, direction)]);
} else {
let Some(source_alias) = source_term.to_alias_term(self.tcx) else {
let Some(source_alias) = source_term.to_alias_term() else {
bug!("generalized `{source_term:?} to infer, not an alias");
};
match source_alias.kind(self.tcx) {
Expand All @@ -207,7 +207,7 @@ impl<'tcx> InferCtxt<'tcx> {
}
ty::AliasTermKind::InherentConst { .. }
| ty::AliasTermKind::FreeConst { .. }
| ty::AliasTermKind::UnevaluatedConst { .. } => {
| ty::AliasTermKind::AnonConst { .. } => {
return Err(TypeError::CyclicConst(source_term.expect_const()));
}
}
Expand Down Expand Up @@ -701,6 +701,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
c: ty::Const<'tcx>,
c2: ty::Const<'tcx>,
) -> RelateResult<'tcx, ty::Const<'tcx>> {
let tcx = self.cx();
assert_eq!(c, c2); // we are misusing TypeRelation here; both LHS and RHS ought to be ==

match c.kind() {
Expand Down Expand Up @@ -741,7 +742,7 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
{
variable_table.union(vid, new_var_id);
}
Ok(ty::Const::new_var(self.cx(), new_var_id))
Ok(ty::Const::new_var(tcx, new_var_id))
}
}
}
Expand All @@ -755,19 +756,18 @@ impl<'tcx> TypeRelation<TyCtxt<'tcx>> for Generalizer<'_, 'tcx> {
// 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 !self.cx().features().generic_const_exprs() => {
self.generalize_alias_term(ty::AliasTerm::from_unevaluated_const(self.cx(), uv))
.map(|v| v.expect_const())
StructurallyRelateAliases::No if !tcx.features().generic_const_exprs() => {
self.generalize_alias_term(uv.into()).map(|v| v.expect_const())
}
_ => {
let ty::UnevaluatedConst { def, args } = uv;
let ty::UnevaluatedConst { kind, args, .. } = uv;
let args = self.relate_with_variance(
ty::Invariant,
ty::VarianceDiagInfo::default(),
args,
args,
)?;
Ok(ty::Const::new_unevaluated(self.cx(), ty::UnevaluatedConst { def, args }))
Ok(ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(tcx, kind, args)))
}
},
ty::ConstKind::Placeholder(placeholder) => {
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_middle/src/mir/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,9 +467,13 @@ pub struct UnevaluatedConst<'tcx> {

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

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_middle/src/mir/interpret/queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ impl<'tcx> TyCtxt<'tcx> {
bug!("did not expect inference variables here");
}

let cid = match ty::Instance::try_resolve(self, typing_env, ct.def, ct.args) {
let cid = match ty::Instance::try_resolve(self, typing_env, ct.kind.def_id(), ct.args) {
Ok(Some(instance)) => GlobalId { instance, promoted: None },
// For errors during resolution, we deliberately do not point at the usage site of the constant,
// since for these errors the place the constant is used shouldn't matter.
Expand Down Expand Up @@ -138,11 +138,11 @@ impl<'tcx> TyCtxt<'tcx> {
{
let mir_body = self.mir_for_ctfe(cid.instance.def_id());
if mir_body.is_polymorphic {
let Some(local_def_id) = ct.def.as_local() else { return };
let Some(local_def_id) = ct.kind.def_id().as_local() else { return };
self.emit_node_span_lint(
lint::builtin::CONST_EVALUATABLE_UNCHECKED,
self.local_def_id_to_hir_id(local_def_id),
self.def_span(ct.def),
self.def_span(ct.kind.def_id()),
rustc_errors::DiagDecorator(|lint| {
lint.primary_message(
"cannot use constants which depend on generic parameters in types",
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1429,7 +1429,11 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
Const::Ty(_, ct) => match ct.kind() {
ty::ConstKind::Param(p) => format!("ty::Param({p})"),
ty::ConstKind::Unevaluated(uv) => {
format!("ty::Unevaluated({}, {:?})", self.tcx.def_path_str(uv.def), uv.args,)
format!(
"ty::Unevaluated({}, {:?})",
self.tcx.def_path_str(uv.kind.def_id()),
uv.args,
)
}
ty::ConstKind::Value(cv) => {
format!("ty::Valtree({})", fmt_valtree(&cv))
Expand Down
18 changes: 10 additions & 8 deletions compiler/rustc_middle/src/ty/abstract_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,17 @@ impl<'tcx> TyCtxt<'tcx> {
}
fn fold_const(&mut self, c: Const<'tcx>) -> Const<'tcx> {
let ct = match c.kind() {
ty::ConstKind::Unevaluated(uv) => match self.tcx.thir_abstract_const(uv.def) {
Err(e) => ty::Const::new_error(self.tcx, e),
Ok(Some(bac)) => {
let args = self.tcx.erase_and_anonymize_regions(uv.args);
let bac = bac.instantiate(self.tcx, args).skip_norm_wip();
return bac.fold_with(self);
ty::ConstKind::Unevaluated(uv) => {
match self.tcx.thir_abstract_const(uv.kind.def_id()) {
Err(e) => ty::Const::new_error(self.tcx, e),
Ok(Some(bac)) => {
let args = self.tcx.erase_and_anonymize_regions(uv.args);
let bac = bac.instantiate(self.tcx, args).skip_norm_wip();
return bac.fold_with(self);
}
Ok(None) => c,
}
Ok(None) => c,
},
}
_ => c,
};
ct.super_fold_with(self)
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_middle/src/ty/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ pub use valtree::*;

pub type ConstKind<'tcx> = ir::ConstKind<TyCtxt<'tcx>>;
pub type UnevaluatedConst<'tcx> = ir::UnevaluatedConst<TyCtxt<'tcx>>;
pub type UnevaluatedConstKind<'tcx> = ir::UnevaluatedConstKind<TyCtxt<'tcx>>;

#[cfg(target_pointer_width = "64")]
rustc_data_structures::static_assert_size!(ConstKind<'_>, 24);
rustc_data_structures::static_assert_size!(ConstKind<'_>, 32);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

N.B.


#[derive(Copy, Clone, PartialEq, Eq, Hash, StableHash)]
#[rustc_pass_by_value]
Expand Down Expand Up @@ -107,7 +108,6 @@ impl<'tcx> Const<'tcx> {

#[inline]
pub fn new_unevaluated(tcx: TyCtxt<'tcx>, uv: ty::UnevaluatedConst<'tcx>) -> Const<'tcx> {
tcx.debug_assert_args_compatible(uv.def, uv.args);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this assert has moved to the UnevaluatedConstKind constructor, which is what AliasTyKind does

Const::new(tcx, ty::ConstKind::Unevaluated(uv))
}

Expand Down
22 changes: 21 additions & 1 deletion compiler/rustc_middle/src/ty/context/impl_interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,26 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
}
}

fn unevaluated_const_kind_from_def_id(
self,
def_id: Self::DefId,
) -> ty::UnevaluatedConstKind<'tcx> {
match self.def_kind(def_id) {
DefKind::AssocConst { .. } => {
if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id)) {
ty::UnevaluatedConstKind::Inherent { def_id }
} else {
ty::UnevaluatedConstKind::Projection { def_id }
}
}
DefKind::Const { .. } => ty::UnevaluatedConstKind::Free { def_id },
DefKind::AnonConst | DefKind::InlineConst | DefKind::Ctor(_, CtorKind::Const) => {
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am unsure about DefKind::InlineConst. alias_term_kind_from_def_id does not include it. Removing it causes MIR stuff to panic: rustc_codegen_ssa immediate_const_vector -> eval_unevaluated_mir_constant_to_valtree -> MIR::UnevaluatedConst::shrink -> unevaluated_const_kind_from_def_id -> unexpected DefKind in UnevaluatedConst: InlineConst

ty::UnevaluatedConstKind::Anon { def_id }
}
kind => bug!("unexpected DefKind in UnevaluatedConst: {kind:?}"),
}
}

fn alias_term_kind_from_def_id(self, def_id: DefId) -> ty::AliasTermKind<'tcx> {
match self.def_kind(def_id) {
DefKind::AssocTy => {
Expand All @@ -239,7 +259,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
DefKind::TyAlias => ty::AliasTermKind::FreeTy { def_id },
DefKind::Const { .. } => ty::AliasTermKind::FreeConst { def_id },
DefKind::AnonConst | DefKind::Ctor(_, CtorKind::Const) => {
ty::AliasTermKind::UnevaluatedConst { def_id }
ty::AliasTermKind::AnonConst { def_id }
}
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ pub use self::closure::{
};
pub use self::consts::{
AtomicOrdering, Const, ConstInt, ConstKind, ConstToValTreeResult, Expr, ExprKind,
LitToConstInput, ScalarInt, SimdAlign, UnevaluatedConst, ValTree, ValTreeKindExt, Value,
const_lit_matches_ty,
LitToConstInput, ScalarInt, SimdAlign, UnevaluatedConst, UnevaluatedConstKind, ValTree,
ValTreeKindExt, Value, const_lit_matches_ty,
};
pub use self::context::{
CtxtInterners, CurrentGcx, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed, tls,
Expand Down Expand Up @@ -669,14 +669,14 @@ impl<'tcx> Term<'tcx> {
}
}

pub fn to_alias_term(self, tcx: TyCtxt<'tcx>) -> Option<AliasTerm<'tcx>> {
pub fn to_alias_term(self) -> Option<AliasTerm<'tcx>> {
match self.kind() {
TermKind::Ty(ty) => match *ty.kind() {
ty::Alias(alias_ty) => Some(alias_ty.into()),
_ => None,
},
TermKind::Const(ct) => match ct.kind() {
ConstKind::Unevaluated(uv) => Some(AliasTerm::from_unevaluated_const(tcx, uv)),
ConstKind::Unevaluated(uv) => Some(uv.into()),
_ => None,
},
}
Expand Down
Loading
Loading