Try fast_reject::simplify_type in coherence before doing full check
Co-authored-by: Jonas Schievink <jonasschievink@gmail.com> Co-authored-by: Ryan Levick <me@ryanlevick.com>
This commit is contained in:
parent
d6a28a97e6
commit
cdfc52fbd6
1 changed files with 31 additions and 1 deletions
|
@ -11,7 +11,7 @@ use crate::traits::{self, Normalized, Obligation, ObligationCause, SelectionCont
|
|||
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc_middle::ty::fold::TypeFoldable;
|
||||
use rustc_middle::ty::subst::Subst;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_middle::ty::{self, fast_reject, Ty, TyCtxt};
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::DUMMY_SP;
|
||||
use std::iter;
|
||||
|
@ -67,6 +67,36 @@ where
|
|||
impl2_def_id={:?})",
|
||||
impl1_def_id, impl2_def_id,
|
||||
);
|
||||
// Before doing expensive operations like entering an inference context, do
|
||||
// a quick check via fast_reject to tell if the impl headers could possibly
|
||||
// unify.
|
||||
let impl1_self = tcx.type_of(impl1_def_id);
|
||||
let impl2_self = tcx.type_of(impl2_def_id);
|
||||
let impl1_ref = tcx.impl_trait_ref(impl1_def_id);
|
||||
let impl2_ref = tcx.impl_trait_ref(impl2_def_id);
|
||||
|
||||
// Check if any of the input types definitely mismatch.
|
||||
if impl1_ref
|
||||
.iter()
|
||||
.flat_map(|tref| tref.substs.types())
|
||||
.zip(impl2_ref.iter().flat_map(|tref| tref.substs.types()))
|
||||
.chain(iter::once((impl1_self, impl2_self)))
|
||||
.any(|(ty1, ty2)| {
|
||||
let ty1 = fast_reject::simplify_type(tcx, ty1, false);
|
||||
let ty2 = fast_reject::simplify_type(tcx, ty2, false);
|
||||
if let (Some(ty1), Some(ty2)) = (ty1, ty2) {
|
||||
// Simplified successfully
|
||||
ty1 != ty2
|
||||
} else {
|
||||
// Types might unify
|
||||
false
|
||||
}
|
||||
})
|
||||
{
|
||||
// Some types involved are definitely different, so the impls couldn't possibly overlap.
|
||||
debug!("overlapping_impls: fast_reject early-exit");
|
||||
return no_overlap();
|
||||
}
|
||||
|
||||
let overlaps = tcx.infer_ctxt().enter(|infcx| {
|
||||
let selcx = &mut SelectionContext::intercrate(&infcx);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue