Skip to content

Commit

Permalink
Auto merge of #80454 - JulianKnodt:ob_forest_op, r=matthewjasper
Browse files Browse the repository at this point in the history
Skip Ty w/o infer ty/const in trait select

Remove some allocations & also add `skip_current_subtree` to skip subtrees with no inferred items.

r? `@eddyb` since marked in the FIXME
  • Loading branch information
bors committed Feb 27, 2021
2 parents ec7f8d9 + 899f27d commit 94736c4
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 20 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type TypeWalkerStack<'tcx> = SmallVec<[GenericArg<'tcx>; 8]>;
pub struct TypeWalker<'tcx> {
stack: TypeWalkerStack<'tcx>,
last_subtree: usize,
visited: SsoHashSet<GenericArg<'tcx>>,
pub visited: SsoHashSet<GenericArg<'tcx>>,
}

/// An iterator for walking the type tree.
Expand Down
43 changes: 24 additions & 19 deletions compiler/rustc_trait_selection/src/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -499,10 +499,10 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
) {
Ok(()) => ProcessResult::Changed(vec![]),
Err(ErrorHandled::TooGeneric) => {
pending_obligation.stalled_on = substs
.iter()
.filter_map(TyOrConstInferVar::maybe_from_generic_arg)
.collect();
pending_obligation.stalled_on.clear();
pending_obligation.stalled_on.extend(
substs.iter().filter_map(TyOrConstInferVar::maybe_from_generic_arg),
);
ProcessResult::Unchanged
}
Err(e) => ProcessResult::Error(CodeSelectionError(ConstEvalFailure(e))),
Expand Down Expand Up @@ -544,13 +544,10 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
) {
Ok(val) => Ok(Const::from_value(self.selcx.tcx(), val, c.ty)),
Err(ErrorHandled::TooGeneric) => {
stalled_on.append(
&mut substs
stalled_on.extend(
substs
.iter()
.filter_map(|arg| {
TyOrConstInferVar::maybe_from_generic_arg(arg)
})
.collect(),
.filter_map(TyOrConstInferVar::maybe_from_generic_arg),
);
Err(ErrorHandled::TooGeneric)
}
Expand Down Expand Up @@ -634,10 +631,11 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
// only reason we can fail to make progress on
// trait selection is because we don't have enough
// information about the types in the trait.
*stalled_on = substs_infer_vars(
stalled_on.clear();
stalled_on.extend(substs_infer_vars(
self.selcx,
trait_obligation.predicate.map_bound(|pred| pred.trait_ref.substs),
);
));

debug!(
"process_predicate: pending obligation {:?} now stalled on {:?}",
Expand All @@ -664,10 +662,11 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
match project::poly_project_and_unify_type(self.selcx, &project_obligation) {
Ok(Ok(Some(os))) => ProcessResult::Changed(mk_pending(os)),
Ok(Ok(None)) => {
*stalled_on = substs_infer_vars(
stalled_on.clear();
stalled_on.extend(substs_infer_vars(
self.selcx,
project_obligation.predicate.map_bound(|pred| pred.projection_ty.substs),
);
));
ProcessResult::Unchanged
}
// Let the caller handle the recursion
Expand All @@ -683,18 +682,24 @@ impl<'a, 'b, 'tcx> FulfillProcessor<'a, 'b, 'tcx> {
fn substs_infer_vars<'a, 'tcx>(
selcx: &mut SelectionContext<'a, 'tcx>,
substs: ty::Binder<SubstsRef<'tcx>>,
) -> Vec<TyOrConstInferVar<'tcx>> {
) -> impl Iterator<Item = TyOrConstInferVar<'tcx>> {
selcx
.infcx()
.resolve_vars_if_possible(substs)
.skip_binder() // ok because this check doesn't care about regions
.iter()
// FIXME(eddyb) try using `skip_current_subtree` to skip everything that
// doesn't contain inference variables, not just the outermost level.
.filter(|arg| arg.has_infer_types_or_consts())
.flat_map(|arg| arg.walk())
.flat_map(|arg| {
let mut walker = arg.walk();
while let Some(c) = walker.next() {
if !c.has_infer_types_or_consts() {
walker.visited.remove(&c);
walker.skip_current_subtree();
}
}
walker.visited.into_iter()
})
.filter_map(TyOrConstInferVar::maybe_from_generic_arg)
.collect()
}

fn to_fulfillment_error<'tcx>(
Expand Down

0 comments on commit 94736c4

Please sign in to comment.