Skip to content

Commit b2a45f0

Browse files
committed
Extract stable_disjoint fn
1 parent 052b31b commit b2a45f0

File tree

1 file changed

+41
-21
lines changed

1 file changed

+41
-21
lines changed

compiler/rustc_trait_selection/src/traits/coherence.rs

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,9 @@ fn overlap_within_probe<'cx, 'tcx>(
157157
impl2_def_id: DefId,
158158
snapshot: &CombinedSnapshot<'_, 'tcx>,
159159
) -> Option<OverlapResult<'tcx>> {
160+
let infcx = selcx.infcx();
161+
let tcx = infcx.tcx;
162+
160163
// For the purposes of this check, we don't bring any placeholder
161164
// types into scope; instead, we replace the generic types with
162165
// fresh type variables, and hence we do our evaluations in an
@@ -166,6 +169,39 @@ fn overlap_within_probe<'cx, 'tcx>(
166169
let impl1_header = with_fresh_ty_vars(selcx, param_env, impl1_def_id);
167170
let impl2_header = with_fresh_ty_vars(selcx, param_env, impl2_def_id);
168171

172+
let strict_coherence = tcx.has_attr(impl1_def_id, sym::rustc_strict_coherence)
173+
&& tcx.has_attr(impl2_def_id, sym::rustc_strict_coherence);
174+
175+
if stable_disjoint(selcx, param_env, &impl1_header, impl2_header, strict_coherence) {
176+
return None;
177+
}
178+
179+
if !skip_leak_check.is_yes() {
180+
if infcx.leak_check(true, snapshot).is_err() {
181+
debug!("overlap: leak check failed");
182+
return None;
183+
}
184+
}
185+
186+
let intercrate_ambiguity_causes = selcx.take_intercrate_ambiguity_causes();
187+
debug!("overlap: intercrate_ambiguity_causes={:#?}", intercrate_ambiguity_causes);
188+
189+
let involves_placeholder =
190+
matches!(selcx.infcx().region_constraints_added_in_snapshot(snapshot), Some(true));
191+
192+
let impl_header = selcx.infcx().resolve_vars_if_possible(impl1_header);
193+
Some(OverlapResult { impl_header, intercrate_ambiguity_causes, involves_placeholder })
194+
}
195+
196+
/// Given impl1 and impl2 check if both impls can be satisfied by a common type (including
197+
/// where-clauses) If so, return false, otherwise return true, they are disjoint.
198+
fn stable_disjoint<'cx, 'tcx>(
199+
selcx: &mut SelectionContext<'cx, 'tcx>,
200+
param_env: ty::ParamEnv<'tcx>,
201+
impl1_header: &ty::ImplHeader<'tcx>,
202+
impl2_header: ty::ImplHeader<'tcx>,
203+
strict_coherence: bool,
204+
) -> bool {
169205
debug!("overlap: impl1_header={:?}", impl1_header);
170206
debug!("overlap: impl2_header={:?}", impl2_header);
171207

@@ -177,7 +213,7 @@ fn overlap_within_probe<'cx, 'tcx>(
177213
{
178214
Ok(InferOk { obligations, value: () }) => obligations,
179215
Err(_) => {
180-
return None;
216+
return true;
181217
}
182218
};
183219

@@ -222,9 +258,7 @@ fn overlap_within_probe<'cx, 'tcx>(
222258
.find(|o| {
223259
// if both impl headers are set to strict coherence it means that this will be accepted
224260
// only if it's stated that T: !Trait. So only prove that the negated obligation holds.
225-
if tcx.has_attr(impl1_def_id, sym::rustc_strict_coherence)
226-
&& tcx.has_attr(impl2_def_id, sym::rustc_strict_coherence)
227-
{
261+
if strict_coherence {
228262
strict_check(selcx, o)
229263
} else {
230264
loose_check(selcx, o) || tcx.features().negative_impls && strict_check(selcx, o)
@@ -236,24 +270,10 @@ fn overlap_within_probe<'cx, 'tcx>(
236270

237271
if let Some(failing_obligation) = opt_failing_obligation {
238272
debug!("overlap: obligation unsatisfiable {:?}", failing_obligation);
239-
return None;
240-
}
241-
242-
if !skip_leak_check.is_yes() {
243-
if infcx.leak_check(true, snapshot).is_err() {
244-
debug!("overlap: leak check failed");
245-
return None;
246-
}
273+
true
274+
} else {
275+
false
247276
}
248-
249-
let impl_header = selcx.infcx().resolve_vars_if_possible(impl1_header);
250-
let intercrate_ambiguity_causes = selcx.take_intercrate_ambiguity_causes();
251-
debug!("overlap: intercrate_ambiguity_causes={:#?}", intercrate_ambiguity_causes);
252-
253-
let involves_placeholder =
254-
matches!(selcx.infcx().region_constraints_added_in_snapshot(snapshot), Some(true));
255-
256-
Some(OverlapResult { impl_header, intercrate_ambiguity_causes, involves_placeholder })
257277
}
258278

259279
fn loose_check<'cx, 'tcx>(

0 commit comments

Comments
 (0)