move fast reject test out of SelectionContext::match_impl
.
`match_impl` has two call sites. For one of them (within `rematch_impl`) the fast reject test isn't necessary, because any rejection would represent a compiler bug. This commit moves the fast reject test to the other `match_impl` call site, in `assemble_candidates_from_impls`. This lets us move the fast reject test outside the `probe` call in that function. This avoids the taking of useless snapshots when the fast reject test succeeds, which gives a performance win when compiling the `bitmaps` and `nalgebra` crates. Co-authored-by: name <n.nethercote@gmail.com>
This commit is contained in:
parent
a76277c6c4
commit
bff7b5130d
@ -539,8 +539,16 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
obligation.predicate.def_id(),
|
||||
obligation.predicate.skip_binder().trait_ref.self_ty(),
|
||||
|impl_def_id| {
|
||||
// Before we create the substitutions and everything, first
|
||||
// consider a "quick reject". This avoids creating more types
|
||||
// and so forth that we need to.
|
||||
let impl_trait_ref = self.tcx().bound_impl_trait_ref(impl_def_id).unwrap();
|
||||
if self.fast_reject_trait_refs(obligation, &impl_trait_ref.0) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.infcx.probe(|_| {
|
||||
if let Ok(_substs) = self.match_impl(impl_def_id, obligation) {
|
||||
if let Ok(_substs) = self.match_impl(impl_def_id, impl_trait_ref, obligation) {
|
||||
candidates.vec.push(ImplCandidate(impl_def_id));
|
||||
}
|
||||
});
|
||||
|
@ -2043,7 +2043,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
impl_def_id: DefId,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
) -> Normalized<'tcx, SubstsRef<'tcx>> {
|
||||
match self.match_impl(impl_def_id, obligation) {
|
||||
let impl_trait_ref = self.tcx().bound_impl_trait_ref(impl_def_id).unwrap();
|
||||
match self.match_impl(impl_def_id, impl_trait_ref, obligation) {
|
||||
Ok(substs) => substs,
|
||||
Err(()) => {
|
||||
self.infcx.tcx.sess.delay_span_bug(
|
||||
@ -2070,17 +2071,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
fn match_impl(
|
||||
&mut self,
|
||||
impl_def_id: DefId,
|
||||
impl_trait_ref: EarlyBinder<ty::TraitRef<'tcx>>,
|
||||
obligation: &TraitObligation<'tcx>,
|
||||
) -> Result<Normalized<'tcx, SubstsRef<'tcx>>, ()> {
|
||||
let impl_trait_ref = self.tcx().bound_impl_trait_ref(impl_def_id).unwrap();
|
||||
|
||||
// Before we create the substitutions and everything, first
|
||||
// consider a "quick reject". This avoids creating more types
|
||||
// and so forth that we need to.
|
||||
if self.fast_reject_trait_refs(obligation, &impl_trait_ref.0) {
|
||||
return Err(());
|
||||
}
|
||||
|
||||
let placeholder_obligation =
|
||||
self.infcx().replace_bound_vars_with_placeholders(obligation.predicate);
|
||||
let placeholder_obligation_trait_ref = placeholder_obligation.trait_ref;
|
||||
|
Loading…
x
Reference in New Issue
Block a user