about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorJack Huey <jack.huey@umassmed.edu>2020-12-16 22:36:14 -0500
committerJack Huey <jack.huey@umassmed.edu>2020-12-19 04:26:35 -0500
commit5e7095850c3577666a6b8e628760dea7cccb46b7 (patch)
tree8cc08198b905aef30e493314e26d232be1b62e19 /compiler
parentaf3b1cb0b55ed28c0f4a500e42699603edf199e7 (diff)
downloadrust-5e7095850c3577666a6b8e628760dea7cccb46b7.tar.gz
rust-5e7095850c3577666a6b8e628760dea7cccb46b7.zip
More rebinds
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_infer/src/infer/combine.rs4
-rw-r--r--compiler/rustc_infer/src/infer/nll_relate/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/_match.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs5
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs16
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs34
-rw-r--r--compiler/rustc_trait_selection/src/traits/object_safety.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs35
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs8
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs6
-rw-r--r--compiler/rustc_typeck/src/bounds.rs10
-rw-r--r--compiler/rustc_typeck/src/check/callee.rs2
-rw-r--r--compiler/rustc_typeck/src/check/closure.rs42
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs5
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs7
-rw-r--r--compiler/rustc_typeck/src/check/generator_interior.rs3
-rw-r--r--compiler/rustc_typeck/src/check/intrinsic.rs36
-rw-r--r--compiler/rustc_typeck/src/collect.rs13
-rw-r--r--compiler/rustc_typeck/src/lib.rs20
-rw-r--r--compiler/rustc_typeck/src/outlives/mod.rs14
22 files changed, 142 insertions, 138 deletions
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index 6a1715ef818..7770f2bd911 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -551,7 +551,7 @@ impl TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
     where
         T: Relate<'tcx>,
     {
-        Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?))
+        Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
     }
 
     fn relate_item_substs(
@@ -833,7 +833,7 @@ impl TypeRelation<'tcx> for ConstInferUnifier<'_, 'tcx> {
     where
         T: Relate<'tcx>,
     {
-        Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?))
+        Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
     }
 
     fn tys(&mut self, t: Ty<'tcx>, _t: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
diff --git a/compiler/rustc_infer/src/infer/nll_relate/mod.rs b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
index 0b2847658f7..b9bd66e4b92 100644
--- a/compiler/rustc_infer/src/infer/nll_relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/nll_relate/mod.rs
@@ -1008,6 +1008,6 @@ where
         self.first_free_index.shift_in(1);
         let result = self.relate(a.skip_binder(), a.skip_binder())?;
         self.first_free_index.shift_out(1);
-        Ok(ty::Binder::bind(result))
+        Ok(a.rebind(result))
     }
 }
diff --git a/compiler/rustc_middle/src/ty/_match.rs b/compiler/rustc_middle/src/ty/_match.rs
index 27bccc0bcaf..a5962e3b3ba 100644
--- a/compiler/rustc_middle/src/ty/_match.rs
+++ b/compiler/rustc_middle/src/ty/_match.rs
@@ -118,6 +118,6 @@ impl TypeRelation<'tcx> for Match<'tcx> {
     where
         T: Relate<'tcx>,
     {
-        Ok(ty::Binder::bind(self.relate(a.skip_binder(), b.skip_binder())?))
+        Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
     }
 }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index adf02412b96..615972ae45c 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -299,6 +299,7 @@ pub struct ResolvedOpaqueTy<'tcx> {
 /// Here, we would store the type `T`, the span of the value `x`, the "scope-span" for
 /// the scope that contains `x`, the expr `T` evaluated from, and the span of `foo.await`.
 #[derive(TyEncodable, TyDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)]
+#[derive(TypeFoldable)]
 pub struct GeneratorInteriorTypeCause<'tcx> {
     /// Type of the captured binding.
     pub ty: Ty<'tcx>,
@@ -423,7 +424,7 @@ pub struct TypeckResults<'tcx> {
 
     /// Stores the type, expression, span and optional scope span of all types
     /// that are live across the yield of this generator (if a generator).
-    pub generator_interior_types: Vec<GeneratorInteriorTypeCause<'tcx>>,
+    pub generator_interior_types: ty::Binder<Vec<GeneratorInteriorTypeCause<'tcx>>>,
 
     /// We sometimes treat byte string literals (which are of type `&[u8; N]`)
     /// as `&[u8]`, depending on the pattern  in which they are used.
@@ -455,7 +456,7 @@ impl<'tcx> TypeckResults<'tcx> {
             concrete_opaque_types: Default::default(),
             closure_captures: Default::default(),
             closure_min_captures: Default::default(),
-            generator_interior_types: Default::default(),
+            generator_interior_types: ty::Binder::dummy(Default::default()),
             treat_byte_string_as_slice: Default::default(),
         }
     }
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index b0f02dee59b..98602d6a459 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1252,7 +1252,7 @@ impl<'tcx> Predicate<'tcx> {
         let pred = self.skip_binders();
         let new = pred.subst(tcx, substs);
         if new != pred {
-            trait_ref.rebind(new).potentially_quantified(tcx, PredicateKind::ForAll)
+            ty::Binder::bind(new).potentially_quantified(tcx, PredicateKind::ForAll)
         } else {
             self
         }
@@ -1282,6 +1282,10 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
         // Ok to skip binder since trait `DefId` does not care about regions.
         self.skip_binder().def_id()
     }
+
+    pub fn self_ty(self) -> ty::Binder<Ty<'tcx>> {
+        self.map_bound(|trait_ref| trait_ref.self_ty())
+    }
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
@@ -1435,9 +1439,10 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
 
 impl<'tcx> Predicate<'tcx> {
     pub fn to_opt_poly_trait_ref(self) -> Option<ConstnessAnd<PolyTraitRef<'tcx>>> {
-        match self.skip_binders() {
+        let predicate = self.bound_atom();
+        match predicate.skip_binder() {
             PredicateAtom::Trait(t, constness) => {
-                Some(ConstnessAnd { constness, value: ty::Binder::bind(t.trait_ref) })
+                Some(ConstnessAnd { constness, value: predicate.rebind(t.trait_ref) })
             }
             PredicateAtom::Projection(..)
             | PredicateAtom::Subtype(..)
@@ -1453,8 +1458,9 @@ impl<'tcx> Predicate<'tcx> {
     }
 
     pub fn to_opt_type_outlives(self) -> Option<PolyTypeOutlivesPredicate<'tcx>> {
-        match self.skip_binders() {
-            PredicateAtom::TypeOutlives(data) => Some(ty::Binder::bind(data)),
+        let predicate = self.bound_atom();
+        match predicate.skip_binder() {
+            PredicateAtom::TypeOutlives(data) => Some(predicate.rebind(data)),
             PredicateAtom::Trait(..)
             | PredicateAtom::Projection(..)
             | PredicateAtom::Subtype(..)
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index 5c185dc4a9f..b4b71a48ce9 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -1151,9 +1151,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
     ) -> DiagnosticBuilder<'tcx> {
         crate fn build_fn_sig_string<'tcx>(
             tcx: TyCtxt<'tcx>,
-            trait_ref: ty::TraitRef<'tcx>,
+            trait_ref: ty::PolyTraitRef<'tcx>,
         ) -> String {
-            let inputs = trait_ref.substs.type_at(1);
+            let inputs = trait_ref.skip_binder().substs.type_at(1);
             let sig = if let ty::Tuple(inputs) = inputs.kind() {
                 tcx.mk_fn_sig(
                     inputs.iter().map(|k| k.expect_ty()),
@@ -1171,7 +1171,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                     abi::Abi::Rust,
                 )
             };
-            ty::Binder::bind(sig).to_string()
+            trait_ref.rebind(sig).to_string()
         }
 
         let argument_is_closure = expected_ref.skip_binder().substs.type_at(0).is_closure();
@@ -1183,17 +1183,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             if argument_is_closure { "closure" } else { "function" }
         );
 
-        let found_str = format!(
-            "expected signature of `{}`",
-            build_fn_sig_string(self.tcx, found.skip_binder())
-        );
+        let found_str = format!("expected signature of `{}`", build_fn_sig_string(self.tcx, found));
         err.span_label(span, found_str);
 
         let found_span = found_span.unwrap_or(span);
-        let expected_str = format!(
-            "found signature of `{}`",
-            build_fn_sig_string(self.tcx, expected_ref.skip_binder())
-        );
+        let expected_str =
+            format!("found signature of `{}`", build_fn_sig_string(self.tcx, expected_ref));
         err.span_label(found_span, expected_str);
 
         err
@@ -1422,7 +1417,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             // generator frame. Bound regions are preserved by
             // `erase_regions` and so we must also call
             // `erase_late_bound_regions`.
-            let ty_erased = self.tcx.erase_late_bound_regions(ty::Binder::bind(ty));
+            let ty_erased = self.tcx.erase_late_bound_regions(ty);
             let ty_erased = self.tcx.erase_regions(ty_erased);
             let eq = ty::TyS::same_type(ty_erased, target_ty_erased);
             debug!(
@@ -1440,7 +1435,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             interior_or_upvar_span = upvars.iter().find_map(|(upvar_id, upvar)| {
                 let upvar_ty = typeck_results.node_type(*upvar_id);
                 let upvar_ty = self.resolve_vars_if_possible(upvar_ty);
-                if ty_matches(&upvar_ty) {
+                if ty_matches(ty::Binder::dummy(upvar_ty)) {
                     Some(GeneratorInteriorOrUpvar::Upvar(upvar.span))
                 } else {
                     None
@@ -1448,10 +1443,13 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
             });
         };
 
-        if let Some(cause) = typeck_results
-            .generator_interior_types
-            .iter()
-            .find(|ty::GeneratorInteriorTypeCause { ty, .. }| ty_matches(ty))
+        // The generator interior types share the same binders
+        if let Some(cause) =
+            typeck_results.generator_interior_types.as_ref().skip_binder().iter().find(
+                |ty::GeneratorInteriorTypeCause { ty, .. }| {
+                    ty_matches(typeck_results.generator_interior_types.rebind(ty))
+                },
+            )
         {
             // Check to see if any awaited expressions have the target type.
             let from_awaited_ty = visitor
@@ -1464,7 +1462,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                         "maybe_note_obligation_cause_for_async_await: await_expr={:?}",
                         await_expr
                     );
-                    ty_matches(ty)
+                    ty_matches(ty::Binder::dummy(ty))
                 })
                 .map(|expr| expr.span);
             let ty::GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } = cause;
diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs
index 8b275db89f1..8b6e30f34fd 100644
--- a/compiler/rustc_trait_selection/src/traits/object_safety.rs
+++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs
@@ -418,11 +418,11 @@ fn virtual_call_violation_for_method<'tcx>(
     }
 
     for (i, &input_ty) in sig.skip_binder().inputs()[1..].iter().enumerate() {
-        if contains_illegal_self_type_reference(tcx, trait_def_id, input_ty) {
+        if contains_illegal_self_type_reference(tcx, trait_def_id, sig.rebind(input_ty)) {
             return Some(MethodViolationCode::ReferencesSelfInput(i));
         }
     }
-    if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output().skip_binder()) {
+    if contains_illegal_self_type_reference(tcx, trait_def_id, sig.output()) {
         return Some(MethodViolationCode::ReferencesSelfOutput);
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index df472e6ed7e..a11499e4320 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -951,7 +951,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
 
     // If we are resolving `<T as TraitRef<...>>::Item == Type`,
     // start out by selecting the predicate `T as TraitRef<...>`:
-    let poly_trait_ref = obligation_trait_ref.to_poly_trait_ref();
+    let poly_trait_ref = ty::Binder::dummy(*obligation_trait_ref);
     let trait_obligation = obligation.with(poly_trait_ref.to_poly_trait_predicate());
     let _ = selcx.infcx().commit_if_ok(|_| {
         let impl_source = match selcx.select(&trait_obligation) {
@@ -1247,7 +1247,9 @@ fn confirm_discriminant_kind_candidate<'cx, 'tcx>(
         ty: self_ty.discriminant_ty(tcx),
     };
 
-    confirm_param_env_candidate(selcx, obligation, ty::Binder::bind(predicate), false)
+    // We get here from `poly_project_and_unify_type` which replaces bound vars
+    // with placeholders, so dummy is okay here.
+    confirm_param_env_candidate(selcx, obligation, ty::Binder::dummy(predicate), false)
 }
 
 fn confirm_fn_pointer_candidate<'cx, 'tcx>(
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index ab09fcfd8cc..81de6dc71f4 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -259,10 +259,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     ) -> ImplSourceAutoImplData<PredicateObligation<'tcx>> {
         debug!(?obligation, ?trait_def_id, "confirm_auto_impl_candidate");
 
-        let types = obligation.predicate.map_bound(|inner| {
-            let self_ty = self.infcx.shallow_resolve(inner.self_ty());
-            self.constituent_types_for_ty(self_ty)
-        });
+        let self_ty = self.infcx.shallow_resolve(obligation.predicate.self_ty());
+        let types = self.constituent_types_for_ty(self_ty);
         self.vtable_auto_impl(obligation, trait_def_id, types)
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 74b6652981a..f1c86eab095 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1276,7 +1276,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         // FIXME(generic_associated_types): Compare the whole projections
         let data_poly_trait_ref = projection_ty.map_bound(|proj| proj.trait_ref(self.tcx()));
-        let obligation_poly_trait_ref = obligation_trait_ref.to_poly_trait_ref();
+        let obligation_poly_trait_ref = ty::Binder::dummy(*obligation_trait_ref);
         self.infcx
             .at(&obligation.cause, obligation.param_env)
             .sup(obligation_poly_trait_ref, data_poly_trait_ref)
@@ -1648,8 +1648,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     /// Bar<i32> where struct Bar<T> { x: T, y: u32 } -> [i32, u32]
     /// Zed<i32> where enum Zed { A(T), B(u32) } -> [i32, u32]
     /// ```
-    fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Vec<Ty<'tcx>> {
-        match *t.kind() {
+    fn constituent_types_for_ty(&self, t: ty::Binder<Ty<'tcx>>) -> ty::Binder<Vec<Ty<'tcx>>> {
+        match *t.skip_binder().kind() {
             ty::Uint(_)
             | ty::Int(_)
             | ty::Bool
@@ -1660,7 +1660,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             | ty::Error(_)
             | ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
             | ty::Never
-            | ty::Char => Vec::new(),
+            | ty::Char => ty::Binder::dummy(Vec::new()),
 
             ty::Placeholder(..)
             | ty::Dynamic(..)
@@ -1673,44 +1673,44 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             }
 
             ty::RawPtr(ty::TypeAndMut { ty: element_ty, .. }) | ty::Ref(_, element_ty, _) => {
-                vec![element_ty]
+                t.rebind(vec![element_ty])
             }
 
-            ty::Array(element_ty, _) | ty::Slice(element_ty) => vec![element_ty],
+            ty::Array(element_ty, _) | ty::Slice(element_ty) => t.rebind(vec![element_ty]),
 
             ty::Tuple(ref tys) => {
                 // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
-                tys.iter().map(|k| k.expect_ty()).collect()
+                t.rebind(tys.iter().map(|k| k.expect_ty()).collect())
             }
 
             ty::Closure(_, ref substs) => {
                 let ty = self.infcx.shallow_resolve(substs.as_closure().tupled_upvars_ty());
-                vec![ty]
+                t.rebind(vec![ty])
             }
 
             ty::Generator(_, ref substs, _) => {
                 let ty = self.infcx.shallow_resolve(substs.as_generator().tupled_upvars_ty());
                 let witness = substs.as_generator().witness();
-                vec![ty].into_iter().chain(iter::once(witness)).collect()
+                t.rebind(vec![ty].into_iter().chain(iter::once(witness)).collect())
             }
 
             ty::GeneratorWitness(types) => {
-                // This is sound because no regions in the witness can refer to
-                // the binder outside the witness. So we'll effectivly reuse
-                // the implicit binder around the witness.
-                types.skip_binder().to_vec()
+                debug_assert!(!types.has_escaping_bound_vars());
+                types.map_bound(|types| types.to_vec())
             }
 
             // For `PhantomData<T>`, we pass `T`.
-            ty::Adt(def, substs) if def.is_phantom_data() => substs.types().collect(),
+            ty::Adt(def, substs) if def.is_phantom_data() => t.rebind(substs.types().collect()),
 
-            ty::Adt(def, substs) => def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect(),
+            ty::Adt(def, substs) => {
+                t.rebind(def.all_fields().map(|f| f.ty(self.tcx(), substs)).collect())
+            }
 
             ty::Opaque(def_id, substs) => {
                 // We can resolve the `impl Trait` to its concrete type,
                 // which enforces a DAG between the functions requiring
                 // the auto trait bounds in question.
-                vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)]
+                t.rebind(vec![self.tcx().type_of(def_id).subst(self.tcx(), substs)])
             }
         }
     }
@@ -1738,10 +1738,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // 3. Re-bind the regions back to `for<'a> &'a i32 : Copy`
 
         types
+            .as_ref()
             .skip_binder() // binder moved -\
             .iter()
             .flat_map(|ty| {
-                let ty: ty::Binder<Ty<'tcx>> = ty::Binder::bind(ty); // <----/
+                let ty: ty::Binder<Ty<'tcx>> = types.rebind(ty); // <----/
 
                 self.infcx.commit_unconditionally(|_| {
                     let placeholder_ty = self.infcx.replace_bound_vars_with_placeholders(ty);
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index ab4a81c7d15..8888ea2c849 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -6,7 +6,7 @@ use smallvec::SmallVec;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::subst::{GenericArg, Subst, SubstsRef};
-use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, WithConstness};
+use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
 
 use super::{Normalized, Obligation, ObligationCause, PredicateObligation, SelectionContext};
 pub use rustc_infer::traits::util::*;
@@ -333,11 +333,12 @@ pub fn closure_trait_ref_and_return_type(
         TupleArgumentsFlag::No => sig.skip_binder().inputs()[0],
         TupleArgumentsFlag::Yes => tcx.intern_tup(sig.skip_binder().inputs()),
     };
+    debug_assert!(!self_ty.has_escaping_bound_vars());
     let trait_ref = ty::TraitRef {
         def_id: fn_trait_def_id,
         substs: tcx.mk_substs_trait(self_ty, &[arguments_tuple.into()]),
     };
-    ty::Binder::bind((trait_ref, sig.skip_binder().output()))
+    sig.map_bound(|sig| (trait_ref, sig.output()))
 }
 
 pub fn generator_trait_ref_and_outputs(
@@ -346,11 +347,12 @@ pub fn generator_trait_ref_and_outputs(
     self_ty: Ty<'tcx>,
     sig: ty::PolyGenSig<'tcx>,
 ) -> ty::Binder<(ty::TraitRef<'tcx>, Ty<'tcx>, Ty<'tcx>)> {
+    debug_assert!(!self_ty.has_escaping_bound_vars());
     let trait_ref = ty::TraitRef {
         def_id: fn_trait_def_id,
         substs: tcx.mk_substs_trait(self_ty, &[sig.skip_binder().resume_ty.into()]),
     };
-    ty::Binder::bind((trait_ref, sig.skip_binder().yield_ty, sig.skip_binder().return_ty))
+    sig.map_bound(|sig| (trait_ref, sig.yield_ty, sig.return_ty))
 }
 
 pub fn impl_item_is_final(tcx: TyCtxt<'_>, assoc_item: &ty::AssocItem) -> bool {
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 693cd236299..c470659e18a 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -837,9 +837,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     .instantiate_lang_item_trait_ref(
                         lang_item, span, hir_id, args, param_ty, bounds,
                     ),
-                hir::GenericBound::Outlives(ref l) => {
-                    bounds.region_bounds.push((self.ast_region_to_region(l, None), l.span))
-                }
+                hir::GenericBound::Outlives(ref l) => bounds
+                    .region_bounds
+                    .push((ty::Binder::bind(self.ast_region_to_region(l, None)), l.span)),
             }
         }
     }
diff --git a/compiler/rustc_typeck/src/bounds.rs b/compiler/rustc_typeck/src/bounds.rs
index 497754f20e4..7ba90ad8819 100644
--- a/compiler/rustc_typeck/src/bounds.rs
+++ b/compiler/rustc_typeck/src/bounds.rs
@@ -26,7 +26,7 @@ pub struct Bounds<'tcx> {
     /// A list of region bounds on the (implicit) self type. So if you
     /// had `T: 'a + 'b` this might would be a list `['a, 'b]` (but
     /// the `T` is not explicitly included).
-    pub region_bounds: Vec<(ty::Region<'tcx>, Span)>,
+    pub region_bounds: Vec<(ty::Binder<ty::Region<'tcx>>, Span)>,
 
     /// A list of trait bounds. So if you had `T: Debug` this would be
     /// `T: Debug`. Note that the self-type is explicit here.
@@ -68,8 +68,12 @@ impl<'tcx> Bounds<'tcx> {
         sized_predicate
             .into_iter()
             .chain(self.region_bounds.iter().map(|&(region_bound, span)| {
-                let outlives = ty::OutlivesPredicate(param_ty, region_bound);
-                (ty::Binder::bind(outlives).to_predicate(tcx), span)
+                (
+                    region_bound
+                        .map_bound(|region_bound| ty::OutlivesPredicate(param_ty, region_bound))
+                        .to_predicate(tcx),
+                    span,
+                )
             }))
             .chain(self.trait_bounds.iter().map(|&(bound_trait_ref, span, constness)| {
                 let predicate = bound_trait_ref.with_constness(constness).to_predicate(tcx);
diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs
index ebfb401fcf3..22e287320d8 100644
--- a/compiler/rustc_typeck/src/check/callee.rs
+++ b/compiler/rustc_typeck/src/check/callee.rs
@@ -389,7 +389,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // In that case, we check each argument against "error" in order to
                 // set up all the node type bindings.
                 (
-                    ty::Binder::bind(self.tcx.mk_fn_sig(
+                    ty::Binder::dummy(self.tcx.mk_fn_sig(
                         self.err_args(arg_exprs.len()).into_iter(),
                         self.tcx.ty_error(),
                         false,
diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs
index 8082a230216..7470c1a76a9 100644
--- a/compiler/rustc_typeck/src/check/closure.rs
+++ b/compiler/rustc_typeck/src/check/closure.rs
@@ -24,7 +24,7 @@ use std::iter;
 struct ExpectedSig<'tcx> {
     /// Span that gave us this expectation, if we know that.
     cause_span: Option<Span>,
-    sig: ty::FnSig<'tcx>,
+    sig: ty::PolyFnSig<'tcx>,
 }
 
 struct ClosureSignatures<'tcx> {
@@ -174,7 +174,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             ty::Infer(ty::TyVar(vid)) => self.deduce_expectations_from_obligations(vid),
             ty::FnPtr(sig) => {
-                let expected_sig = ExpectedSig { cause_span: None, sig: sig.skip_binder() };
+                let expected_sig = ExpectedSig { cause_span: None, sig };
                 (Some(expected_sig), Some(ty::ClosureKind::Fn))
             }
             _ => (None, None),
@@ -274,13 +274,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let ret_param_ty = self.resolve_vars_if_possible(ret_param_ty);
         debug!("deduce_sig_from_projection: ret_param_ty={:?}", ret_param_ty);
 
-        let sig = self.tcx.mk_fn_sig(
+        let sig = projection.rebind(self.tcx.mk_fn_sig(
             input_tys.iter(),
             &ret_param_ty,
             false,
             hir::Unsafety::Normal,
             Abi::Rust,
-        );
+        ));
         debug!("deduce_sig_from_projection: sig={:?}", sig);
 
         Some(ExpectedSig { cause_span, sig })
@@ -374,9 +374,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Watch out for some surprises and just ignore the
         // expectation if things don't see to match up with what we
         // expect.
-        if expected_sig.sig.c_variadic != decl.c_variadic {
+        if expected_sig.sig.c_variadic() != decl.c_variadic {
             return self.sig_of_closure_no_expectation(expr_def_id, decl, body);
-        } else if expected_sig.sig.inputs_and_output.len() != decl.inputs.len() + 1 {
+        } else if expected_sig.sig.skip_binder().inputs_and_output.len() != decl.inputs.len() + 1 {
             return self.sig_of_closure_with_mismatched_number_of_arguments(
                 expr_def_id,
                 decl,
@@ -388,14 +388,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // Create a `PolyFnSig`. Note the oddity that late bound
         // regions appearing free in `expected_sig` are now bound up
         // in this binder we are creating.
-        assert!(!expected_sig.sig.has_vars_bound_above(ty::INNERMOST));
-        let bound_sig = ty::Binder::bind(self.tcx.mk_fn_sig(
-            expected_sig.sig.inputs().iter().cloned(),
-            expected_sig.sig.output(),
-            decl.c_variadic,
-            hir::Unsafety::Normal,
-            Abi::RustCall,
-        ));
+        assert!(!expected_sig.sig.skip_binder().has_vars_bound_above(ty::INNERMOST));
+        let bound_sig = expected_sig.sig.map_bound(|sig| {
+            self.tcx.mk_fn_sig(
+                sig.inputs().iter().cloned(),
+                sig.output(),
+                sig.c_variadic,
+                hir::Unsafety::Normal,
+                Abi::RustCall,
+            )
+        });
 
         // `deduce_expectations_from_expected_type` introduces
         // late-bound lifetimes defined elsewhere, which we now
@@ -428,6 +430,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let expr_map_node = hir.get_if_local(expr_def_id).unwrap();
         let expected_args: Vec<_> = expected_sig
             .sig
+            .skip_binder()
             .inputs()
             .iter()
             .map(|ty| ArgKind::from_expected_ty(ty, None))
@@ -500,7 +503,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let (supplied_ty, _) = self.infcx.replace_bound_vars_with_fresh_vars(
                     hir_ty.span,
                     LateBoundRegionConversionTime::FnCall,
-                    ty::Binder::bind(supplied_ty),
+                    supplied_sig.inputs().rebind(supplied_ty),
                 ); // recreated from (*) above
 
                 // Check that E' = S'.
@@ -619,12 +622,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         // where R is the return type we are expecting. This type `T`
         // will be our output.
         let output_ty = self.obligations_for_self_ty(ret_vid).find_map(|(_, obligation)| {
-            if let ty::PredicateAtom::Projection(proj_predicate) =
-                obligation.predicate.skip_binders()
-            {
+            let bound_predicate = obligation.predicate.bound_atom();
+            if let ty::PredicateAtom::Projection(proj_predicate) = bound_predicate.skip_binder() {
                 self.deduce_future_output_from_projection(
                     obligation.cause.span,
-                    ty::Binder::bind(proj_predicate),
+                    bound_predicate.rebind(proj_predicate),
                 )
             } else {
                 None
@@ -704,7 +706,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             astconv.ast_ty_to_ty(&output);
         }
 
-        let result = ty::Binder::bind(self.tcx.mk_fn_sig(
+        let result = ty::Binder::dummy(self.tcx.mk_fn_sig(
             supplied_arguments,
             self.tcx.ty_error(),
             decl.c_variadic,
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index 20090d37606..bb324d0d8bc 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -494,12 +494,11 @@ fn compare_self_type<'tcx>(
             ty::ImplContainer(_) => impl_trait_ref.self_ty(),
             ty::TraitContainer(_) => tcx.types.self_param,
         };
-        let self_arg_ty = tcx.fn_sig(method.def_id).input(0).skip_binder();
+        let self_arg_ty = tcx.fn_sig(method.def_id).input(0);
         let param_env = ty::ParamEnv::reveal_all();
 
         tcx.infer_ctxt().enter(|infcx| {
-            let self_arg_ty =
-                tcx.liberate_late_bound_regions(method.def_id, ty::Binder::bind(self_arg_ty));
+            let self_arg_ty = tcx.liberate_late_bound_regions(method.def_id, self_arg_ty);
             let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty).is_ok();
             match ExplicitSelf::determine(self_arg_ty, can_eq_self) {
                 ExplicitSelf::ByValue => "self".to_owned(),
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index e1a2f593b8d..41a403a010e 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -764,12 +764,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .pending_obligations()
             .into_iter()
             .filter_map(move |obligation| {
-                match obligation.predicate.skip_binders() {
+                let bound_predicate = obligation.predicate.bound_atom();
+                match bound_predicate.skip_binder() {
                     ty::PredicateAtom::Projection(data) => {
-                        Some((ty::Binder::bind(data).to_poly_trait_ref(self.tcx), obligation))
+                        Some((bound_predicate.rebind(data).to_poly_trait_ref(self.tcx), obligation))
                     }
                     ty::PredicateAtom::Trait(data, _) => {
-                        Some((ty::Binder::bind(data).to_poly_trait_ref(), obligation))
+                        Some((bound_predicate.rebind(data).to_poly_trait_ref(), obligation))
                     }
                     ty::PredicateAtom::Subtype(..) => None,
                     ty::PredicateAtom::RegionOutlives(..) => None,
diff --git a/compiler/rustc_typeck/src/check/generator_interior.rs b/compiler/rustc_typeck/src/check/generator_interior.rs
index 5bc40d617d0..54710e12a74 100644
--- a/compiler/rustc_typeck/src/check/generator_interior.rs
+++ b/compiler/rustc_typeck/src/check/generator_interior.rs
@@ -204,7 +204,8 @@ pub fn resolve_interior<'a, 'tcx>(
     let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind(type_list));
 
     // Store the generator types and spans into the typeck results for this generator.
-    visitor.fcx.inh.typeck_results.borrow_mut().generator_interior_types = type_causes;
+    visitor.fcx.inh.typeck_results.borrow_mut().generator_interior_types =
+        ty::Binder::bind(type_causes);
 
     debug!(
         "types in generator after region replacement {:?}, span = {:?}",
diff --git a/compiler/rustc_typeck/src/check/intrinsic.rs b/compiler/rustc_typeck/src/check/intrinsic.rs
index e2712a30339..dd629980ab4 100644
--- a/compiler/rustc_typeck/src/check/intrinsic.rs
+++ b/compiler/rustc_typeck/src/check/intrinsic.rs
@@ -12,7 +12,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::subst::Subst;
-use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::symbol::{kw, sym, Symbol};
 use rustc_target::spec::abi::Abi;
 
@@ -23,10 +23,7 @@ fn equate_intrinsic_type<'tcx>(
     it: &hir::ForeignItem<'_>,
     def_id: DefId,
     n_tps: usize,
-    abi: Abi,
-    safety: hir::Unsafety,
-    inputs: Vec<Ty<'tcx>>,
-    output: Ty<'tcx>,
+    sig: ty::PolyFnSig<'tcx>,
 ) {
     match it.kind {
         hir::ForeignItemKind::Fn(..) => {}
@@ -53,13 +50,7 @@ fn equate_intrinsic_type<'tcx>(
         return;
     }
 
-    let fty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig(
-        inputs.into_iter(),
-        output,
-        false,
-        safety,
-        abi,
-    )));
+    let fty = tcx.mk_fn_ptr(sig);
     let cause = ObligationCause::new(it.span, it.hir_id, ObligationCauseCode::IntrinsicType);
     require_same_types(tcx, &cause, tcx.mk_fn_ptr(tcx.fn_sig(def_id)), fty);
 }
@@ -380,7 +371,9 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
         };
         (n_tps, inputs, output, unsafety)
     };
-    equate_intrinsic_type(tcx, it, def_id, n_tps, Abi::RustIntrinsic, unsafety, inputs, output)
+    let sig = tcx.mk_fn_sig(inputs.into_iter(), output, false, unsafety, Abi::RustIntrinsic);
+    let sig = ty::Binder::bind(sig);
+    equate_intrinsic_type(tcx, it, def_id, n_tps, sig)
 }
 
 /// Type-check `extern "platform-intrinsic" { ... }` functions.
@@ -466,14 +459,13 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
         }
     };
 
-    equate_intrinsic_type(
-        tcx,
-        it,
-        def_id,
-        n_tps,
-        Abi::PlatformIntrinsic,
-        hir::Unsafety::Unsafe,
-        inputs,
+    let sig = tcx.mk_fn_sig(
+        inputs.into_iter(),
         output,
-    )
+        false,
+        hir::Unsafety::Unsafe,
+        Abi::PlatformIntrinsic,
+    );
+    let sig = ty::Binder::dummy(sig);
+    equate_intrinsic_type(tcx, it, def_id, n_tps, sig)
 }
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 3b49c73c7f2..543e39af669 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -1986,11 +1986,10 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericP
                         }
                         _ => bug!(),
                     };
-                    let pred = ty::Binder::dummy(ty::PredicateAtom::RegionOutlives(
-                        ty::OutlivesPredicate(r1, r2),
-                    ));
+                    let pred = ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(r1, r2))
+                        .to_predicate(icx.tcx);
 
-                    (pred.potentially_quantified(icx.tcx, ty::PredicateKind::ForAll), span)
+                    (pred, span)
                 }))
             }
 
@@ -2238,10 +2237,8 @@ fn predicates_from_bound<'tcx>(
         }
         hir::GenericBound::Outlives(ref lifetime) => {
             let region = astconv.ast_region_to_region(lifetime, None);
-            let pred = ty::Binder::dummy(ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(
-                param_ty, region,
-            )))
-            .potentially_quantified(astconv.tcx(), ty::PredicateKind::ForAll);
+            let pred = ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(param_ty, region))
+                .to_predicate(astconv.tcx());
             vec![(pred, lifetime.span)]
         }
     }
diff --git a/compiler/rustc_typeck/src/lib.rs b/compiler/rustc_typeck/src/lib.rs
index 929c88455f0..dde4a62ffbf 100644
--- a/compiler/rustc_typeck/src/lib.rs
+++ b/compiler/rustc_typeck/src/lib.rs
@@ -226,19 +226,21 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: LocalDefId) {
             let expected_return_type = if tcx.lang_items().termination().is_some() {
                 // we take the return type of the given main function, the real check is done
                 // in `check_fn`
-                actual.output().skip_binder()
+                actual.output()
             } else {
                 // standard () main return type
-                tcx.mk_unit()
+                ty::Binder::dummy(tcx.mk_unit())
             };
 
-            let se_ty = tcx.mk_fn_ptr(ty::Binder::bind(tcx.mk_fn_sig(
-                iter::empty(),
-                expected_return_type,
-                false,
-                hir::Unsafety::Normal,
-                Abi::Rust,
-            )));
+            let se_ty = tcx.mk_fn_ptr(expected_return_type.map_bound(|expected_return_type| {
+                tcx.mk_fn_sig(
+                    iter::empty(),
+                    expected_return_type,
+                    false,
+                    hir::Unsafety::Normal,
+                    Abi::Rust,
+                )
+            }));
 
             require_same_types(
                 tcx,
diff --git a/compiler/rustc_typeck/src/outlives/mod.rs b/compiler/rustc_typeck/src/outlives/mod.rs
index d7c084acf50..b1f79331d5f 100644
--- a/compiler/rustc_typeck/src/outlives/mod.rs
+++ b/compiler/rustc_typeck/src/outlives/mod.rs
@@ -3,7 +3,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::subst::GenericArgKind;
-use rustc_middle::ty::{self, CratePredicatesMap, TyCtxt};
+use rustc_middle::ty::{self, CratePredicatesMap, ToPredicate, TyCtxt};
 use rustc_span::symbol::sym;
 use rustc_span::Span;
 
@@ -89,17 +89,15 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> CratePredica
                 |(ty::OutlivesPredicate(kind1, region2), &span)| {
                     match kind1.unpack() {
                         GenericArgKind::Type(ty1) => Some((
-                            ty::Binder::dummy(ty::PredicateAtom::TypeOutlives(
-                                ty::OutlivesPredicate(ty1, region2),
-                            ))
-                            .potentially_quantified(tcx, ty::PredicateKind::ForAll),
+                            ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(ty1, region2))
+                                .to_predicate(tcx),
                             span,
                         )),
                         GenericArgKind::Lifetime(region1) => Some((
-                            ty::Binder::dummy(ty::PredicateAtom::RegionOutlives(
-                                ty::OutlivesPredicate(region1, region2),
+                            ty::PredicateAtom::RegionOutlives(ty::OutlivesPredicate(
+                                region1, region2,
                             ))
-                            .potentially_quantified(tcx, ty::PredicateKind::ForAll),
+                            .to_predicate(tcx),
                             span,
                         )),
                         GenericArgKind::Const(_) => {