stop folding UnevaluatedConst

This commit is contained in:
lcnr 2022-10-19 10:03:23 +02:00
parent 116d35d401
commit c5c6ef7029
6 changed files with 9 additions and 91 deletions

View File

@ -14,7 +14,7 @@ use super::ScalarInt;
/// An unevaluated (potentially generic) constant used in the type-system.
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)]
#[derive(Hash, HashStable)]
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
pub struct UnevaluatedConst<'tcx> {
pub def: ty::WithOptConstParam<DefId>,
pub substs: SubstsRef<'tcx>,

View File

@ -34,12 +34,6 @@ impl FlagComputation {
result.flags
}
pub fn for_unevaluated_const(uv: ty::UnevaluatedConst<'_>) -> TypeFlags {
let mut result = FlagComputation::new();
result.add_unevaluated_const(uv);
result.flags
}
fn add_flags(&mut self, flags: TypeFlags) {
self.flags = self.flags | flags;
}
@ -289,7 +283,10 @@ impl FlagComputation {
fn add_const(&mut self, c: ty::Const<'_>) {
self.add_ty(c.ty());
match c.kind() {
ty::ConstKind::Unevaluated(unevaluated) => self.add_unevaluated_const(unevaluated),
ty::ConstKind::Unevaluated(uv) => {
self.add_substs(uv.substs);
self.add_flags(TypeFlags::HAS_CT_PROJECTION);
}
ty::ConstKind::Infer(infer) => {
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
match infer {
@ -313,11 +310,6 @@ impl FlagComputation {
}
}
fn add_unevaluated_const(&mut self, ct: ty::UnevaluatedConst<'_>) {
self.add_substs(ct.substs);
self.add_flags(TypeFlags::HAS_CT_PROJECTION);
}
fn add_existential_projection(&mut self, projection: &ty::ExistentialProjection<'_>) {
self.add_substs(projection.substs);
match projection.term.unpack() {

View File

@ -126,13 +126,6 @@ pub trait TypeFolder<'tcx>: FallibleTypeFolder<'tcx, Error = !> {
c.super_fold_with(self)
}
fn fold_ty_unevaluated(
&mut self,
uv: ty::UnevaluatedConst<'tcx>,
) -> ty::UnevaluatedConst<'tcx> {
uv.super_fold_with(self)
}
fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
p.super_fold_with(self)
}
@ -169,13 +162,6 @@ pub trait FallibleTypeFolder<'tcx>: Sized {
c.try_super_fold_with(self)
}
fn try_fold_ty_unevaluated(
&mut self,
c: ty::UnevaluatedConst<'tcx>,
) -> Result<ty::UnevaluatedConst<'tcx>, Self::Error> {
c.try_super_fold_with(self)
}
fn try_fold_predicate(
&mut self,
p: ty::Predicate<'tcx>,
@ -215,13 +201,6 @@ where
Ok(self.fold_const(c))
}
fn try_fold_ty_unevaluated(
&mut self,
c: ty::UnevaluatedConst<'tcx>,
) -> Result<ty::UnevaluatedConst<'tcx>, !> {
Ok(self.fold_ty_unevaluated(c))
}
fn try_fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> Result<ty::Predicate<'tcx>, !> {
Ok(self.fold_predicate(p))
}

View File

@ -832,27 +832,6 @@ impl<'tcx> TypeVisitable<'tcx> for InferConst<'tcx> {
}
}
impl<'tcx> TypeFoldable<'tcx> for ty::UnevaluatedConst<'tcx> {
fn try_fold_with<F: FallibleTypeFolder<'tcx>>(self, folder: &mut F) -> Result<Self, F::Error> {
folder.try_fold_ty_unevaluated(self)
}
}
impl<'tcx> TypeVisitable<'tcx> for ty::UnevaluatedConst<'tcx> {
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
visitor.visit_ty_unevaluated(*self)
}
}
impl<'tcx> TypeSuperFoldable<'tcx> for ty::UnevaluatedConst<'tcx> {
fn try_super_fold_with<F: FallibleTypeFolder<'tcx>>(
self,
folder: &mut F,
) -> Result<Self, F::Error> {
Ok(ty::UnevaluatedConst { def: self.def, substs: self.substs.try_fold_with(folder)? })
}
}
impl<'tcx> TypeSuperVisitable<'tcx> for ty::UnevaluatedConst<'tcx> {
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
self.substs.visit_with(visitor)

View File

@ -197,13 +197,6 @@ pub trait TypeVisitor<'tcx>: Sized {
c.super_visit_with(self)
}
fn visit_ty_unevaluated(
&mut self,
uv: ty::UnevaluatedConst<'tcx>,
) -> ControlFlow<Self::BreakTy> {
uv.super_visit_with(self)
}
fn visit_predicate(&mut self, p: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {
p.super_visit_with(self)
}
@ -592,21 +585,6 @@ impl<'tcx> TypeVisitor<'tcx> for HasTypeFlagsVisitor {
}
}
#[inline]
#[instrument(level = "trace", ret)]
fn visit_ty_unevaluated(
&mut self,
uv: ty::UnevaluatedConst<'tcx>,
) -> ControlFlow<Self::BreakTy> {
let flags = FlagComputation::for_unevaluated_const(uv);
trace!(r.flags=?flags);
if flags.intersects(self.flags) {
ControlFlow::Break(FoundFlags)
} else {
ControlFlow::CONTINUE
}
}
#[inline]
#[instrument(level = "trace", ret)]
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<Self::BreakTy> {

View File

@ -837,24 +837,14 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
}
}
fn visit_ty_unevaluated(
&mut self,
uv: ty::UnevaluatedConst<'tcx>,
) -> ControlFlow<Self::BreakTy> {
fn visit_const(&mut self, ct: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
// Constants can only influence object safety if they reference `Self`.
// This is only possible for unevaluated constants, so we walk these here.
//
// If `AbstractConst::new` returned an error we already failed compilation
// If `AbstractConst::from_const` returned an error we already failed compilation
// so we don't have to emit an additional error here.
//
// We currently recurse into abstract consts here but do not recurse in
// `is_const_evaluatable`. This means that the object safety check is more
// liberal than the const eval check.
//
// This shouldn't really matter though as we can't really use any
// constants which are not considered const evaluatable.
use rustc_middle::ty::abstract_const::Node;
if let Ok(Some(ct)) = AbstractConst::new(self.tcx, uv) {
if let Ok(Some(ct)) = AbstractConst::from_const(self.tcx, ct) {
walk_abstract_const(self.tcx, ct, |node| match node.root(self.tcx) {
Node::Leaf(leaf) => self.visit_const(leaf),
Node::Cast(_, _, ty) => self.visit_ty(ty),
@ -863,7 +853,7 @@ fn contains_illegal_self_type_reference<'tcx, T: TypeVisitable<'tcx>>(
}
})
} else {
ControlFlow::CONTINUE
ct.super_visit_with(self)
}
}
}