Skip to content

Commit 614760f

Browse files
committed
review
1 parent 8167a25 commit 614760f

File tree

1 file changed

+75
-78
lines changed

1 file changed

+75
-78
lines changed

Diff for: compiler/rustc_trait_selection/src/traits/coherence.rs

+75-78
Original file line numberDiff line numberDiff line change
@@ -214,76 +214,69 @@ fn overlap<'tcx>(
214214
let mut obligations = equate_impl_headers(selcx.infcx, &impl1_header, &impl2_header)?;
215215
debug!("overlap: unification check succeeded");
216216

217-
if !overlap_mode.use_implicit_negative() {
218-
let impl_header = selcx.infcx.resolve_vars_if_possible(impl1_header);
219-
return Some(OverlapResult {
220-
impl_header,
221-
intercrate_ambiguity_causes: Default::default(),
222-
involves_placeholder: false,
223-
});
224-
};
225-
226217
obligations.extend(
227218
[&impl1_header.predicates, &impl2_header.predicates].into_iter().flatten().map(
228219
|&predicate| Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, predicate),
229220
),
230221
);
231222

232-
for mode in [TreatInductiveCycleAs::Ambig, TreatInductiveCycleAs::Recur] {
233-
if let Some(failing_obligation) = selcx.with_treat_inductive_cycle_as(mode, |selcx| {
234-
impl_intersection_has_impossible_obligation(selcx, &obligations)
235-
}) {
236-
if matches!(mode, TreatInductiveCycleAs::Recur) {
237-
let first_local_impl = impl1_header
238-
.impl_def_id
239-
.as_local()
240-
.or(impl2_header.impl_def_id.as_local())
241-
.expect("expected one of the impls to be local");
242-
infcx.tcx.struct_span_lint_hir(
243-
COINDUCTIVE_OVERLAP_IN_COHERENCE,
244-
infcx.tcx.local_def_id_to_hir_id(first_local_impl),
245-
infcx.tcx.def_span(first_local_impl),
246-
format!(
247-
"implementations {} will conflict in the future",
248-
match impl1_header.trait_ref {
249-
Some(trait_ref) => {
250-
let trait_ref = infcx.resolve_vars_if_possible(trait_ref);
251-
format!(
252-
"of `{}` for `{}`",
253-
trait_ref.print_only_trait_path(),
254-
trait_ref.self_ty()
255-
)
256-
}
257-
None => format!(
258-
"for `{}`",
259-
infcx.resolve_vars_if_possible(impl1_header.self_ty)
260-
),
223+
if overlap_mode.use_implicit_negative() {
224+
for mode in [TreatInductiveCycleAs::Ambig, TreatInductiveCycleAs::Recur] {
225+
if let Some(failing_obligation) = selcx.with_treat_inductive_cycle_as(mode, |selcx| {
226+
impl_intersection_has_impossible_obligation(selcx, &obligations)
227+
}) {
228+
if matches!(mode, TreatInductiveCycleAs::Recur) {
229+
let first_local_impl = impl1_header
230+
.impl_def_id
231+
.as_local()
232+
.or(impl2_header.impl_def_id.as_local())
233+
.expect("expected one of the impls to be local");
234+
infcx.tcx.struct_span_lint_hir(
235+
COINDUCTIVE_OVERLAP_IN_COHERENCE,
236+
infcx.tcx.local_def_id_to_hir_id(first_local_impl),
237+
infcx.tcx.def_span(first_local_impl),
238+
format!(
239+
"implementations {} will conflict in the future",
240+
match impl1_header.trait_ref {
241+
Some(trait_ref) => {
242+
let trait_ref = infcx.resolve_vars_if_possible(trait_ref);
243+
format!(
244+
"of `{}` for `{}`",
245+
trait_ref.print_only_trait_path(),
246+
trait_ref.self_ty()
247+
)
248+
}
249+
None => format!(
250+
"for `{}`",
251+
infcx.resolve_vars_if_possible(impl1_header.self_ty)
252+
),
253+
},
254+
),
255+
|lint| {
256+
lint.note(
257+
"impls that are not considered to overlap may be considered to \
258+
overlap in the future",
259+
)
260+
.span_label(
261+
infcx.tcx.def_span(impl1_header.impl_def_id),
262+
"the first impl is here",
263+
)
264+
.span_label(
265+
infcx.tcx.def_span(impl2_header.impl_def_id),
266+
"the second impl is here",
267+
);
268+
lint.note(format!(
269+
"`{}` may be considered to hold in future releases, \
270+
causing the impls to overlap",
271+
infcx.resolve_vars_if_possible(failing_obligation.predicate)
272+
));
273+
lint
261274
},
262-
),
263-
|lint| {
264-
lint.note(
265-
"impls that are not considered to overlap may be considered to \
266-
overlap in the future",
267-
)
268-
.span_label(
269-
infcx.tcx.def_span(impl1_header.impl_def_id),
270-
"the first impl is here",
271-
)
272-
.span_label(
273-
infcx.tcx.def_span(impl2_header.impl_def_id),
274-
"the second impl is here",
275-
);
276-
lint.note(format!(
277-
"`{}` may be considered to hold in future releases, \
278-
causing the impls to overlap",
279-
infcx.resolve_vars_if_possible(failing_obligation.predicate)
280-
));
281-
lint
282-
},
283-
);
284-
}
275+
);
276+
}
285277

286-
return None;
278+
return None;
279+
}
287280
}
288281
}
289282

@@ -294,7 +287,9 @@ fn overlap<'tcx>(
294287
return None;
295288
}
296289

297-
let intercrate_ambiguity_causes = if infcx.next_trait_solver() {
290+
let intercrate_ambiguity_causes = if !overlap_mode.use_implicit_negative() {
291+
Default::default()
292+
} else if infcx.next_trait_solver() {
298293
compute_intercrate_ambiguity_causes(&infcx, &obligations)
299294
} else {
300295
selcx.take_intercrate_ambiguity_causes()
@@ -932,6 +927,8 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
932927

933928
let Goal { param_env, predicate } = goal.goal();
934929

930+
// For bound predicates we simply call `infcx.replace_bound_vars_with_placeholders`
931+
// and then prove the resulting predicate as a nested goal.
935932
let trait_ref = match predicate.kind().no_bound_vars() {
936933
Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(tr))) => tr.trait_ref,
937934
Some(ty::PredicateKind::Clause(ty::ClauseKind::Projection(proj))) => {
@@ -942,21 +939,6 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
942939

943940
let mut ambiguity_cause = None;
944941
for cand in goal.candidates() {
945-
match cand.result() {
946-
Ok(Certainty::Maybe(_)) => {}
947-
// We only add intercrate ambiguity causes if the goal would
948-
// otherwise result in an error.
949-
//
950-
// FIXME: this isn't quite right. Changing a goal from YES with
951-
// inference contraints to AMBIGUOUS can also cause a goal to not
952-
// fail.
953-
Ok(Certainty::Yes) => {
954-
ambiguity_cause = None;
955-
break;
956-
}
957-
Err(NoSolution) => continue,
958-
}
959-
960942
// FIXME: boiiii, using string comparisions here sure is scuffed.
961943
if let inspect::ProbeKind::MiscCandidate { name: "coherence unknowable", result: _ } =
962944
cand.kind()
@@ -1011,6 +993,21 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a> {
1011993
}
1012994
}
1013995
})
996+
} else {
997+
match cand.result() {
998+
// We only add an ambiguity cause if the goal would otherwise
999+
// result in an error.
1000+
//
1001+
// FIXME: While this matches the behavior of the
1002+
// old solver, it is not the only way in which the unknowable
1003+
// candidates *weaken* coherence, they can also force otherwise
1004+
// sucessful normalization to be ambiguous.
1005+
Ok(Certainty::Maybe(_) | Certainty::Yes) => {
1006+
ambiguity_cause = None;
1007+
break;
1008+
}
1009+
Err(NoSolution) => continue,
1010+
}
10141011
}
10151012
}
10161013

0 commit comments

Comments
 (0)