提交 bff7b513 编写于 作者: L lcnr

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: Nname <n.nethercote@gmail.com>
上级 a76277c6
......@@ -539,8 +539,16 @@ fn assemble_candidates_from_impls(
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 @@ fn rematch_impl(
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 @@ fn rematch_impl(
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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册