Remove some unnecessary trait_ref
calls
This commit is contained in:
parent
9526c0c6e8
commit
79f6f11816
4 changed files with 35 additions and 20 deletions
|
@ -77,6 +77,12 @@ trait DefIdVisitor<'tcx> {
|
||||||
fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<Self::BreakTy> {
|
fn visit_trait(&mut self, trait_ref: TraitRef<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||||
self.skeleton().visit_trait(trait_ref)
|
self.skeleton().visit_trait(trait_ref)
|
||||||
}
|
}
|
||||||
|
fn visit_projection_ty(
|
||||||
|
&mut self,
|
||||||
|
projection: ty::ProjectionTy<'tcx>,
|
||||||
|
) -> ControlFlow<Self::BreakTy> {
|
||||||
|
self.skeleton().visit_projection_ty(projection)
|
||||||
|
}
|
||||||
fn visit_predicates(
|
fn visit_predicates(
|
||||||
&mut self,
|
&mut self,
|
||||||
predicates: ty::GenericPredicates<'tcx>,
|
predicates: ty::GenericPredicates<'tcx>,
|
||||||
|
@ -101,6 +107,20 @@ where
|
||||||
if self.def_id_visitor.shallow() { ControlFlow::CONTINUE } else { substs.visit_with(self) }
|
if self.def_id_visitor.shallow() { ControlFlow::CONTINUE } else { substs.visit_with(self) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn visit_projection_ty(
|
||||||
|
&mut self,
|
||||||
|
projection: ty::ProjectionTy<'tcx>,
|
||||||
|
) -> ControlFlow<V::BreakTy> {
|
||||||
|
let (trait_ref, assoc_substs) =
|
||||||
|
projection.trait_ref_and_own_substs(self.def_id_visitor.tcx());
|
||||||
|
self.visit_trait(trait_ref)?;
|
||||||
|
if self.def_id_visitor.shallow() {
|
||||||
|
ControlFlow::CONTINUE
|
||||||
|
} else {
|
||||||
|
assoc_substs.iter().try_for_each(|subst| subst.visit_with(self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<V::BreakTy> {
|
fn visit_predicate(&mut self, predicate: ty::Predicate<'tcx>) -> ControlFlow<V::BreakTy> {
|
||||||
match predicate.kind().skip_binder() {
|
match predicate.kind().skip_binder() {
|
||||||
ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref }, _) => {
|
ty::PredicateKind::Trait(ty::TraitPredicate { trait_ref }, _) => {
|
||||||
|
@ -108,7 +128,7 @@ where
|
||||||
}
|
}
|
||||||
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, ty }) => {
|
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, ty }) => {
|
||||||
ty.visit_with(self)?;
|
ty.visit_with(self)?;
|
||||||
self.visit_trait(projection_ty.trait_ref(self.def_id_visitor.tcx()))
|
self.visit_projection_ty(projection_ty)
|
||||||
}
|
}
|
||||||
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty, _region)) => {
|
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty, _region)) => {
|
||||||
ty.visit_with(self)
|
ty.visit_with(self)
|
||||||
|
@ -197,7 +217,7 @@ where
|
||||||
return ControlFlow::CONTINUE;
|
return ControlFlow::CONTINUE;
|
||||||
}
|
}
|
||||||
// This will also visit substs if necessary, so we don't need to recurse.
|
// This will also visit substs if necessary, so we don't need to recurse.
|
||||||
return self.visit_trait(proj.trait_ref(tcx));
|
return self.visit_projection_ty(proj);
|
||||||
}
|
}
|
||||||
ty::Dynamic(predicates, ..) => {
|
ty::Dynamic(predicates, ..) => {
|
||||||
// All traits in the list are considered the "primary" part of the type
|
// All traits in the list are considered the "primary" part of the type
|
||||||
|
@ -1204,10 +1224,9 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (poly_predicate, _) in bounds.projection_bounds {
|
for (poly_predicate, _) in bounds.projection_bounds {
|
||||||
let tcx = self.tcx;
|
|
||||||
if self.visit(poly_predicate.skip_binder().ty).is_break()
|
if self.visit(poly_predicate.skip_binder().ty).is_break()
|
||||||
|| self
|
|| self
|
||||||
.visit_trait(poly_predicate.skip_binder().projection_ty.trait_ref(tcx))
|
.visit_projection_ty(poly_predicate.skip_binder().projection_ty)
|
||||||
.is_break()
|
.is_break()
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -6,6 +6,7 @@ use rustc_errors::ErrorReported;
|
||||||
use rustc_infer::traits::{TraitEngine, TraitEngineExt as _, TraitObligation};
|
use rustc_infer::traits::{TraitEngine, TraitEngineExt as _, TraitObligation};
|
||||||
use rustc_middle::mir::interpret::ErrorHandled;
|
use rustc_middle::mir::interpret::ErrorHandled;
|
||||||
use rustc_middle::ty::error::ExpectedFound;
|
use rustc_middle::ty::error::ExpectedFound;
|
||||||
|
use rustc_middle::ty::subst::SubstsRef;
|
||||||
use rustc_middle::ty::ToPredicate;
|
use rustc_middle::ty::ToPredicate;
|
||||||
use rustc_middle::ty::{self, Binder, Const, Ty, TypeFoldable};
|
use rustc_middle::ty::{self, Binder, Const, Ty, TypeFoldable};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
@ -633,9 +634,9 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
||||||
// only reason we can fail to make progress on
|
// only reason we can fail to make progress on
|
||||||
// trait selection is because we don't have enough
|
// trait selection is because we don't have enough
|
||||||
// information about the types in the trait.
|
// information about the types in the trait.
|
||||||
*stalled_on = trait_ref_infer_vars(
|
*stalled_on = substs_infer_vars(
|
||||||
self.selcx,
|
self.selcx,
|
||||||
trait_obligation.predicate.map_bound(|pred| pred.trait_ref),
|
trait_obligation.predicate.map_bound(|pred| pred.trait_ref.substs),
|
||||||
);
|
);
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
|
@ -663,9 +664,9 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
||||||
match project::poly_project_and_unify_type(self.selcx, &project_obligation) {
|
match project::poly_project_and_unify_type(self.selcx, &project_obligation) {
|
||||||
Ok(Ok(Some(os))) => ProcessResult::Changed(mk_pending(os)),
|
Ok(Ok(Some(os))) => ProcessResult::Changed(mk_pending(os)),
|
||||||
Ok(Ok(None)) => {
|
Ok(Ok(None)) => {
|
||||||
*stalled_on = trait_ref_infer_vars(
|
*stalled_on = substs_infer_vars(
|
||||||
self.selcx,
|
self.selcx,
|
||||||
project_obligation.predicate.to_poly_trait_ref(tcx),
|
project_obligation.predicate.map_bound(|pred| pred.projection_ty.substs),
|
||||||
);
|
);
|
||||||
ProcessResult::Unchanged
|
ProcessResult::Unchanged
|
||||||
}
|
}
|
||||||
|
@ -678,16 +679,15 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the set of inference variables contained in a trait ref.
|
/// Returns the set of inference variables contained in `substs`.
|
||||||
fn trait_ref_infer_vars<'a, 'tcx>(
|
fn substs_infer_vars<'a, 'tcx>(
|
||||||
selcx: &mut SelectionContext<'a, 'tcx>,
|
selcx: &mut SelectionContext<'a, 'tcx>,
|
||||||
trait_ref: ty::PolyTraitRef<'tcx>,
|
substs: ty::Binder<SubstsRef<'tcx>>,
|
||||||
) -> Vec<TyOrConstInferVar<'tcx>> {
|
) -> Vec<TyOrConstInferVar<'tcx>> {
|
||||||
selcx
|
selcx
|
||||||
.infcx()
|
.infcx()
|
||||||
.resolve_vars_if_possible(trait_ref)
|
.resolve_vars_if_possible(substs)
|
||||||
.skip_binder()
|
.skip_binder() // ok because this check doesn't care about regions
|
||||||
.substs
|
|
||||||
.iter()
|
.iter()
|
||||||
// FIXME(eddyb) try using `skip_current_subtree` to skip everything that
|
// FIXME(eddyb) try using `skip_current_subtree` to skip everything that
|
||||||
// doesn't contain inference variables, not just the outermost level.
|
// doesn't contain inference variables, not just the outermost level.
|
||||||
|
|
|
@ -292,11 +292,7 @@ fn predicate_references_self(
|
||||||
//
|
//
|
||||||
// This is ALT2 in issue #56288, see that for discussion of the
|
// This is ALT2 in issue #56288, see that for discussion of the
|
||||||
// possible alternatives.
|
// possible alternatives.
|
||||||
if data.projection_ty.trait_ref(tcx).substs[1..].iter().any(has_self_ty) {
|
if data.projection_ty.substs[1..].iter().any(has_self_ty) { Some(sp) } else { None }
|
||||||
Some(sp)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ty::PredicateKind::WellFormed(..)
|
ty::PredicateKind::WellFormed(..)
|
||||||
| ty::PredicateKind::ObjectSafe(..)
|
| ty::PredicateKind::ObjectSafe(..)
|
||||||
|
|
|
@ -198,7 +198,7 @@ pub fn setup_constraining_predicates<'tcx>(
|
||||||
// `<<T as Bar>::Baz as Iterator>::Output = <U as Iterator>::Output`
|
// `<<T as Bar>::Baz as Iterator>::Output = <U as Iterator>::Output`
|
||||||
// Then the projection only applies if `T` is known, but it still
|
// Then the projection only applies if `T` is known, but it still
|
||||||
// does not determine `U`.
|
// does not determine `U`.
|
||||||
let inputs = parameters_for(&projection.projection_ty.trait_ref(tcx), true);
|
let inputs = parameters_for(&projection.projection_ty, true);
|
||||||
let relies_only_on_inputs = inputs.iter().all(|p| input_parameters.contains(&p));
|
let relies_only_on_inputs = inputs.iter().all(|p| input_parameters.contains(&p));
|
||||||
if !relies_only_on_inputs {
|
if !relies_only_on_inputs {
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue