Skip to content

Commit

Permalink
Prevent cycle in implied predicates computation
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Feb 21, 2024
1 parent 1d447a9 commit 6edbc8d
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 8 deletions.
30 changes: 22 additions & 8 deletions compiler/rustc_hir_analysis/src/collect/predicates_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -640,16 +640,30 @@ pub(super) fn implied_predicates_with_filter(

// Now require that immediate supertraits are converted, which will, in
// turn, reach indirect supertraits, so we detect cycles now instead of
// overflowing during elaboration.
if matches!(filter, PredicateFilter::SelfOnly) {
for &(pred, span) in implied_bounds {
debug!("superbound: {:?}", pred);
if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
&& bound.polarity == ty::ImplPolarity::Positive
{
tcx.at(span).super_predicates_of(bound.def_id());
// overflowing during elaboration. Same for implied predicates, which
// make sure we walk into associated type bounds.
match filter {
PredicateFilter::SelfOnly => {
for &(pred, span) in implied_bounds {
debug!("superbound: {:?}", pred);
if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
&& bound.polarity == ty::ImplPolarity::Positive
{
tcx.at(span).super_predicates_of(bound.def_id());
}
}
}
PredicateFilter::SelfAndAssociatedTypeBounds => {
for &(pred, span) in implied_bounds {
debug!("superbound: {:?}", pred);
if let ty::ClauseKind::Trait(bound) = pred.kind().skip_binder()
&& bound.polarity == ty::ImplPolarity::Positive
{
tcx.at(span).implied_predicates_of(bound.def_id());
}
}
}
_ => {}
}

ty::GenericPredicates { parent: None, predicates: implied_bounds }
Expand Down
10 changes: 10 additions & 0 deletions tests/ui/associated-type-bounds/implied-bounds-cycle.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#![feature(associated_type_bounds)]

trait A {
type T;
}

trait B: A<T: B> {}
//~^ ERROR cycle detected when computing the implied predicates of `B`

fn main() {}
17 changes: 17 additions & 0 deletions tests/ui/associated-type-bounds/implied-bounds-cycle.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
error[E0391]: cycle detected when computing the implied predicates of `B`
--> $DIR/implied-bounds-cycle.rs:7:15
|
LL | trait B: A<T: B> {}
| ^
|
= note: ...which immediately requires computing the implied predicates of `B` again
note: cycle used when computing normalized predicates of `B`
--> $DIR/implied-bounds-cycle.rs:7:1
|
LL | trait B: A<T: B> {}
| ^^^^^^^^^^^^^^^^
= note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0391`.

0 comments on commit 6edbc8d

Please sign in to comment.