Skip to content

Commit 3527964

Browse files
committed
Account for indirect cyclic requirements
1 parent 2098ade commit 3527964

File tree

4 files changed

+102
-2
lines changed

4 files changed

+102
-2
lines changed

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
200200
&obligation.predicate,
201201
&obligation.cause.code,
202202
&mut vec![],
203+
&mut Default::default(),
203204
);
204205

205206
err.emit();
@@ -1700,6 +1701,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> {
17001701
&obligation.predicate,
17011702
&obligation.cause.code,
17021703
&mut vec![],
1704+
&mut Default::default(),
17031705
);
17041706
self.suggest_unsized_bound_if_applicable(err, obligation);
17051707
}

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::autoderef::Autoderef;
77
use crate::infer::InferCtxt;
88
use crate::traits::normalize_projection_type;
99

10+
use rustc_data_structures::fx::FxHashSet;
1011
use rustc_data_structures::stack::ensure_sufficient_stack;
1112
use rustc_errors::{error_code, struct_span_err, Applicability, DiagnosticBuilder, Style};
1213
use rustc_hir as hir;
@@ -158,6 +159,7 @@ pub trait InferCtxtExt<'tcx> {
158159
predicate: &T,
159160
cause_code: &ObligationCauseCode<'tcx>,
160161
obligated_types: &mut Vec<&ty::TyS<'tcx>>,
162+
seen_requirements: &mut FxHashSet<DefId>,
161163
) where
162164
T: fmt::Display;
163165

@@ -1787,6 +1789,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
17871789
&obligation.predicate,
17881790
next_code.unwrap(),
17891791
&mut Vec::new(),
1792+
&mut Default::default(),
17901793
);
17911794
}
17921795

@@ -1796,6 +1799,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
17961799
predicate: &T,
17971800
cause_code: &ObligationCauseCode<'tcx>,
17981801
obligated_types: &mut Vec<&ty::TyS<'tcx>>,
1802+
seen_requirements: &mut FxHashSet<DefId>,
17991803
) where
18001804
T: fmt::Display,
18011805
{
@@ -2050,12 +2054,14 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
20502054
&parent_predicate,
20512055
&data.parent_code,
20522056
obligated_types,
2057+
seen_requirements,
20532058
)
20542059
});
20552060
}
20562061
}
20572062
ObligationCauseCode::ImplDerivedObligation(ref data) => {
20582063
let mut parent_trait_ref = self.resolve_vars_if_possible(data.parent_trait_ref);
2064+
let parent_def_id = parent_trait_ref.def_id();
20592065
err.note(&format!(
20602066
"required because of the requirements on the impl of `{}` for `{}`",
20612067
parent_trait_ref.print_only_trait_path(),
@@ -2066,10 +2072,12 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
20662072
let mut data = data;
20672073
let mut redundant = false;
20682074
let mut count = 0;
2075+
seen_requirements.insert(parent_def_id);
20692076
while let ObligationCauseCode::ImplDerivedObligation(child) = &*data.parent_code {
20702077
// Skip redundant recursive obligation notes. See `ui/issue-20413.rs`.
20712078
let child_trait_ref = self.resolve_vars_if_possible(child.parent_trait_ref);
2072-
if parent_trait_ref.def_id() != child_trait_ref.def_id() {
2079+
let child_def_id = child_trait_ref.def_id();
2080+
if seen_requirements.insert(child_def_id) {
20732081
break;
20742082
}
20752083
count += 1;
@@ -2093,6 +2101,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
20932101
&parent_predicate,
20942102
&data.parent_code,
20952103
obligated_types,
2104+
seen_requirements,
20962105
)
20972106
});
20982107
}
@@ -2106,6 +2115,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
21062115
&parent_predicate,
21072116
&data.parent_code,
21082117
obligated_types,
2118+
seen_requirements,
21092119
)
21102120
});
21112121
}

src/test/ui/issues/issue-20413.rs

+28
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,32 @@ impl<T> Foo for T where NoData<T>: Foo {
1313
}
1414
}
1515

16+
trait Bar {
17+
fn answer(self);
18+
}
19+
20+
trait Baz {
21+
fn answer(self);
22+
}
23+
24+
struct AlmostNoData<T>(Option<T>);
25+
26+
struct EvenLessData<T>(Option<T>);
27+
28+
impl<T> Bar for T where EvenLessData<T>: Baz {
29+
//~^ ERROR: overflow evaluating the requirement
30+
//~| ERROR: overflow evaluating the requirement
31+
fn answer(self) {
32+
let val: EvenLessData<T> = EvenLessData(None);
33+
}
34+
}
35+
36+
impl<T> Baz for T where AlmostNoData<T>: Bar {
37+
//~^ ERROR: overflow evaluating the requirement
38+
//~| ERROR: overflow evaluating the requirement
39+
fn answer(self) {
40+
let val: NoData<T> = AlmostNoData(None);
41+
}
42+
}
43+
1644
fn main() {}

0 commit comments

Comments
 (0)