Skip to content

Commit

Permalink
ty: remove {Existential,}Trait{Ref,Predicate}::input_types.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Apr 6, 2020
1 parent b7fdc7b commit 626abc7
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 107 deletions.
4 changes: 0 additions & 4 deletions src/librustc_middle/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Expand Down
16 changes: 0 additions & 16 deletions src/librustc_middle/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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>,
Expand Down
10 changes: 7 additions & 3 deletions src/librustc_trait_selection/traits/coherence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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());

Expand Down
14 changes: 5 additions & 9 deletions src/librustc_trait_selection/traits/object_safety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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()
Expand All @@ -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
Expand All @@ -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)
Expand Down
38 changes: 27 additions & 11 deletions src/librustc_trait_selection/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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 {
Expand Down Expand Up @@ -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!(),
}
},
)
}
Expand Down
24 changes: 12 additions & 12 deletions src/librustc_typeck/check/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) =>
Expand Down
Loading

0 comments on commit 626abc7

Please sign in to comment.