mirror of https://github.com/rust-lang/rust.git
shrink `ty::PredicateKind` again
This commit is contained in:
parent
283e0e670b
commit
bc0156bace
|
@ -675,8 +675,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
|||
/// canonicalizing the consts.
|
||||
pub fn try_unify_abstract_consts(
|
||||
&self,
|
||||
a: ty::Unevaluated<'tcx>,
|
||||
b: ty::Unevaluated<'tcx>,
|
||||
a: ty::Unevaluated<'tcx, ()>,
|
||||
b: ty::Unevaluated<'tcx, ()>,
|
||||
) -> bool {
|
||||
let canonical = self.canonicalize_query((a, b), &mut OriginalQueryValues::default());
|
||||
debug!("canonical consts: {:?}", &canonical.value);
|
||||
|
|
|
@ -303,7 +303,7 @@ rustc_queries! {
|
|||
}
|
||||
|
||||
query try_unify_abstract_consts(key: (
|
||||
ty::Unevaluated<'tcx>, ty::Unevaluated<'tcx>
|
||||
ty::Unevaluated<'tcx, ()>, ty::Unevaluated<'tcx, ()>
|
||||
)) -> bool {
|
||||
desc {
|
||||
|tcx| "trying to unify the generic constants {} and {}",
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use std::convert::TryInto;
|
||||
use std::fmt;
|
||||
|
||||
use crate::mir::interpret::{AllocId, ConstValue, Scalar};
|
||||
use crate::mir::Promoted;
|
||||
|
@ -20,20 +21,38 @@ use super::ScalarInt;
|
|||
/// so refer to that check for more info.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord, TyEncodable, TyDecodable, Lift)]
|
||||
#[derive(Hash, HashStable)]
|
||||
pub struct Unevaluated<'tcx> {
|
||||
pub struct Unevaluated<'tcx, P = Option<Promoted>> {
|
||||
pub def: ty::WithOptConstParam<DefId>,
|
||||
pub substs_: Option<SubstsRef<'tcx>>,
|
||||
pub promoted: Option<Promoted>,
|
||||
pub promoted: P,
|
||||
}
|
||||
|
||||
impl<'tcx> Unevaluated<'tcx> {
|
||||
pub fn new(def: ty::WithOptConstParam<DefId>, substs: SubstsRef<'tcx>) -> Unevaluated<'tcx> {
|
||||
Unevaluated { def, substs_: Some(substs), promoted: None }
|
||||
pub fn shrink(self) -> Unevaluated<'tcx, ()> {
|
||||
debug_assert_eq!(self.promoted, None);
|
||||
Unevaluated { def: self.def, substs_: self.substs_, promoted: () }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Unevaluated<'tcx, ()> {
|
||||
pub fn expand(self) -> Unevaluated<'tcx> {
|
||||
Unevaluated { def: self.def, substs_: self.substs_, promoted: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, P: Default> Unevaluated<'tcx, P> {
|
||||
pub fn new(def: ty::WithOptConstParam<DefId>, substs: SubstsRef<'tcx>) -> Unevaluated<'tcx, P> {
|
||||
Unevaluated { def, substs_: Some(substs), promoted: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, P: Default + PartialEq + fmt::Debug> Unevaluated<'tcx, P> {
|
||||
pub fn substs(self, tcx: TyCtxt<'tcx>) -> SubstsRef<'tcx> {
|
||||
self.substs_.unwrap_or_else(|| {
|
||||
debug_assert_eq!(self.promoted, None);
|
||||
// We must not use the parents default substs for promoted constants
|
||||
// as that can result in incorrect substs and calls the `default_anon_const_substs`
|
||||
// for something that might not actually be a constant.
|
||||
debug_assert_eq!(self.promoted, Default::default());
|
||||
tcx.default_anon_const_substs(self.def.did)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -310,7 +310,7 @@ impl FlagComputation {
|
|||
}
|
||||
}
|
||||
|
||||
fn add_unevaluated_const(&mut self, ct: ty::Unevaluated<'tcx>) {
|
||||
fn add_unevaluated_const<P>(&mut self, ct: ty::Unevaluated<'tcx, P>) {
|
||||
if let Some(substs) = ct.substs_ {
|
||||
self.add_substs(substs);
|
||||
} else {
|
||||
|
|
|
@ -406,7 +406,7 @@ crate struct PredicateInner<'tcx> {
|
|||
}
|
||||
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
static_assert_size!(PredicateInner<'_>, 56);
|
||||
static_assert_size!(PredicateInner<'_>, 48);
|
||||
|
||||
#[derive(Clone, Copy, Lift)]
|
||||
pub struct Predicate<'tcx> {
|
||||
|
@ -502,7 +502,7 @@ pub enum PredicateKind<'tcx> {
|
|||
Coerce(CoercePredicate<'tcx>),
|
||||
|
||||
/// Constant initializer must evaluate successfully.
|
||||
ConstEvaluatable(ty::Unevaluated<'tcx>),
|
||||
ConstEvaluatable(ty::Unevaluated<'tcx, ()>),
|
||||
|
||||
/// Constants must be equal. The first component is the const that is expected.
|
||||
ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>),
|
||||
|
|
|
@ -579,7 +579,7 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>(
|
|||
(ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu))
|
||||
if tcx.features().const_evaluatable_checked =>
|
||||
{
|
||||
tcx.try_unify_abstract_consts((au, bu))
|
||||
tcx.try_unify_abstract_consts((au.shrink(), bu.shrink()))
|
||||
}
|
||||
|
||||
// While this is slightly incorrect, it shouldn't matter for `min_const_generics`
|
||||
|
|
|
@ -1105,3 +1105,28 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::Unevaluated<'tcx, ()> {
|
||||
fn super_fold_with<F: TypeFolder<'tcx>>(self, folder: &mut F) -> Self {
|
||||
ty::Unevaluated {
|
||||
def: self.def,
|
||||
substs_: Some(self.substs(folder.tcx()).fold_with(folder)),
|
||||
promoted: self.promoted,
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
visitor.visit_unevaluated_const(self.expand())
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> ControlFlow<V::BreakTy> {
|
||||
if let Some(tcx) = visitor.tcx_for_anon_const_substs() {
|
||||
self.substs(tcx).visit_with(visitor)
|
||||
} else if let Some(substs) = self.substs_ {
|
||||
substs.visit_with(visitor)
|
||||
} else {
|
||||
debug!("ignoring default substs of `{:?}`", self.def);
|
||||
ControlFlow::CONTINUE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -217,7 +217,7 @@ impl<'tcx> Key for (DefId, SubstsRef<'tcx>) {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Key for (ty::Unevaluated<'tcx>, ty::Unevaluated<'tcx>) {
|
||||
impl<'tcx> Key for (ty::Unevaluated<'tcx, ()>, ty::Unevaluated<'tcx, ()>) {
|
||||
#[inline(always)]
|
||||
fn query_crate_is_local(&self) -> bool {
|
||||
(self.0).def.did.krate == LOCAL_CRATE
|
||||
|
|
|
@ -29,7 +29,7 @@ use std::ops::ControlFlow;
|
|||
/// Check if a given constant can be evaluated.
|
||||
pub fn is_const_evaluatable<'cx, 'tcx>(
|
||||
infcx: &InferCtxt<'cx, 'tcx>,
|
||||
uv: ty::Unevaluated<'tcx>,
|
||||
uv: ty::Unevaluated<'tcx, ()>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
span: Span,
|
||||
) -> Result<(), NotConstEvaluatable> {
|
||||
|
@ -149,7 +149,7 @@ pub fn is_const_evaluatable<'cx, 'tcx>(
|
|||
// and hopefully soon change this to an error.
|
||||
//
|
||||
// See #74595 for more details about this.
|
||||
let concrete = infcx.const_eval_resolve(param_env, uv, Some(span));
|
||||
let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span));
|
||||
|
||||
if concrete.is_ok() && uv.substs(infcx.tcx).has_param_types_or_consts(infcx.tcx) {
|
||||
match infcx.tcx.def_kind(uv.def.did) {
|
||||
|
@ -194,7 +194,7 @@ pub struct AbstractConst<'tcx> {
|
|||
impl<'tcx> AbstractConst<'tcx> {
|
||||
pub fn new(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
uv: ty::Unevaluated<'tcx>,
|
||||
uv: ty::Unevaluated<'tcx, ()>,
|
||||
) -> Result<Option<AbstractConst<'tcx>>, ErrorReported> {
|
||||
let inner = tcx.mir_abstract_const_opt_const_arg(uv.def)?;
|
||||
debug!("AbstractConst::new({:?}) = {:?}", uv, inner);
|
||||
|
@ -206,7 +206,7 @@ impl<'tcx> AbstractConst<'tcx> {
|
|||
ct: &ty::Const<'tcx>,
|
||||
) -> Result<Option<AbstractConst<'tcx>>, ErrorReported> {
|
||||
match ct.val {
|
||||
ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv),
|
||||
ty::ConstKind::Unevaluated(uv) => AbstractConst::new(tcx, uv.shrink()),
|
||||
ty::ConstKind::Error(_) => Err(ErrorReported),
|
||||
_ => Ok(None),
|
||||
}
|
||||
|
@ -556,7 +556,7 @@ pub(super) fn mir_abstract_const<'tcx>(
|
|||
|
||||
pub(super) fn try_unify_abstract_consts<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
(a, b): (ty::Unevaluated<'tcx>, ty::Unevaluated<'tcx>),
|
||||
(a, b): (ty::Unevaluated<'tcx, ()>, ty::Unevaluated<'tcx, ()>),
|
||||
) -> bool {
|
||||
(|| {
|
||||
if let Some(a) = AbstractConst::new(tcx, a)? {
|
||||
|
|
|
@ -580,7 +580,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
|
||||
(c1.val, c2.val)
|
||||
{
|
||||
if infcx.try_unify_abstract_consts(a, b) {
|
||||
if infcx.try_unify_abstract_consts(a.shrink(), b.shrink()) {
|
||||
return ProcessResult::Changed(vec![]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -623,7 +623,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
if let (ty::ConstKind::Unevaluated(a), ty::ConstKind::Unevaluated(b)) =
|
||||
(c1.val, c2.val)
|
||||
{
|
||||
if self.infcx.try_unify_abstract_consts(a, b) {
|
||||
if self.infcx.try_unify_abstract_consts(a.shrink(), b.shrink()) {
|
||||
return Ok(EvaluatedToOk);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2355,8 +2355,10 @@ fn const_evaluatable_predicates_of<'tcx>(
|
|||
if let ty::ConstKind::Unevaluated(uv) = ct.val {
|
||||
assert_eq!(uv.promoted, None);
|
||||
let span = self.tcx.hir().span(c.hir_id);
|
||||
self.preds
|
||||
.insert((ty::PredicateKind::ConstEvaluatable(uv).to_predicate(self.tcx), span));
|
||||
self.preds.insert((
|
||||
ty::PredicateKind::ConstEvaluatable(uv.shrink()).to_predicate(self.tcx),
|
||||
span,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue