Skip to content

Commit 8e59cf9

Browse files
committed
Auto merge of #135618 - lcnr:coherence-unknown, r=compiler-errors
add cache to `AmbiguityCausesVisitor` fixes #135457, alternative to #135524. cc https://rust-lang.zulipchat.com/#narrow/channel/364551-t-types.2Ftrait-system-refactor/topic/new-solver.20hang.20.23135457 r? `@compiler-errors`
2 parents 6067b36 + 0910173 commit 8e59cf9

File tree

5 files changed

+115
-28
lines changed

5 files changed

+115
-28
lines changed

compiler/rustc_trait_selection/src/traits/coherence.rs

+45-24
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
77
use std::fmt::Debug;
88

9-
use rustc_data_structures::fx::FxIndexSet;
9+
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
1010
use rustc_errors::{Diag, EmissionGuarantee};
1111
use rustc_hir::def::DefKind;
1212
use rustc_hir::def_id::DefId;
@@ -116,28 +116,39 @@ pub fn overlapping_impls(
116116
return None;
117117
}
118118

119-
let _overlap_with_bad_diagnostics = overlap(
120-
tcx,
121-
TrackAmbiguityCauses::No,
122-
skip_leak_check,
123-
impl1_def_id,
124-
impl2_def_id,
125-
overlap_mode,
126-
)?;
127-
128-
// In the case where we detect an error, run the check again, but
129-
// this time tracking intercrate ambiguity causes for better
130-
// diagnostics. (These take time and can lead to false errors.)
131-
let overlap = overlap(
132-
tcx,
133-
TrackAmbiguityCauses::Yes,
134-
skip_leak_check,
135-
impl1_def_id,
136-
impl2_def_id,
137-
overlap_mode,
138-
)
139-
.unwrap();
140-
Some(overlap)
119+
if tcx.next_trait_solver_in_coherence() {
120+
overlap(
121+
tcx,
122+
TrackAmbiguityCauses::Yes,
123+
skip_leak_check,
124+
impl1_def_id,
125+
impl2_def_id,
126+
overlap_mode,
127+
)
128+
} else {
129+
let _overlap_with_bad_diagnostics = overlap(
130+
tcx,
131+
TrackAmbiguityCauses::No,
132+
skip_leak_check,
133+
impl1_def_id,
134+
impl2_def_id,
135+
overlap_mode,
136+
)?;
137+
138+
// In the case where we detect an error, run the check again, but
139+
// this time tracking intercrate ambiguity causes for better
140+
// diagnostics. (These take time and can lead to false errors.)
141+
let overlap = overlap(
142+
tcx,
143+
TrackAmbiguityCauses::Yes,
144+
skip_leak_check,
145+
impl1_def_id,
146+
impl2_def_id,
147+
overlap_mode,
148+
)
149+
.unwrap();
150+
Some(overlap)
151+
}
141152
}
142153

143154
fn fresh_impl_header<'tcx>(infcx: &InferCtxt<'tcx>, impl_def_id: DefId) -> ty::ImplHeader<'tcx> {
@@ -615,6 +626,7 @@ fn compute_intercrate_ambiguity_causes<'tcx>(
615626
}
616627

617628
struct AmbiguityCausesVisitor<'a, 'tcx> {
629+
cache: FxHashSet<Goal<'tcx, ty::Predicate<'tcx>>>,
618630
causes: &'a mut FxIndexSet<IntercrateAmbiguityCause<'tcx>>,
619631
}
620632

@@ -624,6 +636,10 @@ impl<'a, 'tcx> ProofTreeVisitor<'tcx> for AmbiguityCausesVisitor<'a, 'tcx> {
624636
}
625637

626638
fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) {
639+
if !self.cache.insert(goal.goal()) {
640+
return;
641+
}
642+
627643
let infcx = goal.infcx();
628644
for cand in goal.candidates() {
629645
cand.visit_nested_in_probe(self);
@@ -748,5 +764,10 @@ fn search_ambiguity_causes<'tcx>(
748764
goal: Goal<'tcx, ty::Predicate<'tcx>>,
749765
causes: &mut FxIndexSet<IntercrateAmbiguityCause<'tcx>>,
750766
) {
751-
infcx.probe(|_| infcx.visit_proof_tree(goal, &mut AmbiguityCausesVisitor { causes }));
767+
infcx.probe(|_| {
768+
infcx.visit_proof_tree(goal, &mut AmbiguityCausesVisitor {
769+
cache: Default::default(),
770+
causes,
771+
})
772+
});
752773
}

tests/ui/coherence/occurs-check/associated-type.next.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
22
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
3-
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
4-
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
53
error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())`
64
--> $DIR/associated-type.rs:32:1
75
|

tests/ui/coherence/occurs-check/associated-type.old.stderr

-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
22
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
3-
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
4-
WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), "'a")], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit), .. }
53
error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())`
64
--> $DIR/associated-type.rs:32:1
75
|
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// Computing the ambiguity causes for the overlap ended up
2+
// causing an exponential blowup when recursing into the normalization
3+
// goals for `<Box<?t> as RecursiveSuper>::Assoc`. This test
4+
// takes multiple minutes when doing so and less than a second
5+
// otherwise.
6+
7+
//@ compile-flags: -Znext-solver=coherence
8+
9+
trait RecursiveSuper:
10+
Super<
11+
A0 = Self::Assoc,
12+
A1 = Self::Assoc,
13+
A2 = Self::Assoc,
14+
A3 = Self::Assoc,
15+
A4 = Self::Assoc,
16+
A5 = Self::Assoc,
17+
A6 = Self::Assoc,
18+
A7 = Self::Assoc,
19+
A8 = Self::Assoc,
20+
A9 = Self::Assoc,
21+
A10 = Self::Assoc,
22+
A11 = Self::Assoc,
23+
A12 = Self::Assoc,
24+
A13 = Self::Assoc,
25+
A14 = Self::Assoc,
26+
A15 = Self::Assoc,
27+
>
28+
{
29+
type Assoc;
30+
}
31+
32+
trait Super {
33+
type A0;
34+
type A1;
35+
type A2;
36+
type A3;
37+
type A4;
38+
type A5;
39+
type A6;
40+
type A7;
41+
type A8;
42+
type A9;
43+
type A10;
44+
type A11;
45+
type A12;
46+
type A13;
47+
type A14;
48+
type A15;
49+
}
50+
51+
trait Overlap {}
52+
impl<T: RecursiveSuper> Overlap for T {}
53+
impl<T> Overlap for Box<T> {}
54+
//~^ ERROR conflicting implementations of trait `Overlap` for type `Box<_>`
55+
56+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error[E0119]: conflicting implementations of trait `Overlap` for type `Box<_>`
2+
--> $DIR/ambiguity-causes-visitor-hang.rs:53:1
3+
|
4+
LL | impl<T: RecursiveSuper> Overlap for T {}
5+
| ------------------------------------- first implementation here
6+
LL | impl<T> Overlap for Box<T> {}
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
8+
|
9+
= note: downstream crates may implement trait `Super` for type `std::boxed::Box<_>`
10+
= note: downstream crates may implement trait `RecursiveSuper` for type `std::boxed::Box<_>`
11+
12+
error: aborting due to 1 previous error
13+
14+
For more information about this error, try `rustc --explain E0119`.

0 commit comments

Comments
 (0)