Skip to content

Commit 4c210af

Browse files
committed
make overlapping_impls call closures instead of returning
1 parent c48f46b commit 4c210af

File tree

4 files changed

+75
-50
lines changed

4 files changed

+75
-50
lines changed

src/librustc/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
#![feature(specialization)]
6666
#![feature(unboxed_closures)]
6767
#![feature(underscore_lifetimes)]
68+
#![feature(universal_impl_trait)]
6869
#![feature(trace_macros)]
6970
#![feature(catch_expr)]
7071
#![feature(test)]

src/librustc/traits/coherence.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,20 @@ pub struct OverlapResult<'tcx> {
4040
pub intercrate_ambiguity_causes: Vec<IntercrateAmbiguityCause>,
4141
}
4242

43-
/// If there are types that satisfy both impls, returns a suitably-freshened
44-
/// `ImplHeader` with those types substituted
45-
pub fn overlapping_impls<'cx, 'gcx, 'tcx>(infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
46-
impl1_def_id: DefId,
47-
impl2_def_id: DefId,
48-
intercrate_mode: IntercrateMode)
49-
-> Option<OverlapResult<'tcx>>
43+
/// If there are types that satisfy both impls, invokes `on_overlap`
44+
/// with a suitably-freshened `ImplHeader` with those types
45+
/// substituted. Otherwise, invokes `no_overlap`.
46+
pub fn overlapping_impls<F1, F2, R>(
47+
infcx: &InferCtxt<'_, '_, '_>,
48+
impl1_def_id: DefId,
49+
impl2_def_id: DefId,
50+
intercrate_mode: IntercrateMode,
51+
on_overlap: F1,
52+
no_overlap: F2,
53+
) -> R
54+
where
55+
F1: FnOnce(OverlapResult<'_>) -> R,
56+
F2: FnOnce() -> R,
5057
{
5158
debug!("impl_can_satisfy(\
5259
impl1_def_id={:?}, \
@@ -57,7 +64,11 @@ pub fn overlapping_impls<'cx, 'gcx, 'tcx>(infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
5764
intercrate_mode);
5865

5966
let selcx = &mut SelectionContext::intercrate(infcx, intercrate_mode);
60-
overlap(selcx, impl1_def_id, impl2_def_id)
67+
if let Some(r) = overlap(selcx, impl1_def_id, impl2_def_id) {
68+
on_overlap(r)
69+
} else {
70+
no_overlap()
71+
}
6172
}
6273

6374
fn with_fresh_ty_vars<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,

src/librustc/traits/specialize/specialization_graph.rs

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -134,26 +134,27 @@ impl<'a, 'gcx, 'tcx> Children {
134134

135135
let tcx = tcx.global_tcx();
136136
let (le, ge) = tcx.infer_ctxt().enter(|infcx| {
137-
let overlap = traits::overlapping_impls(&infcx,
138-
possible_sibling,
139-
impl_def_id,
140-
traits::IntercrateMode::Issue43355);
141-
if let Some(overlap) = overlap {
142-
if tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) {
143-
return Ok((false, false));
144-
}
145-
146-
let le = tcx.specializes((impl_def_id, possible_sibling));
147-
let ge = tcx.specializes((possible_sibling, impl_def_id));
148-
149-
if le == ge {
150-
Err(overlap_error(overlap))
151-
} else {
152-
Ok((le, ge))
153-
}
154-
} else {
155-
Ok((false, false))
156-
}
137+
traits::overlapping_impls(
138+
&infcx,
139+
possible_sibling,
140+
impl_def_id,
141+
traits::IntercrateMode::Issue43355,
142+
|overlap| {
143+
if tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) {
144+
return Ok((false, false));
145+
}
146+
147+
let le = tcx.specializes((impl_def_id, possible_sibling));
148+
let ge = tcx.specializes((possible_sibling, impl_def_id));
149+
150+
if le == ge {
151+
Err(overlap_error(overlap))
152+
} else {
153+
Ok((le, ge))
154+
}
155+
},
156+
|| Ok((false, false)),
157+
)
157158
})?;
158159

159160
if le && !ge {
@@ -172,14 +173,14 @@ impl<'a, 'gcx, 'tcx> Children {
172173
} else {
173174
if !tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) {
174175
tcx.infer_ctxt().enter(|infcx| {
175-
if let Some(overlap) = traits::overlapping_impls(
176+
traits::overlapping_impls(
176177
&infcx,
177178
possible_sibling,
178179
impl_def_id,
179-
traits::IntercrateMode::Fixed)
180-
{
181-
last_lint = Some(overlap_error(overlap));
182-
}
180+
traits::IntercrateMode::Fixed,
181+
|overlap| last_lint = Some(overlap_error(overlap)),
182+
|| (),
183+
)
183184
});
184185
}
185186

src/librustc_typeck/coherence/inherent_impls_overlap.rs

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -83,27 +83,39 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
8383
for (i, &impl1_def_id) in impls.iter().enumerate() {
8484
for &impl2_def_id in &impls[(i + 1)..] {
8585
let used_to_be_allowed = self.tcx.infer_ctxt().enter(|infcx| {
86-
if let Some(overlap) =
87-
traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id,
88-
IntercrateMode::Issue43355)
89-
{
90-
self.check_for_common_items_in_impls(
91-
impl1_def_id, impl2_def_id, overlap, false);
92-
false
93-
} else {
94-
true
95-
}
86+
traits::overlapping_impls(
87+
&infcx,
88+
impl1_def_id,
89+
impl2_def_id,
90+
IntercrateMode::Issue43355,
91+
|overlap| {
92+
self.check_for_common_items_in_impls(
93+
impl1_def_id,
94+
impl2_def_id,
95+
overlap,
96+
false,
97+
);
98+
false
99+
},
100+
|| true,
101+
)
96102
});
97103

98104
if used_to_be_allowed {
99105
self.tcx.infer_ctxt().enter(|infcx| {
100-
if let Some(overlap) =
101-
traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id,
102-
IntercrateMode::Fixed)
103-
{
104-
self.check_for_common_items_in_impls(
105-
impl1_def_id, impl2_def_id, overlap, true);
106-
}
106+
traits::overlapping_impls(
107+
&infcx,
108+
impl1_def_id,
109+
impl2_def_id,
110+
IntercrateMode::Fixed,
111+
|overlap| self.check_for_common_items_in_impls(
112+
impl1_def_id,
113+
impl2_def_id,
114+
overlap,
115+
true,
116+
),
117+
|| (),
118+
);
107119
});
108120
}
109121
}

0 commit comments

Comments
 (0)