Skip to content

Commit f3ebafa

Browse files
committed
Extract obligations_satisfiable fn
1 parent 89fdb62 commit f3ebafa

File tree

1 file changed

+44
-42
lines changed

1 file changed

+44
-42
lines changed

compiler/rustc_trait_selection/src/traits/coherence.rs

+44-42
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ use crate::traits::{
1717
use rustc_errors::Diagnostic;
1818
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
1919
use rustc_hir::CRATE_HIR_ID;
20+
use rustc_infer::infer::at::ToTrace;
2021
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
2122
use rustc_infer::traits::{util, TraitEngine};
2223
use rustc_middle::traits::specialization_graph::OverlapMode;
@@ -26,6 +27,7 @@ use rustc_middle::ty::subst::Subst;
2627
use rustc_middle::ty::{self, Ty, TyCtxt};
2728
use rustc_span::symbol::sym;
2829
use rustc_span::DUMMY_SP;
30+
use std::fmt::Debug;
2931
use std::iter;
3032

3133
/// Whether we do the orphan check relative to this crate or
@@ -327,56 +329,56 @@ fn negative_impl<'cx, 'tcx>(
327329
let (impl2_trait_ref, obligations) =
328330
impl_trait_ref_and_oblig(selcx, impl1_env, impl2_def_id, impl2_substs);
329331

330-
// do the impls unify? If not, not disjoint.
331-
let Ok(InferOk { obligations: more_obligations, .. }) = infcx
332-
.at(&ObligationCause::dummy(), impl1_env)
333-
.eq(impl1_trait_ref, impl2_trait_ref) else {
334-
debug!(
335-
"explicit_disjoint: {:?} does not unify with {:?}",
336-
impl1_trait_ref, impl2_trait_ref
337-
);
338-
return false;
339-
};
340-
341-
let opt_failing_obligation = obligations
342-
.into_iter()
343-
.chain(more_obligations)
344-
.find(|o| negative_impl_exists(selcx, impl1_env, impl1_def_id, o));
345-
346-
if let Some(failing_obligation) = opt_failing_obligation {
347-
debug!("overlap: obligation unsatisfiable {:?}", failing_obligation);
348-
true
349-
} else {
350-
false
351-
}
332+
!obligations_satisfiable(
333+
&infcx,
334+
impl1_env,
335+
impl1_def_id,
336+
impl1_trait_ref,
337+
impl2_trait_ref,
338+
obligations,
339+
)
352340
} else {
353341
let ty1 = tcx.type_of(impl1_def_id);
354342
let ty2 = tcx.type_of(impl2_def_id);
355343

356-
let Ok(InferOk { obligations, .. }) = infcx
357-
.at(&ObligationCause::dummy(), impl1_env)
358-
.eq(ty1, ty2) else {
359-
debug!(
360-
"explicit_disjoint: {:?} does not unify with {:?}",
361-
ty1, ty2
362-
);
363-
return false;
364-
};
365-
366-
let opt_failing_obligation = obligations
367-
.into_iter()
368-
.find(|o| negative_impl_exists(selcx, impl1_env, impl1_def_id, o));
369-
370-
if let Some(failing_obligation) = opt_failing_obligation {
371-
debug!("overlap: obligation unsatisfiable {:?}", failing_obligation);
372-
true
373-
} else {
374-
false
375-
}
344+
!obligations_satisfiable(&infcx, impl1_env, impl1_def_id, ty1, ty2, iter::empty())
376345
}
377346
})
378347
}
379348

349+
fn obligations_satisfiable<'cx, 'tcx, T: Debug + ToTrace<'tcx>>(
350+
infcx: &InferCtxt<'cx, 'tcx>,
351+
impl1_env: ty::ParamEnv<'tcx>,
352+
impl1_def_id: DefId,
353+
impl1: T,
354+
impl2: T,
355+
obligations: impl Iterator<Item = PredicateObligation<'tcx>>,
356+
) -> bool {
357+
// do the impls unify? If not, not disjoint.
358+
let Ok(InferOk { obligations: more_obligations, .. }) = infcx
359+
.at(&ObligationCause::dummy(), impl1_env)
360+
.eq(impl1, impl2) else {
361+
debug!(
362+
"explicit_disjoint: {:?} does not unify with {:?}",
363+
impl1, impl2
364+
);
365+
return true;
366+
};
367+
368+
let selcx = &mut SelectionContext::new(&infcx);
369+
let opt_failing_obligation = obligations
370+
.into_iter()
371+
.chain(more_obligations)
372+
.find(|o| negative_impl_exists(selcx, impl1_env, impl1_def_id, o));
373+
374+
if let Some(failing_obligation) = opt_failing_obligation {
375+
debug!("overlap: obligation unsatisfiable {:?}", failing_obligation);
376+
false
377+
} else {
378+
true
379+
}
380+
}
381+
380382
/// Try to prove that a negative impl exist for the given obligation and their super predicates.
381383
#[instrument(level = "debug", skip(selcx))]
382384
fn negative_impl_exists<'cx, 'tcx>(

0 commit comments

Comments
 (0)