about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorJack Huey <31162821+jackh726@users.noreply.github.com>2022-05-10 22:28:50 -0400
committerJack Huey <31162821+jackh726@users.noreply.github.com>2022-05-14 10:16:49 -0400
commit91afd0263269c44d57fe127f4c20748b5747113b (patch)
tree2d3082011fd1fe4c5e4da1947588f482c5b1b607 /compiler
parent0247faed2980a858e04fa57f78d585c8b066948d (diff)
downloadrust-91afd0263269c44d57fe127f4c20748b5747113b.tar.gz
rust-91afd0263269c44d57fe127f4c20748b5747113b.zip
Add bound_explicit_item_bounds and bound_item_bounds
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs6
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types.rs8
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs10
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs24
-rw-r--r--compiler/rustc_middle/src/ty/util.rs14
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs51
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs2
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs6
-rw-r--r--compiler/rustc_typeck/src/check/closure.rs58
-rw-r--r--compiler/rustc_typeck/src/check/compare_method.rs13
11 files changed, 121 insertions, 77 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 2a5b7e936ca..02caae7a90a 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -1849,10 +1849,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             // Future::Output
             let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0];
 
-            let bounds = self.tcx.explicit_item_bounds(*def_id);
+            let bounds = self.tcx.bound_explicit_item_bounds(*def_id);
 
-            for (predicate, _) in bounds {
-                let predicate = EarlyBinder(*predicate).subst(self.tcx, substs);
+            for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
+                let predicate = predicate.subst(self.tcx, substs);
                 let output = predicate
                     .kind()
                     .map_bound(|kind| match kind {
diff --git a/compiler/rustc_infer/src/infer/opaque_types.rs b/compiler/rustc_infer/src/infer/opaque_types.rs
index 6b2c599864c..92c0ed84057 100644
--- a/compiler/rustc_infer/src/infer/opaque_types.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types.rs
@@ -9,7 +9,7 @@ use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::subst::{GenericArgKind, Subst};
 use rustc_middle::ty::{
-    self, EarlyBinder, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor,
+    self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor,
 };
 use rustc_span::Span;
 
@@ -561,11 +561,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
             obligations = self.at(&cause, param_env).eq(prev, hidden_ty)?.obligations;
         }
 
-        let item_bounds = tcx.explicit_item_bounds(def_id);
+        let item_bounds = tcx.bound_explicit_item_bounds(def_id);
 
-        for (predicate, _) in item_bounds {
+        for predicate in item_bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
             debug!(?predicate);
-            let predicate = EarlyBinder(*predicate).subst(tcx, substs);
+            let predicate = predicate.subst(tcx, substs);
 
             let predicate = predicate.fold_with(&mut BottomUpFolder {
                 tcx,
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index e680250e7b1..4c0bc2e4337 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -1,8 +1,6 @@
 use crate::mir::interpret::{AllocRange, ConstValue, GlobalAlloc, Pointer, Provenance, Scalar};
 use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
-use crate::ty::{
-    self, ConstInt, DefIdTree, EarlyBinder, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable,
-};
+use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable};
 use rustc_apfloat::ieee::{Double, Single};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sso::SsoHashSet;
@@ -776,14 +774,14 @@ pub trait PrettyPrinter<'tcx>:
 
         // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
         // by looking up the projections associated with the def_id.
-        let bounds = self.tcx().explicit_item_bounds(def_id);
+        let bounds = self.tcx().bound_explicit_item_bounds(def_id);
 
         let mut traits = BTreeMap::new();
         let mut fn_traits = BTreeMap::new();
         let mut is_sized = false;
 
-        for (predicate, _) in bounds {
-            let predicate = EarlyBinder(*predicate).subst(self.tcx(), substs);
+        for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
+            let predicate = predicate.subst(self.tcx(), substs);
             let bound_predicate = predicate.kind();
 
             match bound_predicate.skip_binder() {
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index ca8528b3350..a973a5c9b50 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1109,6 +1109,30 @@ impl<T> EarlyBinder<Option<T>> {
     }
 }
 
+impl<T, U> EarlyBinder<(T, U)> {
+    pub fn transpose_tuple2(self) -> (EarlyBinder<T>, EarlyBinder<U>) {
+        (EarlyBinder(self.0.0), EarlyBinder(self.0.1))
+    }
+}
+
+pub struct EarlyBinderIter<T> {
+    t: T,
+}
+
+impl<T: IntoIterator> EarlyBinder<T> {
+    pub fn transpose_iter(self) -> EarlyBinderIter<T::IntoIter> {
+        EarlyBinderIter { t: self.0.into_iter() }
+    }
+}
+
+impl<T: Iterator> Iterator for EarlyBinderIter<T> {
+    type Item = EarlyBinder<T::Item>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.t.next().map(|i| EarlyBinder(i))
+    }
+}
+
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
 #[derive(HashStable)]
 pub enum BoundVariableKind {
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index ed0f6a7ccd1..9c345c76d0e 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -604,6 +604,20 @@ impl<'tcx> TyCtxt<'tcx> {
     pub fn bound_impl_trait_ref(self, def_id: DefId) -> Option<EarlyBinder<ty::TraitRef<'tcx>>> {
         self.impl_trait_ref(def_id).map(|i| EarlyBinder(i))
     }
+
+    pub fn bound_explicit_item_bounds(
+        self,
+        def_id: DefId,
+    ) -> EarlyBinder<&'tcx [(ty::Predicate<'tcx>, rustc_span::Span)]> {
+        EarlyBinder(self.explicit_item_bounds(def_id))
+    }
+
+    pub fn bound_item_bounds(
+        self,
+        def_id: DefId,
+    ) -> EarlyBinder<&'tcx ty::List<ty::Predicate<'tcx>>> {
+        EarlyBinder(self.item_bounds(def_id))
+    }
 }
 
 struct OpaqueTypeExpander<'tcx> {
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 004091661fa..beaa56e1c1c 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1276,10 +1276,8 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
     // Check whether the self-type is itself a projection.
     // If so, extract what we know from the trait and try to come up with a good answer.
     let bounds = match *obligation.predicate.self_ty().kind() {
-        ty::Projection(ref data) => {
-            EarlyBinder(tcx.item_bounds(data.item_def_id)).subst(tcx, data.substs)
-        }
-        ty::Opaque(def_id, substs) => EarlyBinder(tcx.item_bounds(def_id)).subst(tcx, substs),
+        ty::Projection(ref data) => tcx.bound_item_bounds(data.item_def_id).subst(tcx, data.substs),
+        ty::Opaque(def_id, substs) => tcx.bound_item_bounds(def_id).subst(tcx, substs),
         ty::Infer(ty::TyVar(_)) => {
             // If the self-type is an inference variable, then it MAY wind up
             // being a projected type, so induce an ambiguity.
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index fe80d02595a..b9025c98fe7 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -174,7 +174,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 _ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty),
             };
 
-            let candidate_predicate = EarlyBinder(tcx.item_bounds(def_id)[idx]).subst(tcx, substs);
+            let candidate_predicate =
+                tcx.bound_item_bounds(def_id).map_bound(|i| i[idx]).subst(tcx, substs);
             let candidate = candidate_predicate
                 .to_opt_poly_trait_pred()
                 .expect("projection candidate is not a trait predicate")
@@ -500,21 +501,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             // This maybe belongs in wf, but that can't (doesn't) handle
             // higher-ranked things.
             // Prevent, e.g., `dyn Iterator<Item = str>`.
-            for bound in self.tcx().item_bounds(assoc_type) {
-                let subst_bound = if defs.count() == 0 {
-                    EarlyBinder(bound).subst(tcx, trait_predicate.trait_ref.substs)
-                } else {
-                    let mut substs = smallvec::SmallVec::with_capacity(defs.count());
-                    substs.extend(trait_predicate.trait_ref.substs.iter());
-                    let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
-                        smallvec::SmallVec::with_capacity(
-                            bound.kind().bound_vars().len() + defs.count(),
-                        );
-                    bound_vars.extend(bound.kind().bound_vars().into_iter());
-                    InternalSubsts::fill_single(
-                        &mut substs,
-                        defs,
-                        &mut |param, _| match param.kind {
+            for bound in self.tcx().bound_item_bounds(assoc_type).transpose_iter() {
+                let subst_bound =
+                    if defs.count() == 0 {
+                        bound.subst(tcx, trait_predicate.trait_ref.substs)
+                    } else {
+                        let mut substs = smallvec::SmallVec::with_capacity(defs.count());
+                        substs.extend(trait_predicate.trait_ref.substs.iter());
+                        let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
+                            smallvec::SmallVec::with_capacity(
+                                bound.0.kind().bound_vars().len() + defs.count(),
+                            );
+                        bound_vars.extend(bound.0.kind().bound_vars().into_iter());
+                        InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param
+                            .kind
+                        {
                             GenericParamDefKind::Type { .. } => {
                                 let kind = ty::BoundTyKind::Param(param.name);
                                 let bound_var = ty::BoundVariableKind::Ty(kind);
@@ -553,15 +554,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                 })
                                 .into()
                             }
-                        },
-                    );
-                    let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
-                    let assoc_ty_substs = tcx.intern_substs(&substs);
-
-                    let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
-                    let bound = EarlyBinder(bound.kind().skip_binder()).subst(tcx, assoc_ty_substs);
-                    tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars))
-                };
+                        });
+                        let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
+                        let assoc_ty_substs = tcx.intern_substs(&substs);
+
+                        let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
+                        let bound =
+                            EarlyBinder(bound.0.kind().skip_binder()).subst(tcx, assoc_ty_substs);
+                        tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars))
+                    };
                 let normalized_bound = normalize_with_depth_to(
                     self,
                     obligation.param_env,
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index ab617d16cc4..4f797b182c0 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -1341,7 +1341,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 );
             }
         };
-        let bounds = EarlyBinder(tcx.item_bounds(def_id)).subst(tcx, substs);
+        let bounds = tcx.bound_item_bounds(def_id).subst(tcx, substs);
 
         // The bounds returned by `item_bounds` may contain duplicates after
         // normalization, so try to deduplicate when possible to avoid
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 663a644a9e7..2ff32bdf978 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -2447,10 +2447,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                     true,
                     None,
                 );
-                self.normalize_ty(
-                    span,
-                    EarlyBinder(tcx.at(span).type_of(def_id)).subst(tcx, substs),
-                )
+                EarlyBinder(self.normalize_ty(span, tcx.at(span).type_of(def_id)))
+                    .subst(tcx, substs)
             }
             hir::TyKind::Array(ref ty, ref length) => {
                 let length = match length {
diff --git a/compiler/rustc_typeck/src/check/closure.rs b/compiler/rustc_typeck/src/check/closure.rs
index df10853bf50..c8fe0468736 100644
--- a/compiler/rustc_typeck/src/check/closure.rs
+++ b/compiler/rustc_typeck/src/check/closure.rs
@@ -12,7 +12,7 @@ use rustc_infer::infer::LateBoundRegionConversionTime;
 use rustc_infer::infer::{InferOk, InferResult};
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::subst::InternalSubsts;
-use rustc_middle::ty::{self, EarlyBinder, Ty};
+use rustc_middle::ty::{self, Ty};
 use rustc_span::source_map::Span;
 use rustc_span::DUMMY_SP;
 use rustc_target::spec::abi::Abi;
@@ -175,19 +175,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     ) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
         match *expected_ty.kind() {
             ty::Opaque(def_id, substs) => {
-                let bounds = self.tcx.explicit_item_bounds(def_id);
-                let sig = bounds.iter().find_map(|(pred, span)| match pred.kind().skip_binder() {
-                    ty::PredicateKind::Projection(proj_predicate) => self
-                        .deduce_sig_from_projection(
-                            Some(*span),
-                            pred.kind().rebind(EarlyBinder(proj_predicate).subst(self.tcx, substs)),
-                        ),
-                    _ => None,
-                });
+                let bounds = self.tcx.bound_explicit_item_bounds(def_id);
+                let sig = bounds
+                    .transpose_iter()
+                    .map(|e| e.map_bound(|e| *e).transpose_tuple2())
+                    .find_map(|(pred, span)| match pred.0.kind().skip_binder() {
+                        ty::PredicateKind::Projection(proj_predicate) => self
+                            .deduce_sig_from_projection(
+                                Some(span.0),
+                                pred.0.kind().rebind(
+                                    pred.map_bound(|_| proj_predicate).subst(self.tcx, substs),
+                                ),
+                            ),
+                        _ => None,
+                    });
 
                 let kind = bounds
-                    .iter()
-                    .filter_map(|(pred, _)| match pred.kind().skip_binder() {
+                    .transpose_iter()
+                    .map(|e| e.map_bound(|e| *e).transpose_tuple2())
+                    .filter_map(|(pred, _)| match pred.0.kind().skip_binder() {
                         ty::PredicateKind::Trait(tp) => {
                             self.tcx.fn_trait_kind_from_lang_item(tp.def_id())
                         }
@@ -668,7 +674,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             ),
         };
 
-        let item_bounds = self.tcx.explicit_item_bounds(def_id);
+        let item_bounds = self.tcx.bound_explicit_item_bounds(def_id);
 
         // Search for a pending obligation like
         //
@@ -676,17 +682,21 @@ 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 = item_bounds.iter().find_map(|&(predicate, span)| {
-            let bound_predicate = EarlyBinder(predicate).subst(self.tcx, substs).kind();
-            if let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder() {
-                self.deduce_future_output_from_projection(
-                    span,
-                    bound_predicate.rebind(proj_predicate),
-                )
-            } else {
-                None
-            }
-        });
+        let output_ty = item_bounds
+            .transpose_iter()
+            .map(|e| e.map_bound(|e| *e).transpose_tuple2())
+            .find_map(|(predicate, span)| {
+                let bound_predicate = predicate.subst(self.tcx, substs).kind();
+                if let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder()
+                {
+                    self.deduce_future_output_from_projection(
+                        span.0,
+                        bound_predicate.rebind(proj_predicate),
+                    )
+                } else {
+                    None
+                }
+            });
 
         debug!("deduce_future_output_from_obligations: output_ty={:?}", output_ty);
         output_ty
diff --git a/compiler/rustc_typeck/src/check/compare_method.rs b/compiler/rustc_typeck/src/check/compare_method.rs
index 06304d8d7e7..b857679520b 100644
--- a/compiler/rustc_typeck/src/check/compare_method.rs
+++ b/compiler/rustc_typeck/src/check/compare_method.rs
@@ -10,7 +10,7 @@ use rustc_infer::traits::util;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 use rustc_middle::ty::subst::{InternalSubsts, Subst};
 use rustc_middle::ty::util::ExplicitSelf;
-use rustc_middle::ty::{self, DefIdTree, EarlyBinder};
+use rustc_middle::ty::{self, DefIdTree};
 use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
 use rustc_span::Span;
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
@@ -1451,14 +1451,15 @@ pub fn check_type_bounds<'tcx>(
         };
 
         let obligations = tcx
-            .explicit_item_bounds(trait_ty.def_id)
-            .iter()
-            .map(|&(bound, span)| {
+            .bound_explicit_item_bounds(trait_ty.def_id)
+            .transpose_iter()
+            .map(|e| e.map_bound(|e| *e).transpose_tuple2())
+            .map(|(bound, span)| {
                 debug!(?bound);
-                let concrete_ty_bound = EarlyBinder(bound).subst(tcx, rebased_substs);
+                let concrete_ty_bound = bound.subst(tcx, rebased_substs);
                 debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);
 
-                traits::Obligation::new(mk_cause(span), param_env, concrete_ty_bound)
+                traits::Obligation::new(mk_cause(span.0), param_env, concrete_ty_bound)
             })
             .collect();
         debug!("check_type_bounds: item_bounds={:?}", obligations);