make overlapping_impls
call closures instead of returning
This commit is contained in:
parent
c48f46ba36
commit
4c210afb19
4 changed files with 73 additions and 48 deletions
|
@ -65,6 +65,7 @@
|
||||||
#![feature(specialization)]
|
#![feature(specialization)]
|
||||||
#![feature(unboxed_closures)]
|
#![feature(unboxed_closures)]
|
||||||
#![feature(underscore_lifetimes)]
|
#![feature(underscore_lifetimes)]
|
||||||
|
#![feature(universal_impl_trait)]
|
||||||
#![feature(trace_macros)]
|
#![feature(trace_macros)]
|
||||||
#![feature(catch_expr)]
|
#![feature(catch_expr)]
|
||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
|
|
|
@ -40,13 +40,20 @@ pub struct OverlapResult<'tcx> {
|
||||||
pub intercrate_ambiguity_causes: Vec<IntercrateAmbiguityCause>,
|
pub intercrate_ambiguity_causes: Vec<IntercrateAmbiguityCause>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If there are types that satisfy both impls, returns a suitably-freshened
|
/// If there are types that satisfy both impls, invokes `on_overlap`
|
||||||
/// `ImplHeader` with those types substituted
|
/// with a suitably-freshened `ImplHeader` with those types
|
||||||
pub fn overlapping_impls<'cx, 'gcx, 'tcx>(infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
|
/// substituted. Otherwise, invokes `no_overlap`.
|
||||||
impl1_def_id: DefId,
|
pub fn overlapping_impls<F1, F2, R>(
|
||||||
impl2_def_id: DefId,
|
infcx: &InferCtxt<'_, '_, '_>,
|
||||||
intercrate_mode: IntercrateMode)
|
impl1_def_id: DefId,
|
||||||
-> Option<OverlapResult<'tcx>>
|
impl2_def_id: DefId,
|
||||||
|
intercrate_mode: IntercrateMode,
|
||||||
|
on_overlap: F1,
|
||||||
|
no_overlap: F2,
|
||||||
|
) -> R
|
||||||
|
where
|
||||||
|
F1: FnOnce(OverlapResult<'_>) -> R,
|
||||||
|
F2: FnOnce() -> R,
|
||||||
{
|
{
|
||||||
debug!("impl_can_satisfy(\
|
debug!("impl_can_satisfy(\
|
||||||
impl1_def_id={:?}, \
|
impl1_def_id={:?}, \
|
||||||
|
@ -57,7 +64,11 @@ pub fn overlapping_impls<'cx, 'gcx, 'tcx>(infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
|
||||||
intercrate_mode);
|
intercrate_mode);
|
||||||
|
|
||||||
let selcx = &mut SelectionContext::intercrate(infcx, intercrate_mode);
|
let selcx = &mut SelectionContext::intercrate(infcx, intercrate_mode);
|
||||||
overlap(selcx, impl1_def_id, impl2_def_id)
|
if let Some(r) = overlap(selcx, impl1_def_id, impl2_def_id) {
|
||||||
|
on_overlap(r)
|
||||||
|
} else {
|
||||||
|
no_overlap()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_fresh_ty_vars<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
|
fn with_fresh_ty_vars<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
|
||||||
|
|
|
@ -134,26 +134,27 @@ impl<'a, 'gcx, 'tcx> Children {
|
||||||
|
|
||||||
let tcx = tcx.global_tcx();
|
let tcx = tcx.global_tcx();
|
||||||
let (le, ge) = tcx.infer_ctxt().enter(|infcx| {
|
let (le, ge) = tcx.infer_ctxt().enter(|infcx| {
|
||||||
let overlap = traits::overlapping_impls(&infcx,
|
traits::overlapping_impls(
|
||||||
possible_sibling,
|
&infcx,
|
||||||
impl_def_id,
|
possible_sibling,
|
||||||
traits::IntercrateMode::Issue43355);
|
impl_def_id,
|
||||||
if let Some(overlap) = overlap {
|
traits::IntercrateMode::Issue43355,
|
||||||
if tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) {
|
|overlap| {
|
||||||
return Ok((false, false));
|
if tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) {
|
||||||
}
|
return Ok((false, false));
|
||||||
|
}
|
||||||
|
|
||||||
let le = tcx.specializes((impl_def_id, possible_sibling));
|
let le = tcx.specializes((impl_def_id, possible_sibling));
|
||||||
let ge = tcx.specializes((possible_sibling, impl_def_id));
|
let ge = tcx.specializes((possible_sibling, impl_def_id));
|
||||||
|
|
||||||
if le == ge {
|
if le == ge {
|
||||||
Err(overlap_error(overlap))
|
Err(overlap_error(overlap))
|
||||||
} else {
|
} else {
|
||||||
Ok((le, ge))
|
Ok((le, ge))
|
||||||
}
|
}
|
||||||
} else {
|
},
|
||||||
Ok((false, false))
|
|| Ok((false, false)),
|
||||||
}
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if le && !ge {
|
if le && !ge {
|
||||||
|
@ -172,14 +173,14 @@ impl<'a, 'gcx, 'tcx> Children {
|
||||||
} else {
|
} else {
|
||||||
if !tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) {
|
if !tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) {
|
||||||
tcx.infer_ctxt().enter(|infcx| {
|
tcx.infer_ctxt().enter(|infcx| {
|
||||||
if let Some(overlap) = traits::overlapping_impls(
|
traits::overlapping_impls(
|
||||||
&infcx,
|
&infcx,
|
||||||
possible_sibling,
|
possible_sibling,
|
||||||
impl_def_id,
|
impl_def_id,
|
||||||
traits::IntercrateMode::Fixed)
|
traits::IntercrateMode::Fixed,
|
||||||
{
|
|overlap| last_lint = Some(overlap_error(overlap)),
|
||||||
last_lint = Some(overlap_error(overlap));
|
|| (),
|
||||||
}
|
)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -83,27 +83,39 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
|
||||||
for (i, &impl1_def_id) in impls.iter().enumerate() {
|
for (i, &impl1_def_id) in impls.iter().enumerate() {
|
||||||
for &impl2_def_id in &impls[(i + 1)..] {
|
for &impl2_def_id in &impls[(i + 1)..] {
|
||||||
let used_to_be_allowed = self.tcx.infer_ctxt().enter(|infcx| {
|
let used_to_be_allowed = self.tcx.infer_ctxt().enter(|infcx| {
|
||||||
if let Some(overlap) =
|
traits::overlapping_impls(
|
||||||
traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id,
|
&infcx,
|
||||||
IntercrateMode::Issue43355)
|
impl1_def_id,
|
||||||
{
|
impl2_def_id,
|
||||||
self.check_for_common_items_in_impls(
|
IntercrateMode::Issue43355,
|
||||||
impl1_def_id, impl2_def_id, overlap, false);
|
|overlap| {
|
||||||
false
|
self.check_for_common_items_in_impls(
|
||||||
} else {
|
impl1_def_id,
|
||||||
true
|
impl2_def_id,
|
||||||
}
|
overlap,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
false
|
||||||
|
},
|
||||||
|
|| true,
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
if used_to_be_allowed {
|
if used_to_be_allowed {
|
||||||
self.tcx.infer_ctxt().enter(|infcx| {
|
self.tcx.infer_ctxt().enter(|infcx| {
|
||||||
if let Some(overlap) =
|
traits::overlapping_impls(
|
||||||
traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id,
|
&infcx,
|
||||||
IntercrateMode::Fixed)
|
impl1_def_id,
|
||||||
{
|
impl2_def_id,
|
||||||
self.check_for_common_items_in_impls(
|
IntercrateMode::Fixed,
|
||||||
impl1_def_id, impl2_def_id, overlap, true);
|
|overlap| self.check_for_common_items_in_impls(
|
||||||
}
|
impl1_def_id,
|
||||||
|
impl2_def_id,
|
||||||
|
overlap,
|
||||||
|
true,
|
||||||
|
),
|
||||||
|
|| (),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue