Skip to content

Commit 1ec962f

Browse files
committed
Do not pass OverlapMode down, just create a closure to properly set the filtering
1 parent d2d25a5 commit 1ec962f

File tree

1 file changed

+33
-16
lines changed

1 file changed

+33
-16
lines changed

compiler/rustc_trait_selection/src/traits/coherence.rs

+33-16
Original file line numberDiff line numberDiff line change
@@ -201,17 +201,17 @@ fn overlap_within_probe<'cx, 'tcx>(
201201

202202
match overlap_mode(tcx, impl1_def_id, impl2_def_id) {
203203
OverlapMode::Stable => {
204-
if stable_disjoint(selcx, param_env, &impl1_header, impl2_header, OverlapMode::Stable) {
204+
if stable_disjoint(selcx, param_env, &impl1_header, impl2_header) {
205205
return None;
206206
}
207207
}
208208
OverlapMode::Strict => {
209-
if stable_disjoint(selcx, param_env, &impl1_header, impl2_header, OverlapMode::Strict) {
209+
if strict_disjoint(selcx, param_env, &impl1_header, impl2_header) {
210210
return None;
211211
}
212212
}
213213
OverlapMode::WithNegative => {
214-
if stable_disjoint(selcx, param_env, &impl1_header, impl2_header, OverlapMode::Stable)
214+
if stable_disjoint(selcx, param_env, &impl1_header, impl2_header)
215215
|| explicit_disjoint(selcx, impl1_def_id, impl2_def_id)
216216
|| explicit_disjoint(selcx, impl2_def_id, impl1_def_id)
217217
{
@@ -244,7 +244,35 @@ fn stable_disjoint<'cx, 'tcx>(
244244
param_env: ty::ParamEnv<'tcx>,
245245
impl1_header: &ty::ImplHeader<'tcx>,
246246
impl2_header: ty::ImplHeader<'tcx>,
247-
overlap_mode: OverlapMode,
247+
) -> bool {
248+
let infcx = selcx.infcx();
249+
let tcx = infcx.tcx;
250+
251+
disjoint_with_filter(selcx, param_env, impl1_header, impl2_header, |selcx, o| {
252+
loose_check(selcx, o) || tcx.features().negative_impls && strict_check(selcx, o)
253+
})
254+
}
255+
256+
fn strict_disjoint<'cx, 'tcx>(
257+
selcx: &mut SelectionContext<'cx, 'tcx>,
258+
param_env: ty::ParamEnv<'tcx>,
259+
impl1_header: &ty::ImplHeader<'tcx>,
260+
impl2_header: ty::ImplHeader<'tcx>,
261+
) -> bool {
262+
disjoint_with_filter(selcx, param_env, impl1_header, impl2_header, |selcx, o| {
263+
strict_check(selcx, o)
264+
})
265+
}
266+
267+
fn disjoint_with_filter<'cx, 'tcx>(
268+
selcx: &mut SelectionContext<'cx, 'tcx>,
269+
param_env: ty::ParamEnv<'tcx>,
270+
impl1_header: &ty::ImplHeader<'tcx>,
271+
impl2_header: ty::ImplHeader<'tcx>,
272+
mut filter: impl FnMut(
273+
&mut SelectionContext<'cx, 'tcx>,
274+
&rustc_infer::traits::Obligation<'tcx, rustc_middle::ty::Predicate<'tcx>>,
275+
) -> bool,
248276
) -> bool {
249277
debug!("overlap: impl1_header={:?}", impl1_header);
250278
debug!("overlap: impl2_header={:?}", impl2_header);
@@ -285,7 +313,6 @@ fn stable_disjoint<'cx, 'tcx>(
285313
// hold we need to check if `&'?a str: !Error` holds, if doesn't hold there's overlap because
286314
// at some point an impl for `&'?a str: Error` could be added.
287315
let infcx = selcx.infcx();
288-
let tcx = infcx.tcx;
289316
let opt_failing_obligation = impl1_header
290317
.predicates
291318
.iter()
@@ -299,17 +326,7 @@ fn stable_disjoint<'cx, 'tcx>(
299326
predicate: p,
300327
})
301328
.chain(obligations)
302-
.find(|o| {
303-
// if both impl headers are set to strict coherence it means that this will be accepted
304-
// only if it's stated that T: !Trait. So only prove that the negated obligation holds.
305-
match overlap_mode {
306-
OverlapMode::Stable => {
307-
loose_check(selcx, o) || tcx.features().negative_impls && strict_check(selcx, o)
308-
}
309-
OverlapMode::Strict => strict_check(selcx, o),
310-
OverlapMode::WithNegative => loose_check(selcx, o),
311-
}
312-
});
329+
.find(|o| filter(selcx, o));
313330
// FIXME: the call to `selcx.predicate_may_hold_fatal` above should be ported
314331
// to the canonical trait query form, `infcx.predicate_may_hold`, once
315332
// the new system supports intercrate mode (which coherence needs).

0 commit comments

Comments
 (0)