about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBastian Kauschke <bastian_kauschke@hotmail.de>2020-06-21 12:26:17 +0200
committerBastian Kauschke <bastian_kauschke@hotmail.de>2020-07-27 21:06:36 +0200
commit1151d6204919202340e22cef15ca69aa183b41d1 (patch)
tree7da7b153abab2467bf1a49864a97be23331d8724
parentc6c0d17c8d6be89c6ef00de14fbafaf76d276d55 (diff)
downloadrust-1151d6204919202340e22cef15ca69aa183b41d1.tar.gz
rust-1151d6204919202340e22cef15ca69aa183b41d1.zip
split ignore_qualifiers
-rw-r--r--src/librustc_infer/infer/outlives/env.rs6
-rw-r--r--src/librustc_infer/infer/outlives/mod.rs3
-rw-r--r--src/librustc_infer/infer/outlives/verify.rs3
-rw-r--r--src/librustc_infer/traits/util.rs21
-rw-r--r--src/librustc_lint/builtin.rs24
-rw-r--r--src/librustc_lint/unused.rs2
-rw-r--r--src/librustc_middle/ty/mod.rs38
-rw-r--r--src/librustc_middle/ty/print/pretty.rs11
-rw-r--r--src/librustc_mir/borrow_check/diagnostics/region_errors.rs2
-rw-r--r--src/librustc_mir/borrow_check/type_check/free_region_relations.rs2
-rw-r--r--src/librustc_mir/transform/qualify_min_const_fn.rs2
-rw-r--r--src/librustc_privacy/lib.rs48
-rw-r--r--src/librustc_trait_selection/opaque_types.rs4
-rw-r--r--src/librustc_trait_selection/traits/auto_trait.rs6
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/mod.rs14
-rw-r--r--src/librustc_trait_selection/traits/error_reporting/suggestions.rs2
-rw-r--r--src/librustc_trait_selection/traits/mod.rs4
-rw-r--r--src/librustc_trait_selection/traits/object_safety.rs6
-rw-r--r--src/librustc_trait_selection/traits/project.rs6
-rw-r--r--src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs2
-rw-r--r--src/librustc_trait_selection/traits/select/candidate_assembly.rs3
-rw-r--r--src/librustc_trait_selection/traits/select/mod.rs10
-rw-r--r--src/librustc_trait_selection/traits/specialize/mod.rs2
-rw-r--r--src/librustc_trait_selection/traits/util.rs5
-rw-r--r--src/librustc_trait_selection/traits/wf.rs4
-rw-r--r--src/librustc_traits/chalk/lowering.rs29
-rw-r--r--src/librustc_traits/normalize_erasing_regions.rs8
-rw-r--r--src/librustc_ty/ty.rs17
-rw-r--r--src/librustc_typeck/astconv.rs4
-rw-r--r--src/librustc_typeck/check/closure.rs4
-rw-r--r--src/librustc_typeck/check/coercion.rs33
-rw-r--r--src/librustc_typeck/check/dropck.rs6
-rw-r--r--src/librustc_typeck/check/method/confirm.rs2
-rw-r--r--src/librustc_typeck/check/method/probe.rs1
-rw-r--r--src/librustc_typeck/check/method/suggest.rs6
-rw-r--r--src/librustc_typeck/check/mod.rs14
-rw-r--r--src/librustc_typeck/check/regionck.rs2
-rw-r--r--src/librustc_typeck/coherence/builtin.rs4
-rw-r--r--src/librustc_typeck/collect.rs5
-rw-r--r--src/librustc_typeck/constrained_generic_params.rs2
-rw-r--r--src/librustc_typeck/impl_wf_check/min_specialization.rs8
-rw-r--r--src/librustc_typeck/outlives/explicit.rs2
42 files changed, 196 insertions, 181 deletions
diff --git a/src/librustc_infer/infer/outlives/env.rs b/src/librustc_infer/infer/outlives/env.rs
index 59f3d01777c..1a9e20e79fe 100644
--- a/src/librustc_infer/infer/outlives/env.rs
+++ b/src/librustc_infer/infer/outlives/env.rs
@@ -3,7 +3,7 @@ use crate::infer::{GenericKind, InferCtxt};
 use crate::traits::query::OutlivesBound;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty;
 
 use super::explicit_outlives_bounds;
 
@@ -69,7 +69,7 @@ pub struct OutlivesEnvironment<'tcx> {
 pub type RegionBoundPairs<'tcx> = Vec<(ty::Region<'tcx>, GenericKind<'tcx>)>;
 
 impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
-    pub fn new(tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Self {
+    pub fn new(param_env: ty::ParamEnv<'tcx>) -> Self {
         let mut env = OutlivesEnvironment {
             param_env,
             free_region_map: Default::default(),
@@ -77,7 +77,7 @@ impl<'a, 'tcx> OutlivesEnvironment<'tcx> {
             region_bound_pairs_accum: vec![],
         };
 
-        env.add_outlives_bounds(None, explicit_outlives_bounds(tcx, param_env));
+        env.add_outlives_bounds(None, explicit_outlives_bounds(param_env));
 
         env
     }
diff --git a/src/librustc_infer/infer/outlives/mod.rs b/src/librustc_infer/infer/outlives/mod.rs
index ad1579083b6..541a2f18045 100644
--- a/src/librustc_infer/infer/outlives/mod.rs
+++ b/src/librustc_infer/infer/outlives/mod.rs
@@ -5,10 +5,9 @@ pub mod obligations;
 pub mod verify;
 
 use rustc_middle::traits::query::OutlivesBound;
-use rustc_middle::ty::{self, TyCtxt};
+use rustc_middle::ty;
 
 pub fn explicit_outlives_bounds<'tcx>(
-    tcx: TyCtxt<'tcx>,
     param_env: ty::ParamEnv<'tcx>,
 ) -> impl Iterator<Item = OutlivesBound<'tcx>> + 'tcx {
     debug!("explicit_outlives_bounds()");
diff --git a/src/librustc_infer/infer/outlives/verify.rs b/src/librustc_infer/infer/outlives/verify.rs
index 27d21dd0b70..8f20b5743df 100644
--- a/src/librustc_infer/infer/outlives/verify.rs
+++ b/src/librustc_infer/infer/outlives/verify.rs
@@ -331,9 +331,8 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
         compare_ty: impl Fn(Ty<'tcx>) -> bool,
         predicates: impl Iterator<Item = ty::Predicate<'tcx>>,
     ) -> impl Iterator<Item = ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>> {
-        let tcx = self.tcx;
         predicates
-            .filter_map(move |p| p.to_opt_type_outlives(tcx))
+            .filter_map(|p| p.to_opt_type_outlives())
             .filter_map(|p| p.no_bound_vars())
             .filter(move |p| compare_ty(p.0))
     }
diff --git a/src/librustc_infer/traits/util.rs b/src/librustc_infer/traits/util.rs
index a1944781df2..901685d1d84 100644
--- a/src/librustc_infer/traits/util.rs
+++ b/src/librustc_infer/traits/util.rs
@@ -131,14 +131,14 @@ fn predicate_obligation<'tcx>(
 }
 
 impl Elaborator<'tcx> {
-    pub fn filter_to_traits(self) -> FilterToTraits<'tcx, Self> {
-        FilterToTraits::new(self.visited.tcx, self)
+    pub fn filter_to_traits(self) -> FilterToTraits<Self> {
+        FilterToTraits::new(self)
     }
 
     fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
         let tcx = self.visited.tcx;
 
-        match obligation.predicate.ignore_qualifiers(tcx).skip_binder().kind() {
+        match obligation.predicate.ignore_qualifiers().skip_binder().kind() {
             ty::PredicateKind::ForAll(_) => {
                 bug!("unexpected predicate: {:?}", obligation.predicate)
             }
@@ -275,7 +275,7 @@ impl Iterator for Elaborator<'tcx> {
 // Supertrait iterator
 ///////////////////////////////////////////////////////////////////////////
 
-pub type Supertraits<'tcx> = FilterToTraits<'tcx, Elaborator<'tcx>>;
+pub type Supertraits<'tcx> = FilterToTraits<Elaborator<'tcx>>;
 
 pub fn supertraits<'tcx>(
     tcx: TyCtxt<'tcx>,
@@ -297,23 +297,22 @@ pub fn transitive_bounds<'tcx>(
 
 /// A filter around an iterator of predicates that makes it yield up
 /// just trait references.
-pub struct FilterToTraits<'tcx, I> {
-    tcx: TyCtxt<'tcx>,
+pub struct FilterToTraits<I> {
     base_iterator: I,
 }
 
-impl<'tcx, I> FilterToTraits<'tcx, I> {
-    fn new(tcx: TyCtxt<'tcx>, base: I) -> FilterToTraits<'tcx, I> {
-        FilterToTraits { tcx, base_iterator: base }
+impl<I> FilterToTraits<I> {
+    fn new(base: I) -> FilterToTraits<I> {
+        FilterToTraits { base_iterator: base }
     }
 }
 
-impl<'tcx, I: Iterator<Item = PredicateObligation<'tcx>>> Iterator for FilterToTraits<'tcx, I> {
+impl<'tcx, I: Iterator<Item = PredicateObligation<'tcx>>> Iterator for FilterToTraits<I> {
     type Item = ty::PolyTraitRef<'tcx>;
 
     fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
         while let Some(obligation) = self.base_iterator.next() {
-            if let Some(data) = obligation.predicate.to_opt_poly_trait_ref(self.tcx) {
+            if let Some(data) = obligation.predicate.to_opt_poly_trait_ref() {
                 return Some(data);
             }
         }
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index cedf742b9a9..9566cdb1643 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1210,7 +1210,7 @@ impl<'tcx> LateLintPass<'tcx> for TrivialConstraints {
             for &(predicate, span) in predicates.predicates {
                 // We don't actually look inside of the predicate,
                 // so it is safe to skip this binder here.
-                let predicate_kind_name = match predicate.ignore_qualifiers(cx.tcx).skip_binder().kind() {
+                let predicate_kind_name = match predicate.ignore_qualifiers().skip_binder().kind() {
                     Trait(..) => "Trait",
                     TypeOutlives(..) |
                     RegionOutlives(..) => "Lifetime",
@@ -1495,13 +1495,12 @@ declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMEN
 
 impl ExplicitOutlivesRequirements {
     fn lifetimes_outliving_lifetime<'tcx>(
-        tcx: TyCtxt<'tcx>,
         inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)],
         index: u32,
     ) -> Vec<ty::Region<'tcx>> {
         inferred_outlives
             .iter()
-            .filter_map(|(pred, _)| match pred.ignore_qualifiers(tcx).skip_binder().kind() {
+            .filter_map(|(pred, _)| match pred.ignore_qualifiers().skip_binder().kind() {
                 &ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(a, b)) => match a {
                     ty::ReEarlyBound(ebr) if ebr.index == index => Some(b),
                     _ => None,
@@ -1512,13 +1511,12 @@ impl ExplicitOutlivesRequirements {
     }
 
     fn lifetimes_outliving_type<'tcx>(
-        tcx: TyCtxt<'tcx>,
         inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)],
         index: u32,
     ) -> Vec<ty::Region<'tcx>> {
         inferred_outlives
             .iter()
-            .filter_map(|(pred, _)| match pred.ignore_qualifiers(tcx).skip_binder().kind() {
+            .filter_map(|(pred, _)| match pred.ignore_qualifiers().skip_binder().kind() {
                 &ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(a, b)) => {
                     a.is_param(index).then_some(b)
                 }
@@ -1539,10 +1537,10 @@ impl ExplicitOutlivesRequirements {
 
         match param.kind {
             hir::GenericParamKind::Lifetime { .. } => {
-                Self::lifetimes_outliving_lifetime(tcx, inferred_outlives, index)
+                Self::lifetimes_outliving_lifetime(inferred_outlives, index)
             }
             hir::GenericParamKind::Type { .. } => {
-                Self::lifetimes_outliving_type(tcx, inferred_outlives, index)
+                Self::lifetimes_outliving_type(inferred_outlives, index)
             }
             hir::GenericParamKind::Const { .. } => Vec::new(),
         }
@@ -1694,11 +1692,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
                             cx.tcx.named_region(predicate.lifetime.hir_id)
                         {
                             (
-                                Self::lifetimes_outliving_lifetime(
-                                    cx.tcx,
-                                    inferred_outlives,
-                                    index,
-                                ),
+                                Self::lifetimes_outliving_lifetime(inferred_outlives, index),
                                 &predicate.bounds,
                                 predicate.span,
                             )
@@ -1714,11 +1708,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitOutlivesRequirements {
                                 if let Res::Def(DefKind::TyParam, def_id) = path.res {
                                     let index = ty_generics.param_def_id_to_index[&def_id];
                                     (
-                                        Self::lifetimes_outliving_type(
-                                            cx.tcx,
-                                            inferred_outlives,
-                                            index,
-                                        ),
+                                        Self::lifetimes_outliving_type(inferred_outlives, index),
                                         &predicate.bounds,
                                         predicate.span,
                                     )
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 1430b799afc..3f1f397fc8e 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -148,7 +148,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
                     for (predicate, _) in cx.tcx.predicates_of(def).predicates {
                         // We only look at the `DefId`, so it is safe to skip the binder here.
                         if let ty::PredicateKind::Trait(ref poly_trait_predicate, _) =
-                            predicate.ignore_qualifiers(cx.tcx).skip_binder().kind()
+                            predicate.ignore_qualifiers().skip_binder().kind()
                         {
                             let def_id = poly_trait_predicate.trait_ref.def_id;
                             let descr_pre =
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 5b5996e84ee..3782f2b8404 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -1050,7 +1050,30 @@ impl<'tcx> Predicate<'tcx> {
     }
 
     /// Skips `PredicateKind::ForAll`.
-    pub fn ignore_qualifiers(self, tcx: TyCtxt<'tcx>) -> Binder<Predicate<'tcx>> {
+    pub fn ignore_qualifiers(self) -> Binder<Predicate<'tcx>> {
+        match self.kind() {
+            &PredicateKind::ForAll(binder) => binder,
+            ty::PredicateKind::Projection(..)
+            | ty::PredicateKind::Trait(..)
+            | ty::PredicateKind::Subtype(..)
+            | ty::PredicateKind::WellFormed(..)
+            | ty::PredicateKind::ObjectSafe(..)
+            | ty::PredicateKind::ClosureKind(..)
+            | ty::PredicateKind::TypeOutlives(..)
+            | ty::PredicateKind::ConstEvaluatable(..)
+            | ty::PredicateKind::ConstEquate(..)
+            | ty::PredicateKind::RegionOutlives(..) => Binder::dummy(self),
+        }
+    }
+
+    /// Skips `PredicateKind::ForAll`, while allowing for unbound variables.
+    ///
+    /// This method requires the `TyCtxt` as it has to shift the unbound variables
+    /// outwards.
+    ///
+    /// Do not use this method if you may end up just skipping the binder, as this
+    /// would leave the unbound variables at an incorrect binding level.
+    pub fn ignore_qualifiers_with_unbound_vars(self, tcx: TyCtxt<'tcx>) -> Binder<Predicate<'tcx>> {
         match self.kind() {
             &PredicateKind::ForAll(binder) => binder,
             ty::PredicateKind::Projection(..)
@@ -1226,7 +1249,7 @@ impl<'tcx> Predicate<'tcx> {
         // from the substitution and the value being substituted into, and
         // this trick achieves that).
         let substs = trait_ref.skip_binder().substs;
-        let pred = *self.ignore_qualifiers(tcx).skip_binder();
+        let pred = *self.ignore_qualifiers().skip_binder();
         let new = pred.subst(tcx, substs);
         if new != pred { new.potentially_qualified(tcx, PredicateKind::ForAll) } else { self }
     }
@@ -1427,8 +1450,8 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
 }
 
 impl<'tcx> Predicate<'tcx> {
-    pub fn to_opt_poly_trait_ref(self, tcx: TyCtxt<'tcx>) -> Option<PolyTraitRef<'tcx>> {
-        self.ignore_qualifiers(tcx)
+    pub fn to_opt_poly_trait_ref(self) -> Option<PolyTraitRef<'tcx>> {
+        self.ignore_qualifiers()
             .map_bound(|pred| match pred.kind() {
                 &PredicateKind::Trait(ref t, _) => Some(t.trait_ref),
                 PredicateKind::Projection(..)
@@ -1445,11 +1468,8 @@ impl<'tcx> Predicate<'tcx> {
             .transpose()
     }
 
-    pub fn to_opt_type_outlives(
-        self,
-        tcx: TyCtxt<'tcx>,
-    ) -> Option<PolyTypeOutlivesPredicate<'tcx>> {
-        self.ignore_qualifiers(tcx)
+    pub fn to_opt_type_outlives(self) -> Option<PolyTypeOutlivesPredicate<'tcx>> {
+        self.ignore_qualifiers()
             .map_bound(|pred| match pred.kind() {
                 &PredicateKind::TypeOutlives(data) => Some(data),
                 PredicateKind::Trait(..)
diff --git a/src/librustc_middle/ty/print/pretty.rs b/src/librustc_middle/ty/print/pretty.rs
index 1fdd7d4c824..1f9fc481883 100644
--- a/src/librustc_middle/ty/print/pretty.rs
+++ b/src/librustc_middle/ty/print/pretty.rs
@@ -572,7 +572,16 @@ pub trait PrettyPrinter<'tcx>:
                     let mut is_sized = false;
                     p!(write("impl"));
                     for predicate in bounds.predicates {
-                        if let Some(trait_ref) = predicate.to_opt_poly_trait_ref(self.tcx()) {
+                        // Note: We can't use `to_opt_poly_trait_ref` here as `predicate`
+                        // may contain unbound variables. We therefore do this manually.
+                        //
+                        // FIXME(lcnr): Find out why exactly this is the case :)
+                        if let ty::PredicateKind::Trait(pred, _) = predicate
+                            .ignore_qualifiers_with_unbound_vars(self.tcx())
+                            .skip_binder()
+                            .kind()
+                        {
+                            let trait_ref = ty::Binder::bind(pred.trait_ref);
                             // Don't print +Sized, but rather +?Sized if absent.
                             if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() {
                                 is_sized = true;
diff --git a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
index 4daebcec6ff..c28f23dc7d6 100644
--- a/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/region_errors.rs
@@ -590,7 +590,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                     let mut found = false;
                     for predicate in bounds.predicates {
                         if let ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(_, r)) =
-                            predicate.ignore_qualifiers(self.infcx.tcx).skip_binder().kind()
+                            predicate.ignore_qualifiers().skip_binder().kind()
                         {
                             if let ty::RegionKind::ReStatic = r {
                                 found = true;
diff --git a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs
index fe8d924debe..beee3181256 100644
--- a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs
+++ b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs
@@ -274,7 +274,7 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
 
         // Insert the facts we know from the predicates. Why? Why not.
         let param_env = self.param_env;
-        self.add_outlives_bounds(outlives::explicit_outlives_bounds(self.infcx.tcx, param_env));
+        self.add_outlives_bounds(outlives::explicit_outlives_bounds(param_env));
 
         // Finally:
         // - outlives is reflexive, so `'r: 'r` for every region `'r`
diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs
index f4bfc7d4b98..c176fbf90b6 100644
--- a/src/librustc_mir/transform/qualify_min_const_fn.rs
+++ b/src/librustc_mir/transform/qualify_min_const_fn.rs
@@ -24,7 +24,7 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) -
     loop {
         let predicates = tcx.predicates_of(current);
         for (predicate, _) in predicates.predicates {
-            match predicate.ignore_qualifiers(tcx).skip_binder().kind() {
+            match predicate.ignore_qualifiers().skip_binder().kind() {
                 ty::PredicateKind::ForAll(_) => bug!("unexpected predicate: {:?}", predicate),
                 ty::PredicateKind::RegionOutlives(_)
                 | ty::PredicateKind::TypeOutlives(_)
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 74f0e669ef3..3591a707ac0 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -84,31 +84,33 @@ where
             || (!self.def_id_visitor.shallow() && substs.visit_with(self))
     }
 
+    fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> bool {
+        match predicate.kind() {
+            &ty::PredicateKind::ForAll(pred) => {
+                // This visitor does not care about bound regions as we only
+                // look at `DefId`s.
+                self.visit_predicate(*pred.skip_binder())
+            }
+            &ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref }, _) => {
+                self.visit_trait(trait_ref)
+            }
+            &ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, ty }) => {
+                ty.visit_with(self)
+                    || self.visit_trait(projection_ty.trait_ref(self.def_id_visitor.tcx()))
+            }
+            &ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty, _region)) => {
+                ty.visit_with(self)
+            }
+            ty::PredicateKind::RegionOutlives(..) => false,
+            _ => bug!("unexpected predicate: {:?}", predicate),
+        }
+    }
+
     fn visit_predicates(&mut self, predicates: ty::GenericPredicates<'tcx>) -> bool {
         let ty::GenericPredicates { parent: _, predicates } = predicates;
-        for (predicate, _span) in predicates {
-            // This visitor does not care about bound regions.
-            match predicate.ignore_qualifiers(self.def_id_visitor.tcx()).skip_binder().kind() {
-                &ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref }, _) => {
-                    if self.visit_trait(trait_ref) {
-                        return true;
-                    }
-                }
-                &ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, ty }) => {
-                    if ty.visit_with(self) {
-                        return true;
-                    }
-                    if self.visit_trait(projection_ty.trait_ref(self.def_id_visitor.tcx())) {
-                        return true;
-                    }
-                }
-                &ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty, _region)) => {
-                    if ty.visit_with(self) {
-                        return true;
-                    }
-                }
-                ty::PredicateKind::RegionOutlives(..) => {}
-                _ => bug!("unexpected predicate: {:?}", predicate),
+        for &(predicate, _span) in predicates {
+            if self.visit_predicate(predicate) {
+                return true;
             }
         }
         false
diff --git a/src/librustc_trait_selection/opaque_types.rs b/src/librustc_trait_selection/opaque_types.rs
index 3c42400fbbc..b482f073858 100644
--- a/src/librustc_trait_selection/opaque_types.rs
+++ b/src/librustc_trait_selection/opaque_types.rs
@@ -1155,7 +1155,7 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
 
         for predicate in &bounds.predicates {
             if let ty::PredicateKind::Projection(projection) =
-                predicate.ignore_qualifiers(tcx).skip_binder().kind()
+                predicate.ignore_qualifiers().skip_binder().kind()
             {
                 if projection.ty.references_error() {
                     // No point on adding these obligations since there's a type error involved.
@@ -1254,7 +1254,7 @@ crate fn required_region_bounds(
     traits::elaborate_predicates(tcx, predicates)
         .filter_map(|obligation| {
             debug!("required_region_bounds(obligation={:?})", obligation);
-            match obligation.predicate.ignore_qualifiers(tcx).skip_binder().kind() {
+            match obligation.predicate.ignore_qualifiers().skip_binder().kind() {
                 ty::PredicateKind::Projection(..)
                 | ty::PredicateKind::Trait(..)
                 | ty::PredicateKind::Subtype(..)
diff --git a/src/librustc_trait_selection/traits/auto_trait.rs b/src/librustc_trait_selection/traits/auto_trait.rs
index aebe96f7ddc..2dbb4036397 100644
--- a/src/librustc_trait_selection/traits/auto_trait.rs
+++ b/src/librustc_trait_selection/traits/auto_trait.rs
@@ -418,8 +418,8 @@ impl AutoTraitFinder<'tcx> {
                 ty::PredicateKind::Trait(new_trait, _),
                 ty::PredicateKind::Trait(old_trait, _),
             ) = (
-                new_pred.ignore_qualifiers(self.tcx).skip_binder().kind(),
-                old_pred.ignore_qualifiers(self.tcx).skip_binder().kind(),
+                new_pred.ignore_qualifiers().skip_binder().kind(),
+                old_pred.ignore_qualifiers().skip_binder().kind(),
             ) {
                 if new_trait.def_id() == old_trait.def_id() {
                     let new_substs = new_trait.trait_ref.substs;
@@ -639,7 +639,7 @@ impl AutoTraitFinder<'tcx> {
             // We check this by calling is_of_param on the relevant types
             // from the various possible predicates
 
-            match predicate.ignore_qualifiers(self.tcx).skip_binder().kind() {
+            match predicate.ignore_qualifiers().skip_binder().kind() {
                 &ty::PredicateKind::Trait(p, _) => {
                     if self.is_param_no_infer(p.trait_ref.substs)
                         && !only_projections
diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs
index 75fe9b7701e..f5717285def 100644
--- a/src/librustc_trait_selection/traits/error_reporting/mod.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs
@@ -256,7 +256,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     return;
                 }
 
-                match obligation.predicate.ignore_qualifiers(tcx).skip_binder().kind() {
+                match obligation.predicate.ignore_qualifiers().skip_binder().kind() {
                     ty::PredicateKind::ForAll(_) => {
                         bug!("unexpected predicate: {:?}", obligation.predicate)
                     }
@@ -1091,8 +1091,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
 
         // FIXME: It should be possible to deal with `ForAll` in a cleaner way.
         let (cond, error) = match (
-            cond.ignore_qualifiers(self.tcx).skip_binder().kind(),
-            error.ignore_qualifiers(self.tcx).skip_binder().kind(),
+            cond.ignore_qualifiers().skip_binder().kind(),
+            error.ignore_qualifiers().skip_binder().kind(),
         ) {
             (ty::PredicateKind::Trait(..), &ty::PredicateKind::Trait(error, _)) => {
                 (cond, ty::Binder::bind(error))
@@ -1105,7 +1105,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::PredicateKind::Trait(implication, _) =
-                obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind()
+                obligation.predicate.ignore_qualifiers().skip_binder().kind()
             {
                 let error = error.to_poly_trait_ref();
                 let implication = ty::Binder::bind(implication).to_poly_trait_ref();
@@ -1187,7 +1187,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
             // this can fail if the problem was higher-ranked, in which
             // cause I have no idea for a good error message.
             if let &ty::PredicateKind::Projection(data) =
-                predicate.ignore_qualifiers(self.tcx).skip_binder().kind()
+                predicate.ignore_qualifiers().skip_binder().kind()
             {
                 let mut selcx = SelectionContext::new(self);
                 let (data, _) = self.replace_bound_vars_with_fresh_vars(
@@ -1480,7 +1480,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
             return;
         }
 
-        let mut err = match predicate.ignore_qualifiers(self.tcx).skip_binder().kind() {
+        let mut err = match predicate.ignore_qualifiers().skip_binder().kind() {
             &ty::PredicateKind::Trait(data, _) => {
                 let trait_ref = ty::Binder::bind(data.trait_ref);
                 let self_ty = trait_ref.skip_binder().self_ty();
@@ -1734,7 +1734,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
         obligation: &PredicateObligation<'tcx>,
     ) {
         let (pred, item_def_id, span) = match (
-            obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind(),
+            obligation.predicate.ignore_qualifiers().skip_binder().kind(),
             obligation.cause.code.peel_derives(),
         ) {
             (
diff --git a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
index 7e3d4908f9a..1b618cea600 100644
--- a/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/suggestions.rs
@@ -1300,7 +1300,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
         // bound was introduced. At least one generator should be present for this diagnostic to be
         // modified.
         let (mut trait_ref, mut target_ty) =
-            match obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind() {
+            match obligation.predicate.ignore_qualifiers().skip_binder().kind() {
                 ty::PredicateKind::Trait(p, _) => (Some(p.trait_ref), Some(p.self_ty())),
                 _ => (None, None),
             };
diff --git a/src/librustc_trait_selection/traits/mod.rs b/src/librustc_trait_selection/traits/mod.rs
index da17d89b8c1..54df3559683 100644
--- a/src/librustc_trait_selection/traits/mod.rs
+++ b/src/librustc_trait_selection/traits/mod.rs
@@ -237,7 +237,7 @@ fn do_normalize_predicates<'tcx>(
 
         // We can use the `elaborated_env` here; the region code only
         // cares about declarations like `'a: 'b`.
-        let outlives_env = OutlivesEnvironment::new(tcx, elaborated_env);
+        let outlives_env = OutlivesEnvironment::new(elaborated_env);
 
         infcx.resolve_regions_and_report_errors(
             region_context,
@@ -328,7 +328,7 @@ pub fn normalize_param_env_or_error<'tcx>(
     // This works fairly well because trait matching  does not actually care about param-env
     // TypeOutlives predicates - these are normally used by regionck.
     let outlives_predicates: Vec<_> = predicates
-        .drain_filter(|predicate| match predicate.ignore_qualifiers(tcx).skip_binder().kind() {
+        .drain_filter(|predicate| match predicate.ignore_qualifiers().skip_binder().kind() {
             ty::PredicateKind::TypeOutlives(..) => true,
             _ => false,
         })
diff --git a/src/librustc_trait_selection/traits/object_safety.rs b/src/librustc_trait_selection/traits/object_safety.rs
index 5ad43084e7f..b3525ddeb21 100644
--- a/src/librustc_trait_selection/traits/object_safety.rs
+++ b/src/librustc_trait_selection/traits/object_safety.rs
@@ -245,7 +245,7 @@ fn predicates_reference_self(
         .iter()
         .map(|(predicate, sp)| (predicate.subst_supertrait(tcx, &trait_ref), sp))
         .filter_map(|(predicate, &sp)| {
-            match predicate.ignore_qualifiers(tcx).skip_binder().kind() {
+            match predicate.ignore_qualifiers().skip_binder().kind() {
                 ty::PredicateKind::Trait(ref data, _) => {
                     // In the case of a trait predicate, we can skip the "self" type.
                     if data.trait_ref.substs[1..].iter().any(has_self_ty) { Some(sp) } else { None }
@@ -299,7 +299,7 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
     let predicates = tcx.predicates_of(def_id);
     let predicates = predicates.instantiate_identity(tcx).predicates;
     elaborate_predicates(tcx, predicates.into_iter()).any(|obligation| {
-        match obligation.predicate.ignore_qualifiers(tcx).skip_binder().kind() {
+        match obligation.predicate.ignore_qualifiers().skip_binder().kind() {
             ty::PredicateKind::Trait(ref trait_pred, _) => {
                 trait_pred.def_id() == sized_def_id && trait_pred.self_ty().is_param(0)
             }
@@ -400,7 +400,7 @@ fn virtual_call_violation_for_method<'tcx>(
         // A trait object can't claim to live more than the concrete type,
         // so outlives predicates will always hold.
         .cloned()
-        .filter(|(p, _)| p.to_opt_type_outlives(tcx).is_none())
+        .filter(|(p, _)| p.to_opt_type_outlives().is_none())
         .collect::<Vec<_>>()
         // Do a shallow visit so that `contains_illegal_self_type_reference`
         // may apply it's custom visiting.
diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs
index c2ae26d9d25..a5199b7fbef 100644
--- a/src/librustc_trait_selection/traits/project.rs
+++ b/src/librustc_trait_selection/traits/project.rs
@@ -665,7 +665,7 @@ fn prune_cache_value_obligations<'a, 'tcx>(
         .obligations
         .iter()
         .filter(|obligation| {
-            match obligation.predicate.ignore_qualifiers(infcx.tcx).skip_binder().kind() {
+            match obligation.predicate.ignore_qualifiers().skip_binder().kind() {
                 // We found a `T: Foo<X = U>` predicate, let's check
                 // if `U` references any unresolved type
                 // variables. In principle, we only care if this
@@ -934,7 +934,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
     for predicate in env_predicates {
         debug!("assemble_candidates_from_predicates: predicate={:?}", predicate);
         if let &ty::PredicateKind::Projection(data) =
-            predicate.ignore_qualifiers(infcx.tcx).skip_binder().kind()
+            predicate.ignore_qualifiers().skip_binder().kind()
         {
             let data = ty::Binder::bind(data);
             let same_def_id = data.projection_def_id() == obligation.predicate.item_def_id;
@@ -1228,7 +1228,7 @@ fn confirm_object_candidate<'cx, 'tcx>(
         // item with the correct name
 
         let env_predicates = env_predicates.filter_map(|o| {
-            match o.predicate.ignore_qualifiers(selcx.tcx()).skip_binder().kind() {
+            match o.predicate.ignore_qualifiers().skip_binder().kind() {
                 &ty::PredicateKind::Projection(data)
                     if data.projection_ty.item_def_id == obligation.predicate.item_def_id =>
                 {
diff --git a/src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs b/src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs
index f2a6677e2f6..76154adb175 100644
--- a/src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs
+++ b/src/librustc_trait_selection/traits/query/type_op/prove_predicate.rs
@@ -16,7 +16,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
         // we have to prove. No need to canonicalize and all that for
         // such cases.
         if let ty::PredicateKind::Trait(trait_ref, _) =
-            key.value.predicate.ignore_qualifiers(tcx).skip_binder().kind()
+            key.value.predicate.ignore_qualifiers().skip_binder().kind()
         {
             if let Some(sized_def_id) = tcx.lang_items().sized_trait() {
                 if trait_ref.def_id() == sized_def_id {
diff --git a/src/librustc_trait_selection/traits/select/candidate_assembly.rs b/src/librustc_trait_selection/traits/select/candidate_assembly.rs
index 7b654856dde..1d5441b8eff 100644
--- a/src/librustc_trait_selection/traits/select/candidate_assembly.rs
+++ b/src/librustc_trait_selection/traits/select/candidate_assembly.rs
@@ -181,7 +181,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         stack: &TraitObligationStack<'o, 'tcx>,
         candidates: &mut SelectionCandidateSet<'tcx>,
     ) -> Result<(), SelectionError<'tcx>> {
-        let tcx = self.tcx();
         debug!("assemble_candidates_from_caller_bounds({:?})", stack.obligation);
 
         let all_bounds = stack
@@ -189,7 +188,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             .param_env
             .caller_bounds()
             .iter()
-            .filter_map(move |o| o.to_opt_poly_trait_ref(tcx));
+            .filter_map(|o| o.to_opt_poly_trait_ref());
 
         // Micro-optimization: filter out predicates relating to different traits.
         let matching_bounds =
diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs
index 1bc53f0c5c5..f8b2e092581 100644
--- a/src/librustc_trait_selection/traits/select/mod.rs
+++ b/src/librustc_trait_selection/traits/select/mod.rs
@@ -408,7 +408,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             None => self.check_recursion_limit(&obligation, &obligation)?,
         }
 
-        match obligation.predicate.ignore_qualifiers(self.tcx()).skip_binder().kind() {
+        match obligation.predicate.ignore_qualifiers().skip_binder().kind() {
             ty::PredicateKind::ForAll(_) => {
                 bug!("unexpected predicate: {:?}", obligation.predicate)
             }
@@ -792,7 +792,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     }
 
     fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool {
-        let result = match predicate.ignore_qualifiers(self.tcx()).skip_binder().kind() {
+        let result = match predicate.ignore_qualifiers().skip_binder().kind() {
             ty::PredicateKind::Trait(ref data, _) => self.tcx().trait_is_auto(data.def_id()),
             _ => false,
         };
@@ -1301,8 +1301,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         };
 
         let matching_bound = predicates.iter().find_map(|bound| {
-            if let ty::PredicateKind::Trait(bound, _) = bound.kind() {
-                let bound = bound.to_poly_trait_ref();
+            if let ty::PredicateKind::Trait(pred, _) =
+                bound.ignore_qualifiers().skip_binder().kind()
+            {
+                let bound = ty::Binder::bind(pred.trait_ref);
                 if self.infcx.probe(|_| {
                     self.match_projection(obligation, bound, placeholder_trait_predicate.trait_ref)
                 }) {
diff --git a/src/librustc_trait_selection/traits/specialize/mod.rs b/src/librustc_trait_selection/traits/specialize/mod.rs
index dda2e03d779..9b737d46417 100644
--- a/src/librustc_trait_selection/traits/specialize/mod.rs
+++ b/src/librustc_trait_selection/traits/specialize/mod.rs
@@ -497,7 +497,7 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String>
         Vec::with_capacity(predicates.len() + types_without_default_bounds.len());
 
     for (p, _) in predicates {
-        if let Some(poly_trait_ref) = p.to_opt_poly_trait_ref(tcx) {
+        if let Some(poly_trait_ref) = p.to_opt_poly_trait_ref() {
             if Some(poly_trait_ref.def_id()) == sized_trait {
                 types_without_default_bounds.remove(poly_trait_ref.self_ty().skip_binder());
                 continue;
diff --git a/src/librustc_trait_selection/traits/util.rs b/src/librustc_trait_selection/traits/util.rs
index d2fdfb45617..cc8997078e0 100644
--- a/src/librustc_trait_selection/traits/util.rs
+++ b/src/librustc_trait_selection/traits/util.rs
@@ -120,7 +120,7 @@ impl<'tcx> TraitAliasExpander<'tcx> {
 
         let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| {
             pred.subst_supertrait(tcx, &trait_ref)
-                .to_opt_poly_trait_ref(tcx)
+                .to_opt_poly_trait_ref()
                 .map(|trait_ref| item.clone_and_push(trait_ref, *span))
         });
         debug!("expand_trait_aliases: items={:?}", items.clone());
@@ -170,7 +170,6 @@ impl Iterator for SupertraitDefIds<'tcx> {
     type Item = DefId;
 
     fn next(&mut self) -> Option<DefId> {
-        let tcx = self.tcx;
         let def_id = self.stack.pop()?;
         let predicates = self.tcx.super_predicates_of(def_id);
         let visited = &mut self.visited;
@@ -178,7 +177,7 @@ impl Iterator for SupertraitDefIds<'tcx> {
             predicates
                 .predicates
                 .iter()
-                .filter_map(move |(pred, _)| pred.to_opt_poly_trait_ref(tcx))
+                .filter_map(|(pred, _)| pred.to_opt_poly_trait_ref())
                 .map(|trait_ref| trait_ref.def_id())
                 .filter(|&super_def_id| visited.insert(super_def_id)),
         );
diff --git a/src/librustc_trait_selection/traits/wf.rs b/src/librustc_trait_selection/traits/wf.rs
index da1a34871d0..fd762f9d571 100644
--- a/src/librustc_trait_selection/traits/wf.rs
+++ b/src/librustc_trait_selection/traits/wf.rs
@@ -196,7 +196,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
         };
 
     // It is fine to skip the binder as we don't care about regions here.
-    match pred.ignore_qualifiers(tcx).skip_binder().kind() {
+    match pred.ignore_qualifiers().skip_binder().kind() {
         ty::PredicateKind::Projection(proj) => {
             // The obligation comes not from the current `impl` nor the `trait` being implemented,
             // but rather from a "second order" obligation, where an associated type has a
@@ -269,7 +269,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
 
         let extend = |obligation: traits::PredicateObligation<'tcx>| {
             let mut cause = cause.clone();
-            if let Some(parent_trait_ref) = obligation.predicate.to_opt_poly_trait_ref(tcx) {
+            if let Some(parent_trait_ref) = obligation.predicate.to_opt_poly_trait_ref() {
                 let derived_cause = traits::DerivedObligationCause {
                     parent_trait_ref,
                     parent_code: Rc::new(obligation.cause.code.clone()),
diff --git a/src/librustc_traits/chalk/lowering.rs b/src/librustc_traits/chalk/lowering.rs
index 7154b3fb378..7857b19bd90 100644
--- a/src/librustc_traits/chalk/lowering.rs
+++ b/src/librustc_traits/chalk/lowering.rs
@@ -79,7 +79,11 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
         let clauses = self.environment.into_iter().filter_map(|clause| match clause {
             ChalkEnvironmentClause::Predicate(predicate) => {
                 // FIXME(chalk): forall
-                match predicate.ignore_qualifiers(interner.tcx).skip_binder().kind() {
+                match predicate
+                    .ignore_qualifiers_with_unbound_vars(interner.tcx)
+                    .skip_binder()
+                    .kind()
+                {
                     ty::PredicateKind::ForAll(_) => bug!("unexpected predicate: {:?}", predicate),
                     &ty::PredicateKind::Trait(predicate, _) => {
                         let predicate = ty::Binder::bind(predicate);
@@ -102,9 +106,10 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
                             .intern(interner),
                         )
                     }
-                    ty::PredicateKind::RegionOutlives(predicate) => {
+                    &ty::PredicateKind::RegionOutlives(predicate) => {
+                        let predicate = ty::Binder::bind(predicate);
                         let (predicate, binders, _named_regions) =
-                            collect_bound_vars(interner, interner.tcx, predicate);
+                            collect_bound_vars(interner, interner.tcx, &predicate);
 
                         Some(
                             chalk_ir::ProgramClauseData(chalk_ir::Binders::new(
@@ -186,14 +191,15 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::InEnvironment<chalk_ir::Goal<RustInterner<'
 impl<'tcx> LowerInto<'tcx, chalk_ir::GoalData<RustInterner<'tcx>>> for ty::Predicate<'tcx> {
     fn lower_into(self, interner: &RustInterner<'tcx>) -> chalk_ir::GoalData<RustInterner<'tcx>> {
         // FIXME(chalk): forall
-        match self.ignore_qualifiers(interner.tcx).skip_binder().kind() {
+        match self.ignore_qualifiers_with_unbound_vars(interner.tcx).skip_binder().kind() {
             ty::PredicateKind::ForAll(_) => bug!("unexpected predicate: {:?}", self),
             &ty::PredicateKind::Trait(predicate, _) => {
                 ty::Binder::bind(predicate).lower_into(interner)
             }
-            ty::PredicateKind::RegionOutlives(predicate) => {
+            &ty::PredicateKind::RegionOutlives(predicate) => {
+                let predicate = ty::Binder::bind(predicate);
                 let (predicate, binders, _named_regions) =
-                    collect_bound_vars(interner, interner.tcx, predicate);
+                    collect_bound_vars(interner, interner.tcx, &predicate);
 
                 chalk_ir::GoalData::Quantified(
                     chalk_ir::QuantifierKind::ForAll,
@@ -555,21 +561,22 @@ impl<'tcx> LowerInto<'tcx, Option<chalk_ir::QuantifiedWhereClause<RustInterner<'
         interner: &RustInterner<'tcx>,
     ) -> Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>> {
         // FIXME(chalk): forall
-        match self.ignore_qualifiers(interner.tcx).skip_binder().kind() {
+        match self.ignore_qualifiers_with_unbound_vars(interner.tcx).skip_binder().kind() {
             ty::PredicateKind::ForAll(_) => bug!("unexpected predicate: {:?}", self),
             &ty::PredicateKind::Trait(predicate, _) => {
-                let predicate = &ty::Binder::bind(predicate);
+                let predicate = ty::Binder::bind(predicate);
                 let (predicate, binders, _named_regions) =
-                    collect_bound_vars(interner, interner.tcx, predicate);
+                    collect_bound_vars(interner, interner.tcx, &predicate);
 
                 Some(chalk_ir::Binders::new(
                     binders,
                     chalk_ir::WhereClause::Implemented(predicate.trait_ref.lower_into(interner)),
                 ))
             }
-            ty::PredicateKind::RegionOutlives(predicate) => {
+            &ty::PredicateKind::RegionOutlives(predicate) => {
+                let predicate = ty::Binder::bind(predicate);
                 let (predicate, binders, _named_regions) =
-                    collect_bound_vars(interner, interner.tcx, predicate);
+                    collect_bound_vars(interner, interner.tcx, &predicate);
 
                 Some(chalk_ir::Binders::new(
                     binders,
diff --git a/src/librustc_traits/normalize_erasing_regions.rs b/src/librustc_traits/normalize_erasing_regions.rs
index 8415690d41f..cdc22b987a7 100644
--- a/src/librustc_traits/normalize_erasing_regions.rs
+++ b/src/librustc_traits/normalize_erasing_regions.rs
@@ -27,9 +27,7 @@ fn normalize_generic_arg_after_erasing_regions<'tcx>(
                 // always only region relations, and we are about to
                 // erase those anyway:
                 debug_assert_eq!(
-                    normalized_obligations
-                        .iter()
-                        .find(|p| not_outlives_predicate(tcx, &p.predicate)),
+                    normalized_obligations.iter().find(|p| not_outlives_predicate(&p.predicate)),
                     None,
                 );
 
@@ -41,8 +39,8 @@ fn normalize_generic_arg_after_erasing_regions<'tcx>(
     })
 }
 
-fn not_outlives_predicate(tcx: TyCtxt<'tcx>, p: &ty::Predicate<'tcx>) -> bool {
-    match p.ignore_qualifiers(tcx).skip_binder().kind() {
+fn not_outlives_predicate(p: &ty::Predicate<'tcx>) -> bool {
+    match p.ignore_qualifiers().skip_binder().kind() {
         ty::PredicateKind::RegionOutlives(..) | ty::PredicateKind::TypeOutlives(..) => false,
         ty::PredicateKind::ForAll(_) => bug!("unexpected predicate: {:?}", p),
         ty::PredicateKind::Trait(..)
diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs
index c99bc8a47e3..9daf665dd41 100644
--- a/src/librustc_ty/ty.rs
+++ b/src/librustc_ty/ty.rs
@@ -392,23 +392,23 @@ fn associated_type_projection_predicates(
 
     let predicates = item_predicates.filter_map(|obligation| {
         let pred = obligation.predicate;
-        match pred.kind() {
+        match pred.ignore_qualifiers().skip_binder().kind() {
             ty::PredicateKind::Trait(tr, _) => {
-                if let ty::Projection(p) = tr.skip_binder().self_ty().kind {
+                if let ty::Projection(p) = tr.self_ty().kind {
                     if p == assoc_item_ty {
                         return Some(pred);
                     }
                 }
             }
             ty::PredicateKind::Projection(proj) => {
-                if let ty::Projection(p) = proj.skip_binder().projection_ty.self_ty().kind {
+                if let ty::Projection(p) = proj.projection_ty.self_ty().kind {
                     if p == assoc_item_ty {
                         return Some(pred);
                     }
                 }
             }
             ty::PredicateKind::TypeOutlives(outlives) => {
-                if let ty::Projection(p) = outlives.skip_binder().0.kind {
+                if let ty::Projection(p) = outlives.0.kind {
                     if p == assoc_item_ty {
                         return Some(pred);
                     }
@@ -443,17 +443,16 @@ fn opaque_type_projection_predicates(
 
     let filtered_predicates = predicates.filter_map(|obligation| {
         let pred = obligation.predicate;
-        match pred.kind() {
+        match pred.ignore_qualifiers().skip_binder().kind() {
             ty::PredicateKind::Trait(tr, _) => {
-                if let ty::Opaque(opaque_def_id, opaque_substs) = tr.skip_binder().self_ty().kind {
+                if let ty::Opaque(opaque_def_id, opaque_substs) = tr.self_ty().kind {
                     if opaque_def_id == def_id && opaque_substs == substs {
                         return Some(pred);
                     }
                 }
             }
             ty::PredicateKind::Projection(proj) => {
-                if let ty::Opaque(opaque_def_id, opaque_substs) =
-                    proj.skip_binder().projection_ty.self_ty().kind
+                if let ty::Opaque(opaque_def_id, opaque_substs) = proj.projection_ty.self_ty().kind
                 {
                     if opaque_def_id == def_id && opaque_substs == substs {
                         return Some(pred);
@@ -461,7 +460,7 @@ fn opaque_type_projection_predicates(
                 }
             }
             ty::PredicateKind::TypeOutlives(outlives) => {
-                if let ty::Opaque(opaque_def_id, opaque_substs) = outlives.skip_binder().0.kind {
+                if let ty::Opaque(opaque_def_id, opaque_substs) = outlives.0.kind {
                     if opaque_def_id == def_id && opaque_substs == substs {
                         return Some(pred);
                     }
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index c028597ccd2..01d48ece663 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1706,7 +1706,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     obligation.predicate
                 );
 
-                match obligation.predicate.ignore_qualifiers(tcx).skip_binder().kind() {
+                match obligation.predicate.ignore_qualifiers().skip_binder().kind() {
                     &ty::PredicateKind::Trait(pred, _) => {
                         let pred = ty::Binder::bind(pred);
                         associated_types.entry(span).or_default().extend(
@@ -2097,7 +2097,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             || {
                 traits::transitive_bounds(
                     tcx,
-                    predicates.iter().filter_map(move |(p, _)| p.to_opt_poly_trait_ref(tcx)),
+                    predicates.iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref()),
                 )
             },
             || param_name.to_string(),
diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs
index 9d88a35901e..3918eac23ea 100644
--- a/src/librustc_typeck/check/closure.rs
+++ b/src/librustc_typeck/check/closure.rs
@@ -207,7 +207,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 );
 
                 if let &ty::PredicateKind::Projection(proj_predicate) =
-                    obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind()
+                    obligation.predicate.ignore_qualifiers().skip_binder().kind()
                 {
                     // Given a Projection predicate, we can potentially infer
                     // the complete signature.
@@ -632,7 +632,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // will be our output.
         let output_ty = self.obligations_for_self_ty(ret_vid).find_map(|(_, obligation)| {
             if let &ty::PredicateKind::Projection(proj_predicate) =
-                obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind()
+                obligation.predicate.ignore_qualifiers().skip_binder().kind()
             {
                 self.deduce_future_output_from_projection(
                     obligation.cause.span,
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 6b3d986e7b1..4df39971afa 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -582,25 +582,24 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         while !queue.is_empty() {
             let obligation = queue.remove(0);
             debug!("coerce_unsized resolve step: {:?}", obligation);
-            let trait_pred =
-                match obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind() {
-                    &ty::PredicateKind::Trait(trait_pred, _)
-                        if traits.contains(&trait_pred.def_id()) =>
-                    {
-                        if unsize_did == trait_pred.def_id() {
-                            let unsize_ty = trait_pred.trait_ref.substs[1].expect_ty();
-                            if let ty::Tuple(..) = unsize_ty.kind {
-                                debug!("coerce_unsized: found unsized tuple coercion");
-                                has_unsized_tuple_coercion = true;
-                            }
+            let trait_pred = match obligation.predicate.ignore_qualifiers().skip_binder().kind() {
+                &ty::PredicateKind::Trait(trait_pred, _)
+                    if traits.contains(&trait_pred.def_id()) =>
+                {
+                    if unsize_did == trait_pred.def_id() {
+                        let unsize_ty = trait_pred.trait_ref.substs[1].expect_ty();
+                        if let ty::Tuple(..) = unsize_ty.kind {
+                            debug!("coerce_unsized: found unsized tuple coercion");
+                            has_unsized_tuple_coercion = true;
                         }
-                        ty::Binder::bind(trait_pred)
-                    }
-                    _ => {
-                        coercion.obligations.push(obligation);
-                        continue;
                     }
-                };
+                    ty::Binder::bind(trait_pred)
+                }
+                _ => {
+                    coercion.obligations.push(obligation);
+                    continue;
+                }
+            };
             match selcx.select(&obligation.with(trait_pred)) {
                 // Uncertain or unimplemented.
                 Ok(None) => {
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index ae288ef6af7..c06bbc3d015 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -127,7 +127,7 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
         // it did the wrong thing, so I chose to preserve existing
         // behavior, since it ought to be simply more
         // conservative. -nmatsakis
-        let outlives_env = OutlivesEnvironment::new(infcx.tcx, ty::ParamEnv::empty());
+        let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty());
 
         infcx.resolve_regions_and_report_errors(
             drop_impl_did.to_def_id(),
@@ -227,8 +227,8 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
         let predicate_matches_closure = |p: Predicate<'tcx>| {
             let mut relator: SimpleEqRelation<'tcx> = SimpleEqRelation::new(tcx, self_param_env);
             match (
-                predicate.ignore_qualifiers(tcx).skip_binder().kind(),
-                p.ignore_qualifiers(tcx).skip_binder().kind(),
+                predicate.ignore_qualifiers().skip_binder().kind(),
+                p.ignore_qualifiers().skip_binder().kind(),
             ) {
                 (&ty::PredicateKind::Trait(a, _), &ty::PredicateKind::Trait(b, _)) => {
                     relator.relate(ty::Binder::bind(a), ty::Binder::bind(b)).is_ok()
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index a9f663fff48..645862fa924 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -449,7 +449,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
         traits::elaborate_predicates(self.tcx, predicates.predicates.iter().copied())
             // We don't care about regions here.
             .filter_map(|obligation| {
-                match obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind() {
+                match obligation.predicate.ignore_qualifiers().skip_binder().kind() {
                     ty::PredicateKind::Trait(trait_pred, _)
                         if trait_pred.def_id() == sized_def_id =>
                     {
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index 90ebce8dc18..9c5e3cbc938 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -795,7 +795,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
     }
 
     fn assemble_inherent_candidates_from_param(&mut self, param_ty: ty::ParamTy) {
-        let tcx = self.tcx;
         // FIXME: do we want to commit to this behavior for param bounds?
         debug!("assemble_inherent_candidates_from_param(param_ty={:?})", param_ty);
 
diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs
index ddf539277b9..0900bc583ae 100644
--- a/src/librustc_typeck/check/method/suggest.rs
+++ b/src/librustc_typeck/check/method/suggest.rs
@@ -578,7 +578,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             // We don't care about regions here, so it's fine to skip the binder here.
                             if let (ty::Param(_), ty::PredicateKind::Trait(p, _)) = (
                                 &self_ty.kind,
-                                parent_pred.ignore_qualifiers(tcx).skip_binder().kind(),
+                                parent_pred.ignore_qualifiers().skip_binder().kind(),
                             ) {
                                 if let ty::Adt(def, _) = p.trait_ref.self_ty().kind {
                                     let node = def.did.as_local().map(|def_id| {
@@ -631,7 +631,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         }
                     };
                     let mut format_pred = |pred: ty::Predicate<'tcx>| {
-                        match pred.ignore_qualifiers(tcx).skip_binder().kind() {
+                        match pred.ignore_qualifiers().skip_binder().kind() {
                             &ty::PredicateKind::Projection(pred) => {
                                 let pred = ty::Binder::bind(pred);
                                 // `<Foo as Iterator>::Item = String`.
@@ -959,7 +959,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // implementing a trait would be legal but is rejected
                 // here).
                 unsatisfied_predicates.iter().all(|(p, _)| {
-                    match p.ignore_qualifiers(self.tcx).skip_binder().kind() {
+                    match p.ignore_qualifiers().skip_binder().kind() {
                         // Hide traits if they are present in predicates as they can be fixed without
                         // having to implement them.
                         ty::PredicateKind::Trait(t, _) => t.def_id() == info.def_id,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 201288022ed..0cb0c7d0e30 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -2400,7 +2400,7 @@ fn bounds_from_generic_predicates<'tcx>(
     let mut projections = vec![];
     for (predicate, _) in predicates.predicates {
         debug!("predicate {:?}", predicate);
-        match predicate.ignore_qualifiers(tcx).skip_binder().kind() {
+        match predicate.ignore_qualifiers().skip_binder().kind() {
             ty::PredicateKind::Trait(trait_predicate, _) => {
                 let entry = types.entry(trait_predicate.self_ty()).or_default();
                 let def_id = trait_predicate.def_id();
@@ -3894,7 +3894,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .pending_obligations()
             .into_iter()
             .filter_map(move |obligation| {
-                match obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind() {
+                match obligation.predicate.ignore_qualifiers().skip_binder().kind() {
                     ty::PredicateKind::ForAll(_) => {
                         bug!("unexpected predicate: {:?}", obligation.predicate)
                     }
@@ -4250,7 +4250,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
 
             if let ty::PredicateKind::Trait(predicate, _) =
-                error.obligation.predicate.ignore_qualifiers(self.tcx).skip_binder().kind()
+                error.obligation.predicate.ignore_qualifiers().skip_binder().kind()
             {
                 // Collect the argument position for all arguments that could have caused this
                 // `FulfillmentError`.
@@ -4298,12 +4298,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             if let hir::ExprKind::Path(qpath) = &path.kind {
                 if let hir::QPath::Resolved(_, path) = &qpath {
                     for error in errors {
-                        if let ty::PredicateKind::Trait(predicate, _) = error
-                            .obligation
-                            .predicate
-                            .ignore_qualifiers(self.tcx)
-                            .skip_binder()
-                            .kind()
+                        if let ty::PredicateKind::Trait(predicate, _) =
+                            error.obligation.predicate.ignore_qualifiers().skip_binder().kind()
                         {
                             // If any of the type arguments in this path segment caused the
                             // `FullfillmentError`, point at its span (#61860).
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 71187244601..221e5f72dc9 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -194,7 +194,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
         param_env: ty::ParamEnv<'tcx>,
     ) -> RegionCtxt<'a, 'tcx> {
         let region_scope_tree = fcx.tcx.region_scope_tree(subject);
-        let outlives_environment = OutlivesEnvironment::new(fcx.tcx, param_env);
+        let outlives_environment = OutlivesEnvironment::new(param_env);
         RegionCtxt {
             fcx,
             region_scope_tree,
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index d40abf1f54e..8c6161a6264 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -292,7 +292,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
                     }
 
                     // Finally, resolve all regions.
-                    let outlives_env = OutlivesEnvironment::new(tcx, param_env);
+                    let outlives_env = OutlivesEnvironment::new(param_env);
                     infcx.resolve_regions_and_report_errors(
                         impl_did.to_def_id(),
                         &outlives_env,
@@ -549,7 +549,7 @@ pub fn coerce_unsized_info(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUnsizedI
         }
 
         // Finally, resolve all regions.
-        let outlives_env = OutlivesEnvironment::new(tcx, param_env);
+        let outlives_env = OutlivesEnvironment::new(param_env);
         infcx.resolve_regions_and_report_errors(impl_did, &outlives_env, RegionckMode::default());
 
         CoerceUnsizedInfo { custom_kind: kind }
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 23cf639f3c8..636c178d348 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -552,7 +552,7 @@ fn type_param_predicates(
     let extra_predicates = extend.into_iter().chain(
         icx.type_parameter_bounds_in_generics(ast_generics, param_id, ty, OnlySelfBounds(true))
             .into_iter()
-            .filter(|(predicate, _)| match predicate.ignore_qualifiers(tcx).skip_binder().kind() {
+            .filter(|(predicate, _)| match predicate.ignore_qualifiers().skip_binder().kind() {
                 ty::PredicateKind::Trait(data, _) => data.self_ty().is_param(index),
                 _ => false,
             }),
@@ -1004,8 +1004,7 @@ fn super_predicates_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> ty::GenericPredi
     // which will, in turn, reach indirect supertraits.
     for &(pred, span) in superbounds {
         debug!("superbound: {:?}", pred);
-        if let ty::PredicateKind::Trait(bound, _) = pred.ignore_qualifiers(tcx).skip_binder().kind()
-        {
+        if let ty::PredicateKind::Trait(bound, _) = pred.ignore_qualifiers().skip_binder().kind() {
             tcx.at(span).super_predicates_of(bound.def_id());
         }
     }
diff --git a/src/librustc_typeck/constrained_generic_params.rs b/src/librustc_typeck/constrained_generic_params.rs
index 8d469d0e429..85fe2dba250 100644
--- a/src/librustc_typeck/constrained_generic_params.rs
+++ b/src/librustc_typeck/constrained_generic_params.rs
@@ -183,7 +183,7 @@ pub fn setup_constraining_predicates<'tcx>(
             // Note that we don't have to care about binders here,
             // as the impl trait ref never contains any late-bound regions.
             if let ty::PredicateKind::Projection(projection) =
-                predicates[j].0.ignore_qualifiers(tcx).skip_binder().kind()
+                predicates[j].0.ignore_qualifiers().skip_binder().kind()
             {
                 // Special case: watch out for some kind of sneaky attempt
                 // to project out an associated type defined by this very
diff --git a/src/librustc_typeck/impl_wf_check/min_specialization.rs b/src/librustc_typeck/impl_wf_check/min_specialization.rs
index c1c8e73358b..50312a99175 100644
--- a/src/librustc_typeck/impl_wf_check/min_specialization.rs
+++ b/src/librustc_typeck/impl_wf_check/min_specialization.rs
@@ -163,7 +163,7 @@ fn get_impl_substs<'tcx>(
     let impl2_substs = translate_substs(infcx, param_env, impl1_def_id, impl1_substs, impl2_node);
 
     // Conservatively use an empty `ParamEnv`.
-    let outlives_env = OutlivesEnvironment::new(tcx, ty::ParamEnv::empty());
+    let outlives_env = OutlivesEnvironment::new(ty::ParamEnv::empty());
     infcx.resolve_regions_and_report_errors(impl1_def_id, &outlives_env, RegionckMode::default());
     let impl2_substs = match infcx.fully_resolve(&impl2_substs) {
         Ok(s) => s,
@@ -199,7 +199,7 @@ fn unconstrained_parent_impl_substs<'tcx>(
     // unconstrained parameters.
     for (predicate, _) in impl_generic_predicates.predicates.iter() {
         if let ty::PredicateKind::Projection(proj) =
-            predicate.ignore_qualifiers(tcx).skip_binder().kind()
+            predicate.ignore_qualifiers().skip_binder().kind()
         {
             let projection_ty = proj.projection_ty;
             let projected_ty = proj.ty;
@@ -361,7 +361,7 @@ fn check_predicates<'tcx>(
 
 fn check_specialization_on<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tcx>, span: Span) {
     debug!("can_specialize_on(predicate = {:?})", predicate);
-    match predicate.ignore_qualifiers(tcx).skip_binder().kind() {
+    match predicate.ignore_qualifiers().skip_binder().kind() {
         // Global predicates are either always true or always false, so we
         // are fine to specialize on.
         _ if predicate.is_global() => (),
@@ -394,7 +394,7 @@ fn trait_predicate_kind<'tcx>(
     tcx: TyCtxt<'tcx>,
     predicate: ty::Predicate<'tcx>,
 ) -> Option<TraitSpecializationKind> {
-    match predicate.ignore_qualifiers(tcx).skip_binder().kind() {
+    match predicate.ignore_qualifiers().skip_binder().kind() {
         ty::PredicateKind::ForAll(_) => bug!("unexpected predicate: {:?}", predicate),
         ty::PredicateKind::Trait(pred, hir::Constness::NotConst) => {
             Some(tcx.trait_def(pred.def_id()).specialization_kind)
diff --git a/src/librustc_typeck/outlives/explicit.rs b/src/librustc_typeck/outlives/explicit.rs
index d6551a5a387..ac2f8ae36c3 100644
--- a/src/librustc_typeck/outlives/explicit.rs
+++ b/src/librustc_typeck/outlives/explicit.rs
@@ -29,7 +29,7 @@ impl<'tcx> ExplicitPredicatesMap<'tcx> {
 
             // process predicates and convert to `RequiredPredicates` entry, see below
             for &(predicate, span) in predicates.predicates {
-                match predicate.ignore_qualifiers(tcx).skip_binder().kind() {
+                match predicate.ignore_qualifiers().skip_binder().kind() {
                     ty::PredicateKind::ForAll(_) => bug!("unepected predicate: {:?}", predicate),
 
                     ty::PredicateKind::TypeOutlives(OutlivesPredicate(ref ty, ref reg)) => {