Make overlapping_impls non-generic
This improves perf
This commit is contained in:
parent
6b3ede3f7b
commit
c4068c76a8
3 changed files with 34 additions and 47 deletions
|
@ -117,12 +117,11 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
|
||||||
// inherent impls without warning.
|
// inherent impls without warning.
|
||||||
SkipLeakCheck::Yes,
|
SkipLeakCheck::Yes,
|
||||||
overlap_mode,
|
overlap_mode,
|
||||||
|overlap| {
|
)
|
||||||
self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap);
|
.map_or(true, |overlap| {
|
||||||
false
|
self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id, overlap);
|
||||||
},
|
false
|
||||||
|| true,
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_item(&mut self, id: hir::ItemId) {
|
fn check_item(&mut self, id: hir::ItemId) {
|
||||||
|
|
|
@ -60,23 +60,17 @@ pub fn add_placeholder_note(err: &mut Diagnostic) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If there are types that satisfy both impls, invokes `on_overlap`
|
/// If there are types that satisfy both impls, returns `Some`
|
||||||
/// with a suitably-freshened `ImplHeader` with those types
|
/// with a suitably-freshened `ImplHeader` with those types
|
||||||
/// substituted. Otherwise, invokes `no_overlap`.
|
/// substituted. Otherwise, returns `None`.
|
||||||
#[instrument(skip(tcx, skip_leak_check, on_overlap, no_overlap), level = "debug")]
|
#[instrument(skip(tcx, skip_leak_check), level = "debug")]
|
||||||
pub fn overlapping_impls<F1, F2, R>(
|
pub fn overlapping_impls(
|
||||||
tcx: TyCtxt<'_>,
|
tcx: TyCtxt<'_>,
|
||||||
impl1_def_id: DefId,
|
impl1_def_id: DefId,
|
||||||
impl2_def_id: DefId,
|
impl2_def_id: DefId,
|
||||||
skip_leak_check: SkipLeakCheck,
|
skip_leak_check: SkipLeakCheck,
|
||||||
overlap_mode: OverlapMode,
|
overlap_mode: OverlapMode,
|
||||||
on_overlap: F1,
|
) -> Option<OverlapResult<'_>> {
|
||||||
no_overlap: F2,
|
|
||||||
) -> R
|
|
||||||
where
|
|
||||||
F1: FnOnce(OverlapResult<'_>) -> R,
|
|
||||||
F2: FnOnce() -> R,
|
|
||||||
{
|
|
||||||
// Before doing expensive operations like entering an inference context, do
|
// Before doing expensive operations like entering an inference context, do
|
||||||
// a quick check via fast_reject to tell if the impl headers could possibly
|
// a quick check via fast_reject to tell if the impl headers could possibly
|
||||||
// unify.
|
// unify.
|
||||||
|
@ -97,7 +91,7 @@ where
|
||||||
if !may_overlap {
|
if !may_overlap {
|
||||||
// Some types involved are definitely different, so the impls couldn't possibly overlap.
|
// Some types involved are definitely different, so the impls couldn't possibly overlap.
|
||||||
debug!("overlapping_impls: fast_reject early-exit");
|
debug!("overlapping_impls: fast_reject early-exit");
|
||||||
return no_overlap();
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx = tcx.infer_ctxt().build();
|
||||||
|
@ -105,7 +99,7 @@ where
|
||||||
let overlaps =
|
let overlaps =
|
||||||
overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).is_some();
|
overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).is_some();
|
||||||
if !overlaps {
|
if !overlaps {
|
||||||
return no_overlap();
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
// In the case where we detect an error, run the check again, but
|
// In the case where we detect an error, run the check again, but
|
||||||
|
@ -114,7 +108,7 @@ where
|
||||||
let infcx = tcx.infer_ctxt().build();
|
let infcx = tcx.infer_ctxt().build();
|
||||||
let selcx = &mut SelectionContext::intercrate(&infcx);
|
let selcx = &mut SelectionContext::intercrate(&infcx);
|
||||||
selcx.enable_tracking_intercrate_ambiguity_causes();
|
selcx.enable_tracking_intercrate_ambiguity_causes();
|
||||||
on_overlap(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap())
|
Some(overlap(selcx, skip_leak_check, impl1_def_id, impl2_def_id, overlap_mode).unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_fresh_ty_vars<'cx, 'tcx>(
|
fn with_fresh_ty_vars<'cx, 'tcx>(
|
||||||
|
|
|
@ -137,9 +137,8 @@ impl ChildrenExt<'_> for Children {
|
||||||
impl_def_id,
|
impl_def_id,
|
||||||
traits::SkipLeakCheck::default(),
|
traits::SkipLeakCheck::default(),
|
||||||
overlap_mode,
|
overlap_mode,
|
||||||
|_| true,
|
)
|
||||||
|| false,
|
.is_some();
|
||||||
);
|
|
||||||
|
|
||||||
let error = create_overlap_error(overlap);
|
let error = create_overlap_error(overlap);
|
||||||
|
|
||||||
|
@ -162,34 +161,29 @@ impl ChildrenExt<'_> for Children {
|
||||||
impl_def_id,
|
impl_def_id,
|
||||||
traits::SkipLeakCheck::Yes,
|
traits::SkipLeakCheck::Yes,
|
||||||
overlap_mode,
|
overlap_mode,
|
||||||
|overlap| {
|
)
|
||||||
if let Some(overlap_kind) =
|
.map_or(Ok((false, false)), |overlap| {
|
||||||
tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling)
|
if let Some(overlap_kind) =
|
||||||
{
|
tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling)
|
||||||
match overlap_kind {
|
{
|
||||||
ty::ImplOverlapKind::Permitted { marker: _ } => {}
|
match overlap_kind {
|
||||||
ty::ImplOverlapKind::Issue33140 => {
|
ty::ImplOverlapKind::Permitted { marker: _ } => {}
|
||||||
*last_lint_mut = Some(FutureCompatOverlapError {
|
ty::ImplOverlapKind::Issue33140 => {
|
||||||
error: create_overlap_error(overlap),
|
*last_lint_mut = Some(FutureCompatOverlapError {
|
||||||
kind: FutureCompatOverlapErrorKind::Issue33140,
|
error: create_overlap_error(overlap),
|
||||||
});
|
kind: FutureCompatOverlapErrorKind::Issue33140,
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok((false, false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let le = tcx.specializes((impl_def_id, possible_sibling));
|
return Ok((false, false));
|
||||||
let ge = tcx.specializes((possible_sibling, impl_def_id));
|
}
|
||||||
|
|
||||||
if le == ge {
|
let le = tcx.specializes((impl_def_id, possible_sibling));
|
||||||
report_overlap_error(overlap, last_lint_mut)
|
let ge = tcx.specializes((possible_sibling, impl_def_id));
|
||||||
} else {
|
|
||||||
Ok((le, ge))
|
if le == ge { report_overlap_error(overlap, last_lint_mut) } else { Ok((le, ge)) }
|
||||||
}
|
})?;
|
||||||
},
|
|
||||||
|| Ok((false, false)),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
if le && !ge {
|
if le && !ge {
|
||||||
debug!(
|
debug!(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue