it works again 🎉
This commit is contained in:
parent
825cb5bdc9
commit
072cc45839
5 changed files with 46 additions and 41 deletions
|
@ -1051,12 +1051,17 @@ impl<'tcx> Predicate<'tcx> {
|
|||
|
||||
/// Returns the inner `PredicateAtom`.
|
||||
///
|
||||
/// The returned atom may contain unbound variables bound to binders skipped in this method.
|
||||
/// It is safe to reapply binders to the given atom.
|
||||
///
|
||||
/// 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(),
|
||||
&ty::PredicateKind::Atom(atom) => atom,
|
||||
&PredicateKind::Atom(atom) => {
|
||||
debug_assert!(!atom.has_escaping_bound_vars());
|
||||
atom
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1378,7 +1383,7 @@ impl ToPredicate<'tcx> for PredicateKind<'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);
|
||||
debug_assert!(!self.has_escaping_bound_vars(), "escaping bound vars for {:?}", self);
|
||||
tcx.mk_predicate(ty::PredicateKind::Atom(self))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -486,11 +486,9 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
|
|||
impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
|
||||
type Lifted = ty::PredicateKind<'tcx>;
|
||||
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
match *self {
|
||||
ty::PredicateKind::ForAll(ref binder) => {
|
||||
tcx.lift(binder).map(ty::PredicateKind::ForAll)
|
||||
}
|
||||
ty::PredicateKind::Atom(ref atom) => tcx.lift(atom).map(ty::PredicateKind::Atom),
|
||||
match self {
|
||||
ty::PredicateKind::ForAll(binder) => tcx.lift(binder).map(ty::PredicateKind::ForAll),
|
||||
ty::PredicateKind::Atom(atom) => tcx.lift(atom).map(ty::PredicateKind::Atom),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -897,6 +897,9 @@ impl<T> Binder<T> {
|
|||
|
||||
/// Wraps `value` in a binder without actually binding any currently
|
||||
/// unbound variables.
|
||||
///
|
||||
/// Note that this will shift all debrujin indices of escaping bound variables
|
||||
/// by 1 to avoid accidential captures.
|
||||
pub fn wrap_nonbinding(tcx: TyCtxt<'tcx>, value: T) -> Binder<T>
|
||||
where
|
||||
T: TypeFoldable<'tcx>,
|
||||
|
|
|
@ -1100,7 +1100,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
|
|||
for obligation in super::elaborate_predicates(self.tcx, std::iter::once(cond)) {
|
||||
if let ty::PredicateAtom::Trait(implication, _) = obligation.predicate.skip_binders() {
|
||||
let error = error.to_poly_trait_ref();
|
||||
let implication = ty::Binder::bind(implication).to_poly_trait_ref();
|
||||
let implication = ty::Binder::bind(implication.trait_ref);
|
||||
// FIXME: I'm just not taking associated types at all here.
|
||||
// Eventually I'll need to implement param-env-aware
|
||||
// `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.
|
||||
|
|
|
@ -3,7 +3,7 @@ use rustc_data_structures::obligation_forest::ProcessResult;
|
|||
use rustc_data_structures::obligation_forest::{DoCompleted, Error, ForestObligation};
|
||||
use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
|
||||
use rustc_errors::ErrorReported;
|
||||
use rustc_infer::traits::{PolyTraitObligation, TraitEngine, TraitEngineExt as _};
|
||||
use rustc_infer::traits::{TraitObligation, TraitEngine, TraitEngineExt as _};
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::ty::error::ExpectedFound;
|
||||
use rustc_middle::ty::ToPredicate;
|
||||
|
@ -320,41 +320,40 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
|
|||
let infcx = self.selcx.infcx();
|
||||
|
||||
match obligation.predicate.kind() {
|
||||
ty::PredicateKind::ForAll(binder) => match binder.skip_binder().kind() {
|
||||
ty::PredicateKind::ForAll(_) => bug!("unexpected forall"),
|
||||
ty::PredicateKind::ForAll(binder) => match binder.skip_binder() {
|
||||
// Evaluation will discard candidates using the leak check.
|
||||
// This means we need to pass it the bound version of our
|
||||
// predicate.
|
||||
&ty::PredicateKind::Atom(atom) => match atom {
|
||||
ty::PredicateAtom::Trait(trait_ref, _constness) => {
|
||||
let trait_obligation = obligation.with(Binder::bind(trait_ref));
|
||||
ty::PredicateAtom::Trait(trait_ref, _constness) => {
|
||||
let trait_obligation = obligation.with(Binder::bind(trait_ref));
|
||||
|
||||
self.process_trait_obligation(
|
||||
obligation,
|
||||
trait_obligation,
|
||||
&mut pending_obligation.stalled_on,
|
||||
)
|
||||
}
|
||||
ty::PredicateAtom::Projection(projection) => {
|
||||
let project_obligation = obligation.with(Binder::bind(projection));
|
||||
self.process_trait_obligation(
|
||||
obligation,
|
||||
trait_obligation,
|
||||
&mut pending_obligation.stalled_on,
|
||||
)
|
||||
}
|
||||
ty::PredicateAtom::Projection(data) => {
|
||||
let project_obligation = obligation.with(Binder::bind(data));
|
||||
|
||||
self.process_projection_obligation(
|
||||
project_obligation,
|
||||
&mut pending_obligation.stalled_on,
|
||||
)
|
||||
}
|
||||
ty::PredicateAtom::RegionOutlives(_)
|
||||
| ty::PredicateAtom::TypeOutlives(_)
|
||||
| ty::PredicateAtom::WellFormed(_)
|
||||
| ty::PredicateAtom::ObjectSafe(_)
|
||||
| ty::PredicateAtom::ClosureKind(..)
|
||||
| ty::PredicateAtom::Subtype(_)
|
||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||
| ty::PredicateAtom::ConstEquate(..) => {
|
||||
let (pred, _) = infcx.replace_bound_vars_with_placeholders(binder);
|
||||
ProcessResult::Changed(mk_pending(vec![obligation.with(pred)]))
|
||||
}
|
||||
},
|
||||
self.process_projection_obligation(
|
||||
project_obligation,
|
||||
&mut pending_obligation.stalled_on,
|
||||
)
|
||||
}
|
||||
ty::PredicateAtom::RegionOutlives(_)
|
||||
| ty::PredicateAtom::TypeOutlives(_)
|
||||
| ty::PredicateAtom::WellFormed(_)
|
||||
| ty::PredicateAtom::ObjectSafe(_)
|
||||
| ty::PredicateAtom::ClosureKind(..)
|
||||
| ty::PredicateAtom::Subtype(_)
|
||||
| ty::PredicateAtom::ConstEvaluatable(..)
|
||||
| ty::PredicateAtom::ConstEquate(..) => {
|
||||
let (pred, _) = infcx.replace_bound_vars_with_placeholders(binder);
|
||||
ProcessResult::Changed(mk_pending(vec![
|
||||
obligation.with(pred.to_predicate(self.selcx.tcx())),
|
||||
]))
|
||||
}
|
||||
},
|
||||
&ty::PredicateKind::Atom(atom) => match atom {
|
||||
ty::PredicateAtom::Trait(ref data, _) => {
|
||||
|
@ -560,7 +559,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
|||
fn process_trait_obligation(
|
||||
&mut self,
|
||||
obligation: &PredicateObligation<'tcx>,
|
||||
trait_obligation: PolyTraitObligation<'tcx>,
|
||||
trait_obligation: TraitObligation<'tcx>,
|
||||
stalled_on: &mut Vec<TyOrConstInferVar<'tcx>>,
|
||||
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
|
||||
let infcx = self.selcx.infcx();
|
||||
|
|
Loading…
Add table
Reference in a new issue