introduce mir::Unevaluated

This commit is contained in:
b-naber
2022-09-19 19:46:53 +02:00
parent 3e50038a2d
commit 9f3784df89
32 changed files with 166 additions and 132 deletions

View File

@@ -2055,7 +2055,7 @@ pub enum ConstantKind<'tcx> {
Ty(ty::Const<'tcx>),
/// An unevaluated mir constant which is not part of the type system.
Unevaluated(ty::Unevaluated<'tcx, Option<Promoted>>, Ty<'tcx>),
Unevaluated(Unevaluated<'tcx, Option<Promoted>>, Ty<'tcx>),
/// This constant cannot go back into the type system, as it represents
/// something the type system cannot handle (e.g. pointers).
@@ -2315,12 +2315,11 @@ impl<'tcx> ConstantKind<'tcx> {
ty::InlineConstSubsts::new(tcx, ty::InlineConstSubstsParts { parent_substs, ty })
.substs;
let uneval = ty::Unevaluated {
let uneval = Unevaluated {
def: ty::WithOptConstParam::unknown(def_id).to_global(),
substs,
promoted: None,
};
debug_assert!(!uneval.has_free_regions());
Self::Unevaluated(uneval, ty)
@@ -2404,7 +2403,7 @@ impl<'tcx> ConstantKind<'tcx> {
let hir_id = tcx.hir().local_def_id_to_hir_id(def.did);
let span = tcx.hir().span(hir_id);
let uneval = ty::Unevaluated::new(def.to_global(), substs);
let uneval = Unevaluated::new(def.to_global(), substs);
debug!(?span, ?param_env);
match tcx.const_eval_resolve(param_env, uneval, Some(span)) {
@@ -2417,7 +2416,7 @@ impl<'tcx> ConstantKind<'tcx> {
// Error was handled in `const_eval_resolve`. Here we just create a
// new unevaluated const and error hard later in codegen
Self::Unevaluated(
ty::Unevaluated {
Unevaluated {
def: def.to_global(),
substs: InternalSubsts::identity_for_item(tcx, def.did.to_def_id()),
promoted: None,
@@ -2440,6 +2439,31 @@ impl<'tcx> ConstantKind<'tcx> {
}
}
/// An unevaluated (potentially generic) constant used in MIR.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)]
#[derive(Hash, HashStable)]
pub struct Unevaluated<'tcx, P = Option<Promoted>> {
pub def: ty::WithOptConstParam<DefId>,
pub substs: SubstsRef<'tcx>,
pub promoted: P,
}
impl<'tcx> Unevaluated<'tcx> {
// FIXME: probably should get rid of this method. It's also wrong to
// shrink and then later expand a promoted.
#[inline]
pub fn shrink(self) -> ty::Unevaluated<'tcx> {
ty::Unevaluated { def: self.def, substs: self.substs }
}
}
impl<'tcx, P: Default> Unevaluated<'tcx, P> {
#[inline]
pub fn new(def: ty::WithOptConstParam<DefId>, substs: SubstsRef<'tcx>) -> Unevaluated<'tcx, P> {
Unevaluated { def, substs, promoted: Default::default() }
}
}
/// A collection of projections into user types.
///
/// They are projections because a binding can occur a part of a