about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2020-03-23 06:04:03 +0200
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2020-04-06 21:55:51 +0300
commit626abc797704009e4683be5d95dbeb9417999c82 (patch)
tree1dc4ab5081c2d70333e44899bf260bdfa1d38fdf
parentb7fdc7b619622c1f0700e35e5cffd8c1ca5d4a6c (diff)
downloadrust-626abc797704009e4683be5d95dbeb9417999c82.tar.gz
rust-626abc797704009e4683be5d95dbeb9417999c82.zip
ty: remove `{Existential,}Trait{Ref,Predicate}::input_types`.
-rw-r--r--src/librustc_middle/ty/mod.rs4
-rw-r--r--src/librustc_middle/ty/sty.rs16
-rw-r--r--src/librustc_trait_selection/traits/coherence.rs10
-rw-r--r--src/librustc_trait_selection/traits/object_safety.rs14
-rw-r--r--src/librustc_trait_selection/traits/select.rs38
-rw-r--r--src/librustc_typeck/check/coercion.rs24
-rw-r--r--src/librustdoc/clean/mod.rs104
7 files changed, 103 insertions, 107 deletions
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 48bc90526af..1870856150f 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -1365,10 +1365,6 @@ impl<'tcx> TraitPredicate<'tcx> {
         self.trait_ref.def_id
     }
 
-    pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'a {
-        self.trait_ref.input_types()
-    }
-
     pub fn self_ty(&self) -> Ty<'tcx> {
         self.trait_ref.self_ty()
     }
diff --git a/src/librustc_middle/ty/sty.rs b/src/librustc_middle/ty/sty.rs
index acbfdbafa17..f0932788687 100644
--- a/src/librustc_middle/ty/sty.rs
+++ b/src/librustc_middle/ty/sty.rs
@@ -754,14 +754,6 @@ impl<'tcx> TraitRef<'tcx> {
         self.substs.type_at(0)
     }
 
-    pub fn input_types<'a>(&'a self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'a {
-        // Select only the "input types" from a trait-reference. For
-        // now this is all the types that appear in the
-        // trait-reference, but it should eventually exclude
-        // associated types.
-        self.substs.types()
-    }
-
     pub fn from_method(
         tcx: TyCtxt<'tcx>,
         trait_id: DefId,
@@ -805,14 +797,6 @@ pub struct ExistentialTraitRef<'tcx> {
 }
 
 impl<'tcx> ExistentialTraitRef<'tcx> {
-    pub fn input_types<'b>(&'b self) -> impl DoubleEndedIterator<Item = Ty<'tcx>> + 'b {
-        // Select only the "input types" from a trait-reference. For
-        // now this is all the types that appear in the
-        // trait-reference, but it should eventually exclude
-        // associated types.
-        self.substs.types()
-    }
-
     pub fn erase_self_ty(
         tcx: TyCtxt<'tcx>,
         trait_ref: ty::TraitRef<'tcx>,
diff --git a/src/librustc_trait_selection/traits/coherence.rs b/src/librustc_trait_selection/traits/coherence.rs
index 4a71585ec1c..f1311382c54 100644
--- a/src/librustc_trait_selection/traits/coherence.rs
+++ b/src/librustc_trait_selection/traits/coherence.rs
@@ -393,8 +393,11 @@ fn orphan_check_trait_ref<'tcx>(
     }
 
     let mut non_local_spans = vec![];
-    for (i, input_ty) in
-        trait_ref.input_types().flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate)).enumerate()
+    for (i, input_ty) in trait_ref
+        .substs
+        .types()
+        .flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate))
+        .enumerate()
     {
         debug!("orphan_check_trait_ref: check ty `{:?}`", input_ty);
         let non_local_tys = ty_is_non_local(tcx, input_ty, in_crate);
@@ -404,7 +407,8 @@ fn orphan_check_trait_ref<'tcx>(
         } else if let ty::Param(_) = input_ty.kind {
             debug!("orphan_check_trait_ref: uncovered ty: `{:?}`", input_ty);
             let local_type = trait_ref
-                .input_types()
+                .substs
+                .types()
                 .flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate))
                 .find(|ty| ty_is_non_local_constructor(ty, in_crate).is_none());
 
diff --git a/src/librustc_trait_selection/traits/object_safety.rs b/src/librustc_trait_selection/traits/object_safety.rs
index fc2e984e34d..d9a5b68dc1e 100644
--- a/src/librustc_trait_selection/traits/object_safety.rs
+++ b/src/librustc_trait_selection/traits/object_safety.rs
@@ -16,7 +16,7 @@ use crate::traits::{self, Obligation, ObligationCause};
 use rustc_errors::{Applicability, FatalError};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
-use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts, Subst};
+use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts, Subst};
 use rustc_middle::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness};
 use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY;
 use rustc_span::symbol::Symbol;
@@ -234,7 +234,7 @@ fn predicates_reference_self(
         tcx.predicates_of(trait_def_id)
     };
     let self_ty = tcx.types.self_param;
-    let has_self_ty = |t: Ty<'_>| t.walk().any(|arg| arg == self_ty.into());
+    let has_self_ty = |arg: &GenericArg<'_>| arg.walk().any(|arg| arg == self_ty.into());
     predicates
         .predicates
         .iter()
@@ -243,7 +243,7 @@ fn predicates_reference_self(
             match predicate {
                 ty::Predicate::Trait(ref data, _) => {
                     // In the case of a trait predicate, we can skip the "self" type.
-                    if data.skip_binder().input_types().skip(1).any(has_self_ty) {
+                    if data.skip_binder().trait_ref.substs[1..].iter().any(has_self_ty) {
                         Some(sp)
                     } else {
                         None
@@ -262,12 +262,8 @@ fn predicates_reference_self(
                     //
                     // This is ALT2 in issue #56288, see that for discussion of the
                     // possible alternatives.
-                    if data
-                        .skip_binder()
-                        .projection_ty
-                        .trait_ref(tcx)
-                        .input_types()
-                        .skip(1)
+                    if data.skip_binder().projection_ty.trait_ref(tcx).substs[1..]
+                        .iter()
                         .any(has_self_ty)
                     {
                         Some(sp)
diff --git a/src/librustc_trait_selection/traits/select.rs b/src/librustc_trait_selection/traits/select.rs
index ed547cac582..84c264f06db 100644
--- a/src/librustc_trait_selection/traits/select.rs
+++ b/src/librustc_trait_selection/traits/select.rs
@@ -652,7 +652,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         &mut self,
         stack: &TraitObligationStack<'o, 'tcx>,
     ) -> Result<EvaluationResult, OverflowError> {
-        // In intercrate mode, whenever any of the types are unbound,
+        // In intercrate mode, whenever any of the generics are unbound,
         // there can always be an impl. Even if there are no impls in
         // this crate, perhaps the type would be unified with
         // something from another crate that does provide an impl.
@@ -677,7 +677,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // terms of `Fn` etc, but we could probably make this more
         // precise still.
         let unbound_input_types =
-            stack.fresh_trait_ref.skip_binder().input_types().any(|ty| ty.is_fresh());
+            stack.fresh_trait_ref.skip_binder().substs.types().any(|ty| ty.is_fresh());
         // This check was an imperfect workaround for a bug in the old
         // intercrate mode; it should be removed when that goes away.
         if unbound_input_types && self.intercrate {
@@ -3262,15 +3262,31 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // substitution if we find that any of the input types, when
         // simplified, do not match.
 
-        obligation.predicate.skip_binder().input_types().zip(impl_trait_ref.input_types()).any(
-            |(obligation_ty, impl_ty)| {
-                let simplified_obligation_ty =
-                    fast_reject::simplify_type(self.tcx(), obligation_ty, true);
-                let simplified_impl_ty = fast_reject::simplify_type(self.tcx(), impl_ty, false);
-
-                simplified_obligation_ty.is_some()
-                    && simplified_impl_ty.is_some()
-                    && simplified_obligation_ty != simplified_impl_ty
+        obligation.predicate.skip_binder().trait_ref.substs.iter().zip(impl_trait_ref.substs).any(
+            |(obligation_arg, impl_arg)| {
+                match (obligation_arg.unpack(), impl_arg.unpack()) {
+                    (GenericArgKind::Type(obligation_ty), GenericArgKind::Type(impl_ty)) => {
+                        let simplified_obligation_ty =
+                            fast_reject::simplify_type(self.tcx(), obligation_ty, true);
+                        let simplified_impl_ty =
+                            fast_reject::simplify_type(self.tcx(), impl_ty, false);
+
+                        simplified_obligation_ty.is_some()
+                            && simplified_impl_ty.is_some()
+                            && simplified_obligation_ty != simplified_impl_ty
+                    }
+                    (GenericArgKind::Lifetime(_), GenericArgKind::Lifetime(_)) => {
+                        // Lifetimes can never cause a rejection.
+                        false
+                    }
+                    (GenericArgKind::Const(_), GenericArgKind::Const(_)) => {
+                        // Conservatively ignore consts (i.e. assume they might
+                        // unify later) until we have `fast_reject` support for
+                        // them (if we'll ever need it, even).
+                        false
+                    }
+                    _ => unreachable!(),
+                }
             },
         )
     }
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 5a97a2af120..ff3493eb6de 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -563,30 +563,30 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         while !queue.is_empty() {
             let obligation = queue.remove(0);
             debug!("coerce_unsized resolve step: {:?}", obligation);
-            let trait_ref = match obligation.predicate {
-                ty::Predicate::Trait(ref tr, _) if traits.contains(&tr.def_id()) => {
-                    if unsize_did == tr.def_id() {
-                        let sty = &tr.skip_binder().input_types().nth(1).unwrap().kind;
-                        if let ty::Tuple(..) = sty {
+            let trait_pred = match obligation.predicate {
+                ty::Predicate::Trait(trait_pred, _) if traits.contains(&trait_pred.def_id()) => {
+                    if unsize_did == trait_pred.def_id() {
+                        let unsize_ty = trait_pred.skip_binder().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;
                         }
                     }
-                    *tr
+                    trait_pred
                 }
                 _ => {
                     coercion.obligations.push(obligation);
                     continue;
                 }
             };
-            match selcx.select(&obligation.with(trait_ref)) {
+            match selcx.select(&obligation.with(trait_pred)) {
                 // Uncertain or unimplemented.
                 Ok(None) => {
-                    if trait_ref.def_id() == unsize_did {
-                        let trait_ref = self.resolve_vars_if_possible(&trait_ref);
-                        let self_ty = trait_ref.skip_binder().self_ty();
-                        let unsize_ty = trait_ref.skip_binder().input_types().nth(1).unwrap();
-                        debug!("coerce_unsized: ambiguous unsize case for {:?}", trait_ref);
+                    if trait_pred.def_id() == unsize_did {
+                        let trait_pred = self.resolve_vars_if_possible(&trait_pred);
+                        let self_ty = trait_pred.skip_binder().self_ty();
+                        let unsize_ty = trait_pred.skip_binder().trait_ref.substs[1].expect_ty();
+                        debug!("coerce_unsized: ambiguous unsize case for {:?}", trait_pred);
                         match (&self_ty.kind, &unsize_ty.kind) {
                             (ty::Infer(ty::TyVar(v)), ty::Dynamic(..))
                                 if self.type_var_is_sized(*v) =>
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index f4111483902..5c35dc55132 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -84,15 +84,6 @@ impl<T: Clean<U>, U> Clean<Option<U>> for Option<T> {
     }
 }
 
-impl<T, U> Clean<U> for ty::Binder<T>
-where
-    T: Clean<U>,
-{
-    fn clean(&self, cx: &DocContext<'_>) -> U {
-        self.skip_binder().clean(cx)
-    }
-}
-
 impl Clean<ExternalCrate> for CrateNum {
     fn clean(&self, cx: &DocContext<'_>) -> ExternalCrate {
         let root = DefId { krate: *self, index: CRATE_DEF_INDEX };
@@ -305,59 +296,66 @@ impl Clean<GenericBound> for hir::GenericBound<'_> {
     }
 }
 
-impl<'a, 'tcx> Clean<GenericBound> for (&'a ty::TraitRef<'tcx>, Vec<TypeBinding>) {
-    fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
-        let (trait_ref, ref bounds) = *self;
+impl Clean<Type> for (ty::TraitRef<'_>, &[TypeBinding]) {
+    fn clean(&self, cx: &DocContext<'_>) -> Type {
+        let (trait_ref, bounds) = *self;
         inline::record_extern_fqn(cx, trait_ref.def_id, TypeKind::Trait);
         let path = external_path(
             cx,
             cx.tcx.item_name(trait_ref.def_id),
             Some(trait_ref.def_id),
             true,
-            bounds.clone(),
+            bounds.to_vec(),
             trait_ref.substs,
         );
 
         debug!("ty::TraitRef\n  subst: {:?}\n", trait_ref.substs);
 
+        ResolvedPath { path, param_names: None, did: trait_ref.def_id, is_generic: false }
+    }
+}
+
+impl<'tcx> Clean<GenericBound> for ty::TraitRef<'tcx> {
+    fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
+        GenericBound::TraitBound(
+            PolyTrait { trait_: (*self, &[][..]).clean(cx), generic_params: vec![] },
+            hir::TraitBoundModifier::None,
+        )
+    }
+}
+
+impl Clean<GenericBound> for (ty::PolyTraitRef<'_>, &[TypeBinding]) {
+    fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
+        let (poly_trait_ref, bounds) = *self;
+        let poly_trait_ref = poly_trait_ref.lift_to_tcx(cx.tcx).unwrap();
+
         // collect any late bound regions
-        let mut late_bounds = vec![];
-        for ty_s in trait_ref.input_types().skip(1) {
-            if let ty::Tuple(ts) = ty_s.kind {
-                for &ty_s in ts {
-                    if let ty::Ref(ref reg, _, _) = ty_s.expect_ty().kind {
-                        if let &ty::RegionKind::ReLateBound(..) = *reg {
-                            debug!("  hit an ReLateBound {:?}", reg);
-                            if let Some(Lifetime(name)) = reg.clean(cx) {
-                                late_bounds.push(GenericParamDef {
-                                    name,
-                                    kind: GenericParamDefKind::Lifetime,
-                                });
-                            }
-                        }
-                    }
-                }
-            }
-        }
+        let late_bound_regions: Vec<_> = cx
+            .tcx
+            .collect_referenced_late_bound_regions(&poly_trait_ref)
+            .into_iter()
+            .filter_map(|br| match br {
+                ty::BrNamed(_, name) => Some(GenericParamDef {
+                    name: name.to_string(),
+                    kind: GenericParamDefKind::Lifetime,
+                }),
+                _ => None,
+            })
+            .collect();
 
         GenericBound::TraitBound(
             PolyTrait {
-                trait_: ResolvedPath {
-                    path,
-                    param_names: None,
-                    did: trait_ref.def_id,
-                    is_generic: false,
-                },
-                generic_params: late_bounds,
+                trait_: (*poly_trait_ref.skip_binder(), bounds).clean(cx),
+                generic_params: late_bound_regions,
             },
             hir::TraitBoundModifier::None,
         )
     }
 }
 
-impl<'tcx> Clean<GenericBound> for ty::TraitRef<'tcx> {
+impl<'tcx> Clean<GenericBound> for ty::PolyTraitRef<'tcx> {
     fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
-        (self, vec![]).clean(cx)
+        (*self, &[][..]).clean(cx)
     }
 }
 
@@ -495,16 +493,17 @@ impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
     }
 }
 
-impl<'a> Clean<WherePredicate> for ty::TraitPredicate<'a> {
+impl<'a> Clean<WherePredicate> for ty::PolyTraitPredicate<'a> {
     fn clean(&self, cx: &DocContext<'_>) -> WherePredicate {
+        let poly_trait_ref = self.map_bound(|pred| pred.trait_ref);
         WherePredicate::BoundPredicate {
-            ty: self.trait_ref.self_ty().clean(cx),
-            bounds: vec![self.trait_ref.clean(cx)],
+            ty: poly_trait_ref.self_ty().clean(cx),
+            bounds: vec![poly_trait_ref.clean(cx)],
         }
     }
 }
 
-impl<'tcx> Clean<WherePredicate> for ty::SubtypePredicate<'tcx> {
+impl<'tcx> Clean<WherePredicate> for ty::PolySubtypePredicate<'tcx> {
     fn clean(&self, _cx: &DocContext<'_>) -> WherePredicate {
         panic!(
             "subtype predicates are an internal rustc artifact \
@@ -514,10 +513,10 @@ impl<'tcx> Clean<WherePredicate> for ty::SubtypePredicate<'tcx> {
 }
 
 impl<'tcx> Clean<Option<WherePredicate>>
-    for ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
+    for ty::PolyOutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
 {
     fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
-        let ty::OutlivesPredicate(ref a, ref b) = *self;
+        let ty::OutlivesPredicate(a, b) = self.skip_binder();
 
         if let (ty::ReEmpty(_), ty::ReEmpty(_)) = (a, b) {
             return None;
@@ -530,9 +529,9 @@ impl<'tcx> Clean<Option<WherePredicate>>
     }
 }
 
-impl<'tcx> Clean<Option<WherePredicate>> for ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>> {
+impl<'tcx> Clean<Option<WherePredicate>> for ty::PolyOutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>> {
     fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
-        let ty::OutlivesPredicate(ref ty, ref lt) = *self;
+        let ty::OutlivesPredicate(ty, lt) = self.skip_binder();
 
         if let ty::ReEmpty(_) = lt {
             return None;
@@ -545,9 +544,10 @@ impl<'tcx> Clean<Option<WherePredicate>> for ty::OutlivesPredicate<Ty<'tcx>, ty:
     }
 }
 
-impl<'tcx> Clean<WherePredicate> for ty::ProjectionPredicate<'tcx> {
+impl<'tcx> Clean<WherePredicate> for ty::PolyProjectionPredicate<'tcx> {
     fn clean(&self, cx: &DocContext<'_>) -> WherePredicate {
-        WherePredicate::EqPredicate { lhs: self.projection_ty.clean(cx), rhs: self.ty.clean(cx) }
+        let ty::ProjectionPredicate { projection_ty, ty } = *self.skip_binder();
+        WherePredicate::EqPredicate { lhs: projection_ty.clean(cx), rhs: ty.clean(cx) }
     }
 }
 
@@ -1674,7 +1674,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                             }
                         }
 
-                        let bounds = bounds
+                        let bounds: Vec<_> = bounds
                             .predicates
                             .iter()
                             .filter_map(|pred| {
@@ -1703,7 +1703,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                             })
                             .collect();
 
-                        Some((trait_ref.skip_binder(), bounds).clean(cx))
+                        Some((trait_ref, &bounds[..]).clean(cx))
                     })
                     .collect::<Vec<_>>();
                 bounds.extend(regions);