1
Fork 0

Short circuit full corherence check when dealing with types with different reference mutability

This commit is contained in:
Ryan Levick 2021-02-12 14:04:09 +01:00
parent cdfc52fbd6
commit 8ea0973725
2 changed files with 15 additions and 5 deletions

View file

@ -1837,6 +1837,15 @@ impl<'tcx> TyS<'tcx> {
) )
} }
/// Get the mutability of the reference or `None` when not a reference
#[inline]
pub fn ref_mutability(&self) -> Option<hir::Mutability> {
match self.kind() {
Ref(_, _, mutability) => Some(*mutability),
_ => None,
}
}
#[inline] #[inline]
pub fn is_unsafe_ptr(&self) -> bool { pub fn is_unsafe_ptr(&self) -> bool {
matches!(self.kind(), RawPtr(_)) matches!(self.kind(), RawPtr(_))

View file

@ -75,18 +75,19 @@ where
let impl1_ref = tcx.impl_trait_ref(impl1_def_id); let impl1_ref = tcx.impl_trait_ref(impl1_def_id);
let impl2_ref = tcx.impl_trait_ref(impl2_def_id); let impl2_ref = tcx.impl_trait_ref(impl2_def_id);
// Check if any of the input types definitely mismatch. // Check if any of the input types definitely do not unify.
if impl1_ref if impl1_ref
.iter() .iter()
.flat_map(|tref| tref.substs.types()) .flat_map(|tref| tref.substs.types())
.zip(impl2_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))) .chain(iter::once((impl1_self, impl2_self)))
.any(|(ty1, ty2)| { .any(|(ty1, ty2)| {
let ty1 = fast_reject::simplify_type(tcx, ty1, false); let t1 = fast_reject::simplify_type(tcx, ty1, false);
let ty2 = fast_reject::simplify_type(tcx, ty2, false); let t2 = fast_reject::simplify_type(tcx, ty2, false);
if let (Some(ty1), Some(ty2)) = (ty1, ty2) { if let (Some(t1), Some(t2)) = (t1, t2) {
// Simplified successfully // Simplified successfully
ty1 != ty2 // Types cannot unify if they differ in their reference mutability or simplify to different types
ty1.ref_mutability() != ty2.ref_mutability() || t1 != t2
} else { } else {
// Types might unify // Types might unify
false false