Skip to content

Commit 02529d2

Browse files
committed
add and move trait solver cycle tests
1 parent d558353 commit 02529d2

21 files changed

+215
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// compile-flags: -Ztrait-solver=next
2+
#![feature(rustc_attrs)]
3+
4+
// Test that having both an inductive and a coinductive cycle
5+
// is handled correctly.
6+
7+
#[rustc_coinductive]
8+
trait Trait {}
9+
impl<T: Inductive + Coinductive> Trait for T {}
10+
11+
trait Inductive {}
12+
impl<T: Trait> Inductive for T {}
13+
#[rustc_coinductive]
14+
trait Coinductive {}
15+
impl<T: Trait> Coinductive for T {}
16+
17+
fn impls_trait<T: Trait>() {}
18+
19+
#[rustc_coinductive]
20+
trait TraitRev {}
21+
impl<T: CoinductiveRev + InductiveRev> TraitRev for T {}
22+
23+
trait InductiveRev {}
24+
impl<T: TraitRev> InductiveRev for T {}
25+
#[rustc_coinductive]
26+
trait CoinductiveRev {}
27+
impl<T: TraitRev> CoinductiveRev for T {}
28+
29+
fn impls_trait_rev<T: TraitRev>() {}
30+
31+
fn main() {
32+
impls_trait::<()>();
33+
//~^ ERROR overflow evaluating the requirement
34+
35+
impls_trait_rev::<()>();
36+
//~^ ERROR overflow evaluating the requirement
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
error[E0275]: overflow evaluating the requirement `(): Trait`
2+
--> $DIR/double-cycle-inductive-coinductive.rs:32:5
3+
|
4+
LL | impls_trait::<()>();
5+
| ^^^^^^^^^^^^^^^^^
6+
|
7+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`)
8+
note: required by a bound in `impls_trait`
9+
--> $DIR/double-cycle-inductive-coinductive.rs:17:19
10+
|
11+
LL | fn impls_trait<T: Trait>() {}
12+
| ^^^^^ required by this bound in `impls_trait`
13+
14+
error[E0275]: overflow evaluating the requirement `(): TraitRev`
15+
--> $DIR/double-cycle-inductive-coinductive.rs:35:5
16+
|
17+
LL | impls_trait_rev::<()>();
18+
| ^^^^^^^^^^^^^^^^^^^^^
19+
|
20+
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`)
21+
note: required by a bound in `impls_trait_rev`
22+
--> $DIR/double-cycle-inductive-coinductive.rs:29:23
23+
|
24+
LL | fn impls_trait_rev<T: TraitRev>() {}
25+
| ^^^^^^^^ required by this bound in `impls_trait_rev`
26+
27+
error: aborting due to 2 previous errors
28+
29+
For more information about this error, try `rustc --explain E0275`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// compile-flags: -Ztrait-solver=next
2+
#![feature(trivial_bounds, marker_trait_attr)]
3+
#![allow(trivial_bounds)]
4+
// This previously triggered a bug in the provisional cache.
5+
//
6+
// This has the proof tree
7+
// - `MultipleCandidates: Trait` proven via impl-one
8+
// - `MultipleNested: Trait` via impl
9+
// - `MultipleCandidates: Trait` (inductive cycle ~> OVERFLOW)
10+
// - `DoesNotImpl: Trait` (ERR)
11+
// - `MultipleCandidates: Trait` proven via impl-two
12+
// - `MultipleNested: Trait` (in provisional cache ~> OVERFLOW)
13+
//
14+
// We previously incorrectly treated the `MultipleCandidates: Trait` as
15+
// overflow because it was in the cache and reached via an inductive cycle.
16+
// It should be `NoSolution`.
17+
18+
struct MultipleCandidates;
19+
struct MultipleNested;
20+
struct DoesNotImpl;
21+
22+
#[marker]
23+
trait Trait {}
24+
25+
// impl-one
26+
impl Trait for MultipleCandidates
27+
where
28+
MultipleNested: Trait
29+
{}
30+
31+
// impl-two
32+
impl Trait for MultipleCandidates
33+
where
34+
MultipleNested: Trait,
35+
{}
36+
37+
impl Trait for MultipleNested
38+
where
39+
MultipleCandidates: Trait,
40+
DoesNotImpl: Trait,
41+
{}
42+
43+
fn impls_trait<T: Trait>() {}
44+
45+
fn main() {
46+
impls_trait::<MultipleCandidates>();
47+
//~^ ERROR the trait bound `MultipleCandidates: Trait` is not satisfied
48+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0277]: the trait bound `MultipleCandidates: Trait` is not satisfied
2+
--> $DIR/inductive-cycle-but-err.rs:46:19
3+
|
4+
LL | impls_trait::<MultipleCandidates>();
5+
| ^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `MultipleCandidates`
6+
|
7+
= help: the trait `Trait` is implemented for `MultipleCandidates`
8+
note: required by a bound in `impls_trait`
9+
--> $DIR/inductive-cycle-but-err.rs:43:19
10+
|
11+
LL | fn impls_trait<T: Trait>() {}
12+
| ^^^^^ required by this bound in `impls_trait`
13+
14+
error: aborting due to previous error
15+
16+
For more information about this error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// compile-flags: -Ztrait-solver=next
2+
// check-pass
3+
#![feature(trivial_bounds, marker_trait_attr)]
4+
#![allow(trivial_bounds)]
5+
6+
// This previously triggered a bug in the provisional cache.
7+
//
8+
// This has the proof tree
9+
// - `Root: Trait` proven via impl
10+
// - `MultipleCandidates: Trait`
11+
// - candidate: overflow-impl
12+
// - `Root: Trait` (inductive cycle ~> OVERFLOW)
13+
// - candidate: trivial-impl ~> YES
14+
// - merge respones ~> YES
15+
// - `MultipleCandidates: Trait` (in provisional cache ~> OVERFLOW)
16+
//
17+
// We previously incorrectly treated the `MultipleCandidates: Trait` as
18+
// overflow because it was in the cache and reached via an inductive cycle.
19+
// It should be `YES`.
20+
21+
struct Root;
22+
struct MultipleCandidates;
23+
24+
#[marker]
25+
trait Trait {}
26+
impl Trait for Root
27+
where
28+
MultipleCandidates: Trait,
29+
MultipleCandidates: Trait,
30+
{}
31+
32+
// overflow-impl
33+
impl Trait for MultipleCandidates
34+
where
35+
Root: Trait,
36+
{}
37+
// trivial-impl
38+
impl Trait for MultipleCandidates {}
39+
40+
fn impls_trait<T: Trait>() {}
41+
42+
fn main() {
43+
impls_trait::<Root>();
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// check-pass
2+
// compile-flags: -Ztrait-solver=next
3+
#![feature(rustc_attrs, marker_trait_attr)]
4+
#[rustc_coinductive]
5+
trait Trait {}
6+
7+
impl<T, U> Trait for (T, U)
8+
where
9+
(U, T): Trait,
10+
(T, U): Inductive,
11+
(): ConstrainToU32<T>,
12+
{}
13+
14+
trait ConstrainToU32<T> {}
15+
impl ConstrainToU32<u32> for () {}
16+
17+
// We only prefer the candidate without an inductive cycle
18+
// once the inductive cycle has the same constraints as the
19+
// other goal.
20+
#[marker]
21+
trait Inductive {}
22+
impl<T, U> Inductive for (T, U)
23+
where
24+
(T, U): Trait,
25+
{}
26+
27+
impl Inductive for (u32, u32) {}
28+
29+
fn impls_trait<T, U>()
30+
where
31+
(T, U): Trait,
32+
{}
33+
34+
fn main() {
35+
impls_trait::<_, _>();
36+
}

tests/ui/traits/new-solver/leak-check-coinductive-cycle.rs renamed to tests/ui/traits/new-solver/cycles/leak-check-coinductive-cycle.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// check-pass
21
// compile-flags: -Ztrait-solver=next
2+
// check-pass
33
#![feature(rustc_attrs)]
44

55
#[rustc_coinductive]

tests/ui/traits/new-solver/dyn-any-dont-prefer-impl.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
// compile-flags: -Ztrait-solver=next
22
// check-pass
33

4+
// Test that selection prefers the builtin trait object impl for `Any`
5+
// instead of the user defined impl. Both impls apply to the trait
6+
// object.
7+
48
use std::any::Any;
59

610
fn needs_usize(_: &usize) {}

0 commit comments

Comments
 (0)