提交 cd9743b4 编写于 作者: B Bastian Kauschke

directly contain `PredicateAtom` in `PredicateKind::ForAll`

上级 d8cf8ba5
......@@ -531,11 +531,9 @@ fn query_outlives_constraints_into_obligations<'a>(
let predicate = match k1.unpack() {
GenericArgKind::Lifetime(r1) => {
ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(r1, r2))
.to_predicate(self.tcx)
}
GenericArgKind::Type(t1) => {
ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(t1, r2))
.to_predicate(self.tcx)
}
GenericArgKind::Const(..) => {
// Consts cannot outlive one another, so we don't expect to
......
......@@ -201,21 +201,21 @@ fn add_kind(&mut self, kind: &ty::TyKind<'_>) {
}
}
fn add_predicate(&mut self, pred: ty::Predicate<'_>) {
self.add_flags(pred.inner.flags);
self.add_exclusive_binder(pred.inner.outer_exclusive_binder);
}
fn add_predicate_kind(&mut self, kind: &ty::PredicateKind<'_>) {
match kind {
ty::PredicateKind::ForAll(binder) => {
let mut computation = FlagComputation::new();
computation.add_predicate(binder.skip_binder());
computation.add_predicate_atom(binder.skip_binder());
self.add_bound_computation(computation);
}
&ty::PredicateKind::Atom(atom) => match atom {
&ty::PredicateKind::Atom(atom) => self.add_predicate_atom(atom),
}
}
fn add_predicate_atom(&mut self, atom: ty::PredicateAtom<'_>) {
match atom {
ty::PredicateAtom::Trait(trait_pred, _constness) => {
self.add_substs(trait_pred.trait_ref.substs);
}
......@@ -249,7 +249,6 @@ fn add_predicate_kind(&mut self, kind: &ty::PredicateKind<'_>) {
self.add_const(expected);
self.add_const(found);
}
},
}
}
......
......@@ -1053,8 +1053,9 @@ pub fn kind(self) -> &'tcx PredicateKind<'tcx> {
///
/// Note that this method panics in case this predicate has unbound variables.
pub fn skip_binders(self) -> PredicateAtom<'tcx> {
// TODO no_escaping_vars
match self.kind() {
&PredicateKind::ForAll(binder) => binder.skip_binder().skip_binders(),
&PredicateKind::ForAll(binder) => binder.skip_binder(),
&ty::PredicateKind::Atom(atom) => atom,
}
}
......@@ -1066,33 +1067,17 @@ pub fn skip_binders(self) -> PredicateAtom<'tcx> {
/// to end up at the wrong binding level.
pub fn skip_binders_unchecked(self) -> PredicateAtom<'tcx> {
match self.kind() {
&PredicateKind::ForAll(binder) => binder.skip_binder().skip_binders(),
&PredicateKind::ForAll(binder) => binder.skip_binder(),
&ty::PredicateKind::Atom(atom) => atom,
}
}
pub fn bound_atom(self, tcx: TyCtxt<'tcx>) -> Binder<PredicateAtom<'tcx>> {
match self.kind() {
&PredicateKind::ForAll(binder) => binder.map_bound(|inner| match inner.kind() {
ty::PredicateKind::ForAll(_) => bug!("unexpect forall"),
&ty::PredicateKind::Atom(atom) => atom,
}),
&PredicateKind::ForAll(binder) => binder,
&ty::PredicateKind::Atom(atom) => Binder::wrap_nonbinding(tcx, atom),
}
}
/// Wraps `self` with the given qualifier if this predicate has any unbound variables.
pub fn potentially_quantified(
self,
tcx: TyCtxt<'tcx>,
qualifier: impl FnOnce(Binder<Predicate<'tcx>>) -> PredicateKind<'tcx>,
) -> Predicate<'tcx> {
if self.has_escaping_bound_vars() {
qualifier(Binder::bind(self)).to_predicate(tcx)
} else {
self
}
}
}
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Predicate<'tcx> {
......@@ -1114,7 +1099,7 @@ fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHas
#[derive(HashStable, TypeFoldable)]
pub enum PredicateKind<'tcx> {
/// `for<'a>: ...`
ForAll(Binder<Predicate<'tcx>>),
ForAll(Binder<PredicateAtom<'tcx>>),
Atom(PredicateAtom<'tcx>),
}
......@@ -1162,6 +1147,22 @@ pub enum PredicateAtom<'tcx> {
ConstEquate(&'tcx Const<'tcx>, &'tcx Const<'tcx>),
}
impl<'tcx> PredicateAtom<'tcx> {
/// Wraps `self` with the given qualifier if this predicate has any unbound variables.
pub fn potentially_quantified(
self,
tcx: TyCtxt<'tcx>,
qualifier: impl FnOnce(Binder<PredicateAtom<'tcx>>) -> PredicateKind<'tcx>,
) -> Predicate<'tcx> {
if self.has_escaping_bound_vars() {
qualifier(Binder::bind(self))
} else {
PredicateKind::Atom(self)
}
.to_predicate(tcx)
}
}
/// The crate outlives map is computed during typeck and contains the
/// outlives of every item in the local crate. You should not use it
/// directly, because to do so will make your pass dependent on the
......@@ -1249,11 +1250,7 @@ pub fn subst_supertrait(
let substs = trait_ref.skip_binder().substs;
let pred = self.skip_binders();
let new = pred.subst(tcx, substs);
if new != pred {
new.to_predicate(tcx).potentially_quantified(tcx, PredicateKind::ForAll)
} else {
self
}
if new != pred { new.potentially_quantified(tcx, PredicateKind::ForAll) } else { self }
}
}
......@@ -1381,6 +1378,7 @@ fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
impl ToPredicate<'tcx> for PredicateAtom<'tcx> {
#[inline(always)]
fn to_predicate(&self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
debug_assert!(!self.has_escaping_bound_vars(), "excaping bound vars for {:?}", self);
tcx.mk_predicate(ty::PredicateKind::Atom(*self))
}
}
......@@ -1408,9 +1406,7 @@ fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
ty::PredicateAtom::Trait(pred, self.constness).to_predicate(tcx)
} else {
ty::PredicateKind::ForAll(
self.value.map_bound(|pred| {
ty::PredicateAtom::Trait(pred, self.constness).to_predicate(tcx)
}),
self.value.map_bound(|pred| ty::PredicateAtom::Trait(pred, self.constness)),
)
.to_predicate(tcx)
}
......@@ -1423,9 +1419,7 @@ fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
PredicateAtom::RegionOutlives(outlives).to_predicate(tcx)
} else {
ty::PredicateKind::ForAll(
self.map_bound(|outlives| {
PredicateAtom::RegionOutlives(outlives).to_predicate(tcx)
}),
self.map_bound(|outlives| PredicateAtom::RegionOutlives(outlives)),
)
.to_predicate(tcx)
}
......@@ -1438,7 +1432,7 @@ fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
PredicateAtom::TypeOutlives(outlives).to_predicate(tcx)
} else {
ty::PredicateKind::ForAll(
self.map_bound(|outlives| PredicateAtom::TypeOutlives(outlives).to_predicate(tcx)),
self.map_bound(|outlives| PredicateAtom::TypeOutlives(outlives)),
)
.to_predicate(tcx)
}
......@@ -1450,9 +1444,7 @@ fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
if let Some(proj) = self.no_bound_vars() {
PredicateAtom::Projection(proj).to_predicate(tcx)
} else {
ty::PredicateKind::ForAll(
self.map_bound(|proj| PredicateAtom::Projection(proj).to_predicate(tcx)),
)
ty::PredicateKind::ForAll(self.map_bound(|proj| PredicateAtom::Projection(proj)))
.to_predicate(tcx)
}
}
......
......@@ -2013,7 +2013,13 @@ pub fn print_only_trait_path(self) -> ty::Binder<TraitRefPrintOnlyTraitPath<'tcx
ty::Predicate<'tcx> {
match self.kind() {
&ty::PredicateKind::Atom(atom) => match atom {
&ty::PredicateKind::Atom(atom) => p!(print(atom)),
ty::PredicateKind::ForAll(binder) => p!(print(binder)),
}
}
ty::PredicateAtom<'tcx> {
match *self {
ty::PredicateAtom::Trait(ref data, constness) => {
if let hir::Constness::Const = constness {
p!(write("const "));
......@@ -2048,10 +2054,6 @@ pub fn print_only_trait_path(self) -> ty::Binder<TraitRefPrintOnlyTraitPath<'tcx
write("`"))
}
}
ty::PredicateKind::ForAll(binder) => {
p!(print(binder))
}
}
}
GenericArg<'tcx> {
......
......@@ -6,6 +6,7 @@
use rustc_infer::traits::{PolyTraitObligation, TraitEngine, TraitEngineExt as _};
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::error::ExpectedFound;
use rustc_middle::ty::ToPredicate;
use rustc_middle::ty::{self, Binder, Const, Ty, TypeFoldable};
use std::marker::PhantomData;
......
......@@ -93,12 +93,8 @@ pub fn predicate_obligations<'a, 'tcx>(
) -> Vec<traits::PredicateObligation<'tcx>> {
let mut wf = WfPredicates { infcx, param_env, body_id, span, out: vec![], item: None };
match predicate.kind() {
ty::PredicateKind::ForAll(binder) => {
// It's ok to skip the binder here because wf code is prepared for it
return predicate_obligations(infcx, param_env, body_id, binder.skip_binder(), span);
}
&ty::PredicateKind::Atom(atom) => match atom {
match predicate.skip_binders() {
ty::PredicateAtom::Trait(t, _) => {
wf.compute_trait_ref(&t.trait_ref, Elaborate::None);
}
......@@ -131,7 +127,6 @@ pub fn predicate_obligations<'a, 'tcx>(
wf.compute(c1.into());
wf.compute(c2.into());
}
},
}
wf.normalize()
......
......@@ -798,11 +798,14 @@ fn assemble_inherent_candidates_from_param(&mut self, param_ty: ty::ParamTy) {
// FIXME: do we want to commit to this behavior for param bounds?
debug!("assemble_inherent_candidates_from_param(param_ty={:?})", param_ty);
let bounds = self.param_env.caller_bounds().iter().map(ty::Predicate::skip_binders).filter_map(|predicate| match predicate
{
let bounds =
self.param_env.caller_bounds().iter().map(ty::Predicate::skip_binders).filter_map(
|predicate| match predicate {
ty::PredicateAtom::Trait(trait_predicate, _) => {
match trait_predicate.trait_ref.self_ty().kind {
ty::Param(ref p) if *p == param_ty => Some(ty::Binder::bind(trait_predicate.trait_ref)),
ty::Param(ref p) if *p == param_ty => {
Some(ty::Binder::bind(trait_predicate.trait_ref))
}
_ => None,
}
}
......@@ -815,7 +818,8 @@ fn assemble_inherent_candidates_from_param(&mut self, param_ty: ty::ParamTy) {
| ty::PredicateAtom::TypeOutlives(..)
| ty::PredicateAtom::ConstEvaluatable(..)
| ty::PredicateAtom::ConstEquate(..) => None,
});
},
);
self.elaborate_bounds(bounds, |this, poly_trait_ref, item| {
let trait_ref = this.erase_late_bound_regions(&poly_trait_ref);
......
......@@ -2939,9 +2939,7 @@ fn get_type_parameter_bounds(&self, _: Span, def_id: DefId) -> ty::GenericPredic
predicates: tcx.arena.alloc_from_iter(
self.param_env.caller_bounds().iter().filter_map(|predicate| {
match predicate.skip_binders() {
ty::PredicateAtom::Trait(data, _)
if data.self_ty().is_param(index) =>
{
ty::PredicateAtom::Trait(data, _) if data.self_ty().is_param(index) => {
// HACK(eddyb) should get the original `Span`.
let span = tcx.def_span(def_id);
Some((predicate, span))
......@@ -5373,7 +5371,6 @@ fn suggest_missing_await(
projection_ty,
ty: expected,
})
.to_predicate(self.tcx)
.potentially_quantified(self.tcx, ty::PredicateKind::ForAll);
let obligation = traits::Obligation::new(self.misc(sp), self.param_env, predicate);
......
......@@ -1961,7 +1961,6 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
let region = AstConv::ast_region_to_region(&icx, lifetime, None);
predicates.push((
ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(ty, region))
.to_predicate(tcx)
.potentially_quantified(tcx, ty::PredicateKind::ForAll),
lifetime.span,
))
......@@ -1979,8 +1978,7 @@ fn extend<I: IntoIterator<Item = (ty::Predicate<'tcx>, Span)>>(&mut self, iter:
}
_ => bug!(),
};
let pred = ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(r1, r2))
.to_predicate(icx.tcx);
let pred = ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(r1, r2));
(pred.potentially_quantified(icx.tcx, ty::PredicateKind::ForAll), span)
}))
......@@ -2111,7 +2109,6 @@ fn predicates_from_bound<'tcx>(
hir::GenericBound::Outlives(ref lifetime) => {
let region = astconv.ast_region_to_region(lifetime, None);
let pred = ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(param_ty, region))
.to_predicate(astconv.tcx())
.potentially_quantified(astconv.tcx(), ty::PredicateKind::ForAll);
vec![(pred, lifetime.span)]
}
......
......@@ -3,7 +3,7 @@
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::{self, CratePredicatesMap, ToPredicate, TyCtxt};
use rustc_middle::ty::{self, CratePredicatesMap, TyCtxt};
use rustc_span::symbol::sym;
use rustc_span::Span;
......@@ -90,7 +90,6 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> CratePredica
match kind1.unpack() {
GenericArgKind::Type(ty1) => Some((
ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(ty1, region2))
.to_predicate(tcx)
.potentially_quantified(tcx, ty::PredicateKind::ForAll),
span,
)),
......@@ -98,7 +97,6 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> CratePredica
ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(
region1, region2,
))
.to_predicate(tcx)
.potentially_quantified(tcx, ty::PredicateKind::ForAll),
span,
)),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册