File tree 4 files changed +57
-4
lines changed
tests/ui/traits/new-solver/cycles
4 files changed +57
-4
lines changed Original file line number Diff line number Diff line change 3
3
// Proving `W<?0>: Trait` instantiates `?0` with `(W<?1>, W<?2>)` and then
4
4
// proves `W<?1>: Trait` and `W<?2>: Trait`, resulting in a coinductive cycle.
5
5
//
6
- // Proving coinductive cycles runs until we reach a fixpoint. This fixpoint is
7
- // never reached here and each step doubles the amount of nested obligations.
6
+ // Proving coinductive cycles runs until we reach a fixpoint. However, after
7
+ // computing `try_evaluate_added_goals` in the second fixpoint iteration, the
8
+ // self type already has a depth equal to the number of steps. This results
9
+ // in enormous constraints, causing the canonicalizer to hang without ever
10
+ // reaching the recursion limit. We currently avoid that by erasing the constraints
11
+ // from overflow.
8
12
//
9
13
// This previously caused a hang in the trait solver, see
10
14
// https://github.com/rust-lang/trait-system-refactor-initiative/issues/13.
Original file line number Diff line number Diff line change 1
1
error[E0275]: overflow evaluating the requirement `W<_>: Trait`
2
- --> $DIR/fixpoint-exponential-growth.rs:29 :13
2
+ --> $DIR/fixpoint-exponential-growth.rs:33 :13
3
3
|
4
4
LL | impls::<W<_>>();
5
5
| ^^^^
6
6
|
7
7
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`fixpoint_exponential_growth`)
8
8
note: required by a bound in `impls`
9
- --> $DIR/fixpoint-exponential-growth.rs:26 :13
9
+ --> $DIR/fixpoint-exponential-growth.rs:30 :13
10
10
|
11
11
LL | fn impls<T: Trait>() {}
12
12
| ^^^^^ required by this bound in `impls`
Original file line number Diff line number Diff line change
1
+ // compile-flags: -Ztrait-solver=next
2
+
3
+ // This currently hangs if we do not erase constraints from
4
+ // overflow.
5
+ //
6
+ // We set the provisional result of `W<?0>` to `?0 := W<_>`.
7
+ // The next iteration does not simply result in a `?0 := W<W<_>` constraint as
8
+ // one might expect, but instead each time we evaluate the nested `W<T>` goal we
9
+ // apply the previously returned constraints: the first fixpoint iteration goes
10
+ // as follows: `W<?1>: Trait` constrains `?1` to `W<?2>`, we then evaluate
11
+ // `W<W<?2>>: Trait` the next time we try to prove the nested goal. This results
12
+ // inn `W<W<W<?3>>>` and so on. This goes on until we reach overflow in
13
+ // `try_evaluate_added_goals`. This means the provisional result after the
14
+ // second fixpoint iteration is already `W<W<W<...>>>` with a size proportional
15
+ // to the number of steps in `try_evaluate_added_goals`. The size then continues
16
+ // to grow. The exponential blowup from having 2 nested goals per impl causes
17
+ // the solver to hang without hitting the recursion limit.
18
+ trait Trait { }
19
+
20
+ struct W < T : ?Sized > ( * const T ) ;
21
+
22
+ impl < T : ?Sized > Trait for W < W < T > >
23
+ where
24
+ W < T > : Trait ,
25
+ W < T > : Trait ,
26
+ { }
27
+
28
+ fn impls_trait < T : Trait > ( ) { }
29
+
30
+ fn main ( ) {
31
+ impls_trait :: < W < _ > > ( ) ;
32
+ //~^ ERROR overflow evaluating the requirement
33
+ }
Original file line number Diff line number Diff line change
1
+ error[E0275]: overflow evaluating the requirement `W<_>: Trait`
2
+ --> $DIR/inductive-fixpoint-hang.rs:31:19
3
+ |
4
+ LL | impls_trait::<W<_>>();
5
+ | ^^^^
6
+ |
7
+ = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_fixpoint_hang`)
8
+ note: required by a bound in `impls_trait`
9
+ --> $DIR/inductive-fixpoint-hang.rs:28:19
10
+ |
11
+ LL | fn impls_trait<T: Trait>() {}
12
+ | ^^^^^ required by this bound in `impls_trait`
13
+
14
+ error: aborting due to 1 previous error
15
+
16
+ For more information about this error, try `rustc --explain E0275`.
You can’t perform that action at this time.
0 commit comments