about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBastian Kauschke <bastian_kauschke@hotmail.de>2020-07-18 14:37:36 +0200
committerBastian Kauschke <bastian_kauschke@hotmail.de>2020-07-27 21:11:19 +0200
commit072cc458393974f9ff38b1448773c013c604c5fd (patch)
tree395f2cb6eabc19c310a77f8486f97ce9ef04c471
parent825cb5bdc925c4f2462c58c8aae5f7942a52a29f (diff)
downloadrust-072cc458393974f9ff38b1448773c013c604c5fd.tar.gz
rust-072cc458393974f9ff38b1448773c013c604c5fd.zip
it works again :tada:
-rw-r--r--src/librustc_middle/ty/mod.rs11
-rw-r--r--src/librustc_middle/ty/structural_impls.rs8
-rw-r--r--src/librustc_middle/ty/sty.rs3
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/mod.rs2
-rw-r--r--src/librustc_trait_selection/traits/fulfill.rs65
5 files changed, 47 insertions, 42 deletions
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 3bae1c13143..6f454e15aad 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -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))
     }
 }
diff --git a/src/librustc_middle/ty/structural_impls.rs b/src/librustc_middle/ty/structural_impls.rs
index cfe076e1207..21b8d7101a3 100644
--- a/src/librustc_middle/ty/structural_impls.rs
+++ b/src/librustc_middle/ty/structural_impls.rs
@@ -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),
         }
     }
 }
diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs
index 58a89c7fdb1..df8fa4d73dd 100644
--- a/src/librustc_middle/ty/sty.rs
+++ b/src/librustc_middle/ty/sty.rs
@@ -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>,
diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs
index 951e0b22026..349fa68a4da 100644
--- a/src/librustc_trait_selection/traits/error_reporting/mod.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs
@@ -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.
diff --git a/src/librustc_trait_selection/traits/fulfill.rs b/src/librustc_trait_selection/traits/fulfill.rs
index 25564d03e83..2b9621c9271 100644
--- a/src/librustc_trait_selection/traits/fulfill.rs
+++ b/src/librustc_trait_selection/traits/fulfill.rs
@@ -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));
-
-                        self.process_trait_obligation(
-                            obligation,
-                            trait_obligation,
-                            &mut pending_obligation.stalled_on,
-                        )
-                    }
-                    ty::PredicateAtom::Projection(projection) => {
-                        let project_obligation = obligation.with(Binder::bind(projection));
+                ty::PredicateAtom::Trait(trait_ref, _constness) => {
+                    let trait_obligation = obligation.with(Binder::bind(trait_ref));
 
-                        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_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.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();