mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 15:32:06 +00:00
Rollup merge of #117851 - compiler-errors:uplift-infer-const, r=spastorino
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.
This commit is contained in:
commit
6258697445
@ -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;
|
||||
|
||||
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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};
|
||||
@ -95,7 +95,6 @@ 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>>;
|
||||
@ -103,7 +102,6 @@ impl<'tcx> Interner for TyCtxt<'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;
|
||||
|
@ -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,
|
||||
};
|
||||
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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)]
|
||||
|
@ -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),
|
||||
@ -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>,
|
||||
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::{Interner, UniverseIndex};
|
||||
use crate::{InferConst, InferTy, Interner, UniverseIndex};
|
||||
|
||||
use core::fmt;
|
||||
use std::marker::PhantomData;
|
||||
@ -6,15 +6,14 @@ 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>);
|
||||
@ -22,11 +21,11 @@ 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
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
@ -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;
|
||||
|
@ -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.
|
||||
@ -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]
|
||||
@ -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<'_>,
|
||||
|
Loading…
Reference in New Issue
Block a user