Skip to content

Commit

Permalink
Rollup merge of #117851 - compiler-errors:uplift-infer-const, r=spast…
Browse files Browse the repository at this point in the history
…orino

Uplift `InferConst` to `rustc_type_ir`

We need this in `rustc_type_ir` because the canonicalizer must understand the difference between a const vid and an effect vid. In that way, it's not an implementation detail of the representation of an infer const, but just part of the type ir.

If we find out later on that it's better to leave the representation up to the consumer of `rustc_type_ir`, we could abstract `InferConst` (and probably `InferTy` as well) with some traits, but I don't see the benefit of that indirection currently.
  • Loading branch information
matthiaskrgr committed Nov 20, 2023
2 parents 8754087 + b4c3d7f commit 6258697
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 94 deletions.
26 changes: 0 additions & 26 deletions compiler/rustc_middle/src/ty/consts/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use crate::mir;
use crate::ty::abstract_const::CastKind;
use crate::ty::GenericArgsRef;
use crate::ty::{self, visit::TypeVisitableExt as _, List, Ty, TyCtxt};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_hir::def_id::DefId;
use rustc_macros::HashStable;

Expand Down Expand Up @@ -77,28 +76,3 @@ static_assert_size!(Expr<'_>, 24);

#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
static_assert_size!(super::ConstKind<'_>, 32);

/// An inference variable for a const, for use in const generics.
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Hash)]
pub enum InferConst {
/// Infer the value of the const.
Var(ty::ConstVid),
/// Infer the value of the effect.
///
/// For why this is separate from the `Var` variant above, see the
/// documentation on `EffectVid`.
EffectVar(ty::EffectVid),
/// A fresh const variable. See `infer::freshen` for more details.
Fresh(u32),
}

impl<CTX> HashStable<CTX> for InferConst {
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
match self {
InferConst::Var(_) | InferConst::EffectVar(_) => {
panic!("const variables should not be hashed: {self:?}")
}
InferConst::Fresh(i) => i.hash_stable(hcx, hasher),
}
}
}
8 changes: 3 additions & 5 deletions compiler/rustc_middle/src/ty/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ use crate::traits::solve::{
};
use crate::ty::{
self, AdtDef, AdtDefData, AdtKind, Binder, Clause, Const, ConstData, GenericParamDefKind,
ImplPolarity, InferTy, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig,
Predicate, PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind,
TyVid, TypeAndMut, Visibility,
ImplPolarity, List, ParamConst, ParamTy, PolyExistentialPredicate, PolyFnSig, Predicate,
PredicateKind, Region, RegionKind, ReprOptions, TraitObjectVisitor, Ty, TyKind, TyVid,
TypeAndMut, Visibility,
};
use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
use rustc_ast::{self as ast, attr};
Expand Down Expand Up @@ -95,15 +95,13 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
type ParamTy = ParamTy;
type BoundTy = ty::BoundTy;
type PlaceholderTy = ty::PlaceholderType;
type InferTy = InferTy;

type ErrorGuaranteed = ErrorGuaranteed;
type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
type PolyFnSig = PolyFnSig<'tcx>;
type AllocId = crate::mir::interpret::AllocId;

type Const = ty::Const<'tcx>;
type InferConst = ty::InferConst;
type AliasConst = ty::UnevaluatedConst<'tcx>;
type PlaceholderConst = ty::PlaceholderConst;
type ParamConst = ty::ParamConst;
Expand Down
6 changes: 2 additions & 4 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,7 @@ pub use self::closure::{
CapturedPlace, ClosureKind, ClosureTypeInfo, MinCaptureInformationMap, MinCaptureList,
RootVariableMinCaptureList, UpvarCapture, UpvarId, UpvarPath, CAPTURE_STRUCT_LOCAL,
};
pub use self::consts::{
Const, ConstData, ConstInt, Expr, InferConst, ScalarInt, UnevaluatedConst, ValTree,
};
pub use self::consts::{Const, ConstData, ConstInt, Expr, ScalarInt, UnevaluatedConst, ValTree};
pub use self::context::{
tls, CtxtInterners, DeducedParamAttrs, FreeRegionInfo, GlobalCtxt, Lift, TyCtxt, TyCtxtFeed,
};
Expand All @@ -98,7 +96,7 @@ pub use self::sty::BoundRegionKind::*;
pub use self::sty::{
AliasTy, Article, Binder, BoundRegion, BoundRegionKind, BoundTy, BoundTyKind, BoundVar,
BoundVariableKind, CanonicalPolyFnSig, ClauseKind, ClosureArgs, ClosureArgsParts, ConstKind,
ConstVid, CoroutineArgs, CoroutineArgsParts, EarlyParamRegion, EffectVid, ExistentialPredicate,
CoroutineArgs, CoroutineArgsParts, EarlyParamRegion, ExistentialPredicate,
ExistentialProjection, ExistentialTraitRef, FnSig, GenSig, InlineConstArgs,
InlineConstArgsParts, LateParamRegion, ParamConst, ParamTy, PolyExistentialPredicate,
PolyExistentialProjection, PolyExistentialTraitRef, PolyFnSig, PolyGenSig, PolyTraitRef,
Expand Down
28 changes: 0 additions & 28 deletions compiler/rustc_middle/src/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,34 +202,6 @@ impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for AliasTy<'tcx> {
}
}

impl fmt::Debug for ty::InferConst {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
InferConst::Var(var) => write!(f, "{var:?}"),
InferConst::EffectVar(var) => write!(f, "{var:?}"),
InferConst::Fresh(var) => write!(f, "Fresh({var:?})"),
}
}
}
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::InferConst {
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
this: WithInfcx<'_, Infcx, &Self>,
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
use ty::InferConst::*;
match this.infcx.universe_of_ct(*this.data) {
None => write!(f, "{:?}", this.data),
Some(universe) => match *this.data {
Var(vid) => write!(f, "?{}_{}c", vid.index(), universe.index()),
EffectVar(vid) => write!(f, "?{}_{}e", vid.index(), universe.index()),
Fresh(_) => {
unreachable!()
}
},
}
}
}

impl<'tcx> fmt::Debug for ty::consts::Expr<'tcx> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
WithInfcx::with_no_infcx(self).fmt(f)
Expand Down
18 changes: 0 additions & 18 deletions compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1608,24 +1608,6 @@ impl fmt::Debug for EarlyParamRegion {
}
}

rustc_index::newtype_index! {
/// A **`const`** **v**ariable **ID**.
#[debug_format = "?{}c"]
pub struct ConstVid {}
}

rustc_index::newtype_index! {
/// An **effect** **v**ariable **ID**.
///
/// Handling effect infer variables happens separately from const infer variables
/// because we do not want to reuse any of the const infer machinery. If we try to
/// relate an effect variable with a normal one, we would ICE, which can catch bugs
/// where we are not correctly using the effect var for an effect param. Fallback
/// is also implemented on top of having separate effect and normal const variables.
#[debug_format = "?{}e"]
pub struct EffectVid {}
}

rustc_index::newtype_index! {
/// A **region** (lifetime) **v**ariable **ID**.
#[derive(HashStable)]
Expand Down
77 changes: 75 additions & 2 deletions compiler/rustc_type_ir/src/const_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub enum ConstKind<I: Interner> {
Param(I::ParamConst),

/// Infer the value of the const.
Infer(I::InferConst),
Infer(InferConst),

/// Bound const variable, used only when preparing a trait query.
Bound(DebruijnIndex, I::BoundConst),
Expand Down Expand Up @@ -65,7 +65,6 @@ const fn const_kind_discriminant<I: Interner>(value: &ConstKind<I>) -> usize {
impl<CTX: crate::HashStableContext, I: Interner> HashStable<CTX> for ConstKind<I>
where
I::ParamConst: HashStable<CTX>,
I::InferConst: HashStable<CTX>,
I::BoundConst: HashStable<CTX>,
I::PlaceholderConst: HashStable<CTX>,
I::AliasConst: HashStable<CTX>,
Expand Down Expand Up @@ -136,3 +135,77 @@ impl<I: Interner> DebugWithInfcx<I> for ConstKind<I> {
}
}
}

rustc_index::newtype_index! {
/// A **`const`** **v**ariable **ID**.
#[debug_format = "?{}c"]
#[gate_rustc_only]
pub struct ConstVid {}
}

rustc_index::newtype_index! {
/// An **effect** **v**ariable **ID**.
///
/// Handling effect infer variables happens separately from const infer variables
/// because we do not want to reuse any of the const infer machinery. If we try to
/// relate an effect variable with a normal one, we would ICE, which can catch bugs
/// where we are not correctly using the effect var for an effect param. Fallback
/// is also implemented on top of having separate effect and normal const variables.
#[debug_format = "?{}e"]
#[gate_rustc_only]
pub struct EffectVid {}
}

/// An inference variable for a const, for use in const generics.
#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
#[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable))]
pub enum InferConst {
/// Infer the value of the const.
Var(ConstVid),
/// Infer the value of the effect.
///
/// For why this is separate from the `Var` variant above, see the
/// documentation on `EffectVid`.
EffectVar(EffectVid),
/// A fresh const variable. See `infer::freshen` for more details.
Fresh(u32),
}

impl fmt::Debug for InferConst {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
InferConst::Var(var) => write!(f, "{var:?}"),
InferConst::EffectVar(var) => write!(f, "{var:?}"),
InferConst::Fresh(var) => write!(f, "Fresh({var:?})"),
}
}
}
impl<I: Interner> DebugWithInfcx<I> for InferConst {
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
this: WithInfcx<'_, Infcx, &Self>,
f: &mut core::fmt::Formatter<'_>,
) -> core::fmt::Result {
match this.infcx.universe_of_ct(*this.data) {
None => write!(f, "{:?}", this.data),
Some(universe) => match *this.data {
InferConst::Var(vid) => write!(f, "?{}_{}c", vid.index(), universe.index()),
InferConst::EffectVar(vid) => write!(f, "?{}_{}e", vid.index(), universe.index()),
InferConst::Fresh(_) => {
unreachable!()
}
},
}
}
}

#[cfg(feature = "nightly")]
impl<CTX> HashStable<CTX> for InferConst {
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
match self {
InferConst::Var(_) | InferConst::EffectVar(_) => {
panic!("const variables should not be hashed: {self:?}")
}
InferConst::Fresh(i) => i.hash_stable(hcx, hasher),
}
}
}
11 changes: 5 additions & 6 deletions compiler/rustc_type_ir/src/debug.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
use crate::{Interner, UniverseIndex};
use crate::{InferConst, InferTy, Interner, UniverseIndex};

use core::fmt;
use std::marker::PhantomData;

pub trait InferCtxtLike {
type Interner: Interner;

fn universe_of_ty(&self, ty: <Self::Interner as Interner>::InferTy) -> Option<UniverseIndex>;
fn universe_of_ty(&self, ty: InferTy) -> Option<UniverseIndex>;

fn universe_of_lt(
&self,
lt: <Self::Interner as Interner>::InferRegion,
) -> Option<UniverseIndex>;

fn universe_of_ct(&self, ct: <Self::Interner as Interner>::InferConst)
-> Option<UniverseIndex>;
fn universe_of_ct(&self, ct: InferConst) -> Option<UniverseIndex>;
}

pub struct NoInfcx<I>(PhantomData<I>);

impl<I: Interner> InferCtxtLike for NoInfcx<I> {
type Interner = I;

fn universe_of_ty(&self, _ty: <I as Interner>::InferTy) -> Option<UniverseIndex> {
fn universe_of_ty(&self, _ty: InferTy) -> Option<UniverseIndex> {
None
}

fn universe_of_ct(&self, _ct: <I as Interner>::InferConst) -> Option<UniverseIndex> {
fn universe_of_ct(&self, _ct: InferConst) -> Option<UniverseIndex> {
None
}

Expand Down
2 changes: 0 additions & 2 deletions compiler/rustc_type_ir/src/interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ pub trait Interner: Sized {
type ParamTy: Clone + Debug + Hash + Ord;
type BoundTy: Clone + Debug + Hash + Ord;
type PlaceholderTy: Clone + Debug + Hash + Ord;
type InferTy: Clone + DebugWithInfcx<Self> + Hash + Ord;

// Things stored inside of tys
type ErrorGuaranteed: Clone + Debug + Hash + Ord;
Expand All @@ -37,7 +36,6 @@ pub trait Interner: Sized {

// Kinds of consts
type Const: Clone + DebugWithInfcx<Self> + Hash + Ord;
type InferConst: Clone + DebugWithInfcx<Self> + Hash + Ord;
type AliasConst: Clone + DebugWithInfcx<Self> + Hash + Ord;
type PlaceholderConst: Clone + Debug + Hash + Ord;
type ParamConst: Clone + Debug + Hash + Ord;
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_type_ir/src/ty_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ pub enum TyKind<I: Interner> {
/// correctly deal with higher ranked types. Though unlike placeholders,
/// that universe is stored in the `InferCtxt` instead of directly
/// inside of the type.
Infer(I::InferTy),
Infer(InferTy),

/// A placeholder for a type which could not be computed; this is
/// propagated to avoid useless error messages.
Expand Down Expand Up @@ -491,7 +491,6 @@ where
I::BoundTy: HashStable<CTX>,
I::ParamTy: HashStable<CTX>,
I::PlaceholderTy: HashStable<CTX>,
I::InferTy: HashStable<CTX>,
I::ErrorGuaranteed: HashStable<CTX>,
{
#[inline]
Expand Down Expand Up @@ -922,7 +921,7 @@ impl fmt::Debug for InferTy {
}
}

impl<I: Interner<InferTy = InferTy>> DebugWithInfcx<I> for InferTy {
impl<I: Interner> DebugWithInfcx<I> for InferTy {
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
this: WithInfcx<'_, Infcx, &Self>,
f: &mut fmt::Formatter<'_>,
Expand Down

0 comments on commit 6258697

Please sign in to comment.