stop folding UnevaluatedConst
This commit is contained in:
parent
116d35d401
commit
c5c6ef7029
@ -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>,
|
||||
|
@ -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() {
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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> {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user