Skip to content

Commit 072cc45

Browse files
committed
it works again 🎉
1 parent 825cb5b commit 072cc45

File tree

5 files changed

+47
-42
lines changed

5 files changed

+47
-42
lines changed

src/librustc_middle/ty/mod.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -1051,12 +1051,17 @@ impl<'tcx> Predicate<'tcx> {
10511051

10521052
/// Returns the inner `PredicateAtom`.
10531053
///
1054+
/// The returned atom may contain unbound variables bound to binders skipped in this method.
1055+
/// It is safe to reapply binders to the given atom.
1056+
///
10541057
/// Note that this method panics in case this predicate has unbound variables.
10551058
pub fn skip_binders(self) -> PredicateAtom<'tcx> {
1056-
// TODO no_escaping_vars
10571059
match self.kind() {
10581060
&PredicateKind::ForAll(binder) => binder.skip_binder(),
1059-
&ty::PredicateKind::Atom(atom) => atom,
1061+
&PredicateKind::Atom(atom) => {
1062+
debug_assert!(!atom.has_escaping_bound_vars());
1063+
atom
1064+
}
10601065
}
10611066
}
10621067

@@ -1378,7 +1383,7 @@ impl ToPredicate<'tcx> for PredicateKind<'tcx> {
13781383
impl ToPredicate<'tcx> for PredicateAtom<'tcx> {
13791384
#[inline(always)]
13801385
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
1381-
debug_assert!(!self.has_escaping_bound_vars(), "excaping bound vars for {:?}", self);
1386+
debug_assert!(!self.has_escaping_bound_vars(), "escaping bound vars for {:?}", self);
13821387
tcx.mk_predicate(ty::PredicateKind::Atom(self))
13831388
}
13841389
}

src/librustc_middle/ty/structural_impls.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -486,11 +486,9 @@ impl<'a, 'tcx> Lift<'tcx> for ty::ExistentialProjection<'a> {
486486
impl<'a, 'tcx> Lift<'tcx> for ty::PredicateKind<'a> {
487487
type Lifted = ty::PredicateKind<'tcx>;
488488
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
489-
match *self {
490-
ty::PredicateKind::ForAll(ref binder) => {
491-
tcx.lift(binder).map(ty::PredicateKind::ForAll)
492-
}
493-
ty::PredicateKind::Atom(ref atom) => tcx.lift(atom).map(ty::PredicateKind::Atom),
489+
match self {
490+
ty::PredicateKind::ForAll(binder) => tcx.lift(binder).map(ty::PredicateKind::ForAll),
491+
ty::PredicateKind::Atom(atom) => tcx.lift(atom).map(ty::PredicateKind::Atom),
494492
}
495493
}
496494
}

src/librustc_middle/ty/sty.rs

+3
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,9 @@ impl<T> Binder<T> {
897897

898898
/// Wraps `value` in a binder without actually binding any currently
899899
/// unbound variables.
900+
///
901+
/// Note that this will shift all debrujin indices of escaping bound variables
902+
/// by 1 to avoid accidential captures.
900903
pub fn wrap_nonbinding(tcx: TyCtxt<'tcx>, value: T) -> Binder<T>
901904
where
902905
T: TypeFoldable<'tcx>,

src/librustc_trait_selection/traits/error_reporting/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1100,7 +1100,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
11001100
for obligation in super::elaborate_predicates(self.tcx, std::iter::once(cond)) {
11011101
if let ty::PredicateAtom::Trait(implication, _) = obligation.predicate.skip_binders() {
11021102
let error = error.to_poly_trait_ref();
1103-
let implication = ty::Binder::bind(implication).to_poly_trait_ref();
1103+
let implication = ty::Binder::bind(implication.trait_ref);
11041104
// FIXME: I'm just not taking associated types at all here.
11051105
// Eventually I'll need to implement param-env-aware
11061106
// `Γ₁ ⊦ φ₁ => Γ₂ ⊦ φ₂` logic.

src/librustc_trait_selection/traits/fulfill.rs

+32-33
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_data_structures::obligation_forest::ProcessResult;
33
use rustc_data_structures::obligation_forest::{DoCompleted, Error, ForestObligation};
44
use rustc_data_structures::obligation_forest::{ObligationForest, ObligationProcessor};
55
use rustc_errors::ErrorReported;
6-
use rustc_infer::traits::{PolyTraitObligation, TraitEngine, TraitEngineExt as _};
6+
use rustc_infer::traits::{TraitObligation, TraitEngine, TraitEngineExt as _};
77
use rustc_middle::mir::interpret::ErrorHandled;
88
use rustc_middle::ty::error::ExpectedFound;
99
use rustc_middle::ty::ToPredicate;
@@ -320,41 +320,40 @@ impl<'a, 'b, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'tcx> {
320320
let infcx = self.selcx.infcx();
321321

322322
match obligation.predicate.kind() {
323-
ty::PredicateKind::ForAll(binder) => match binder.skip_binder().kind() {
324-
ty::PredicateKind::ForAll(_) => bug!("unexpected forall"),
323+
ty::PredicateKind::ForAll(binder) => match binder.skip_binder() {
325324
// Evaluation will discard candidates using the leak check.
326325
// This means we need to pass it the bound version of our
327326
// predicate.
328-
&ty::PredicateKind::Atom(atom) => match atom {
329-
ty::PredicateAtom::Trait(trait_ref, _constness) => {
330-
let trait_obligation = obligation.with(Binder::bind(trait_ref));
331-
332-
self.process_trait_obligation(
333-
obligation,
334-
trait_obligation,
335-
&mut pending_obligation.stalled_on,
336-
)
337-
}
338-
ty::PredicateAtom::Projection(projection) => {
339-
let project_obligation = obligation.with(Binder::bind(projection));
327+
ty::PredicateAtom::Trait(trait_ref, _constness) => {
328+
let trait_obligation = obligation.with(Binder::bind(trait_ref));
340329

341-
self.process_projection_obligation(
342-
project_obligation,
343-
&mut pending_obligation.stalled_on,
344-
)
345-
}
346-
ty::PredicateAtom::RegionOutlives(_)
347-
| ty::PredicateAtom::TypeOutlives(_)
348-
| ty::PredicateAtom::WellFormed(_)
349-
| ty::PredicateAtom::ObjectSafe(_)
350-
| ty::PredicateAtom::ClosureKind(..)
351-
| ty::PredicateAtom::Subtype(_)
352-
| ty::PredicateAtom::ConstEvaluatable(..)
353-
| ty::PredicateAtom::ConstEquate(..) => {
354-
let (pred, _) = infcx.replace_bound_vars_with_placeholders(binder);
355-
ProcessResult::Changed(mk_pending(vec![obligation.with(pred)]))
356-
}
357-
},
330+
self.process_trait_obligation(
331+
obligation,
332+
trait_obligation,
333+
&mut pending_obligation.stalled_on,
334+
)
335+
}
336+
ty::PredicateAtom::Projection(data) => {
337+
let project_obligation = obligation.with(Binder::bind(data));
338+
339+
self.process_projection_obligation(
340+
project_obligation,
341+
&mut pending_obligation.stalled_on,
342+
)
343+
}
344+
ty::PredicateAtom::RegionOutlives(_)
345+
| ty::PredicateAtom::TypeOutlives(_)
346+
| ty::PredicateAtom::WellFormed(_)
347+
| ty::PredicateAtom::ObjectSafe(_)
348+
| ty::PredicateAtom::ClosureKind(..)
349+
| ty::PredicateAtom::Subtype(_)
350+
| ty::PredicateAtom::ConstEvaluatable(..)
351+
| ty::PredicateAtom::ConstEquate(..) => {
352+
let (pred, _) = infcx.replace_bound_vars_with_placeholders(binder);
353+
ProcessResult::Changed(mk_pending(vec![
354+
obligation.with(pred.to_predicate(self.selcx.tcx())),
355+
]))
356+
}
358357
},
359358
&ty::PredicateKind::Atom(atom) => match atom {
360359
ty::PredicateAtom::Trait(ref data, _) => {
@@ -560,7 +559,7 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
560559
fn process_trait_obligation(
561560
&mut self,
562561
obligation: &PredicateObligation<'tcx>,
563-
trait_obligation: PolyTraitObligation<'tcx>,
562+
trait_obligation: TraitObligation<'tcx>,
564563
stalled_on: &mut Vec<TyOrConstInferVar<'tcx>>,
565564
) -> ProcessResult<PendingPredicateObligation<'tcx>, FulfillmentErrorCode<'tcx>> {
566565
let infcx = self.selcx.infcx();

0 commit comments

Comments
 (0)