add and move trait solver cycle tests
This commit is contained in:
parent
d558353f28
commit
02529d2cbe
21 changed files with 215 additions and 1 deletions
|
@ -0,0 +1,37 @@
|
||||||
|
// compile-flags: -Ztrait-solver=next
|
||||||
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
|
// Test that having both an inductive and a coinductive cycle
|
||||||
|
// is handled correctly.
|
||||||
|
|
||||||
|
#[rustc_coinductive]
|
||||||
|
trait Trait {}
|
||||||
|
impl<T: Inductive + Coinductive> Trait for T {}
|
||||||
|
|
||||||
|
trait Inductive {}
|
||||||
|
impl<T: Trait> Inductive for T {}
|
||||||
|
#[rustc_coinductive]
|
||||||
|
trait Coinductive {}
|
||||||
|
impl<T: Trait> Coinductive for T {}
|
||||||
|
|
||||||
|
fn impls_trait<T: Trait>() {}
|
||||||
|
|
||||||
|
#[rustc_coinductive]
|
||||||
|
trait TraitRev {}
|
||||||
|
impl<T: CoinductiveRev + InductiveRev> TraitRev for T {}
|
||||||
|
|
||||||
|
trait InductiveRev {}
|
||||||
|
impl<T: TraitRev> InductiveRev for T {}
|
||||||
|
#[rustc_coinductive]
|
||||||
|
trait CoinductiveRev {}
|
||||||
|
impl<T: TraitRev> CoinductiveRev for T {}
|
||||||
|
|
||||||
|
fn impls_trait_rev<T: TraitRev>() {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
impls_trait::<()>();
|
||||||
|
//~^ ERROR overflow evaluating the requirement
|
||||||
|
|
||||||
|
impls_trait_rev::<()>();
|
||||||
|
//~^ ERROR overflow evaluating the requirement
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
error[E0275]: overflow evaluating the requirement `(): Trait`
|
||||||
|
--> $DIR/double-cycle-inductive-coinductive.rs:32:5
|
||||||
|
|
|
||||||
|
LL | impls_trait::<()>();
|
||||||
|
| ^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`)
|
||||||
|
note: required by a bound in `impls_trait`
|
||||||
|
--> $DIR/double-cycle-inductive-coinductive.rs:17:19
|
||||||
|
|
|
||||||
|
LL | fn impls_trait<T: Trait>() {}
|
||||||
|
| ^^^^^ required by this bound in `impls_trait`
|
||||||
|
|
||||||
|
error[E0275]: overflow evaluating the requirement `(): TraitRev`
|
||||||
|
--> $DIR/double-cycle-inductive-coinductive.rs:35:5
|
||||||
|
|
|
||||||
|
LL | impls_trait_rev::<()>();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
||||||
|
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`double_cycle_inductive_coinductive`)
|
||||||
|
note: required by a bound in `impls_trait_rev`
|
||||||
|
--> $DIR/double-cycle-inductive-coinductive.rs:29:23
|
||||||
|
|
|
||||||
|
LL | fn impls_trait_rev<T: TraitRev>() {}
|
||||||
|
| ^^^^^^^^ required by this bound in `impls_trait_rev`
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0275`.
|
48
tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs
Normal file
48
tests/ui/traits/new-solver/cycles/inductive-cycle-but-err.rs
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
// compile-flags: -Ztrait-solver=next
|
||||||
|
#![feature(trivial_bounds, marker_trait_attr)]
|
||||||
|
#![allow(trivial_bounds)]
|
||||||
|
// This previously triggered a bug in the provisional cache.
|
||||||
|
//
|
||||||
|
// This has the proof tree
|
||||||
|
// - `MultipleCandidates: Trait` proven via impl-one
|
||||||
|
// - `MultipleNested: Trait` via impl
|
||||||
|
// - `MultipleCandidates: Trait` (inductive cycle ~> OVERFLOW)
|
||||||
|
// - `DoesNotImpl: Trait` (ERR)
|
||||||
|
// - `MultipleCandidates: Trait` proven via impl-two
|
||||||
|
// - `MultipleNested: Trait` (in provisional cache ~> OVERFLOW)
|
||||||
|
//
|
||||||
|
// We previously incorrectly treated the `MultipleCandidates: Trait` as
|
||||||
|
// overflow because it was in the cache and reached via an inductive cycle.
|
||||||
|
// It should be `NoSolution`.
|
||||||
|
|
||||||
|
struct MultipleCandidates;
|
||||||
|
struct MultipleNested;
|
||||||
|
struct DoesNotImpl;
|
||||||
|
|
||||||
|
#[marker]
|
||||||
|
trait Trait {}
|
||||||
|
|
||||||
|
// impl-one
|
||||||
|
impl Trait for MultipleCandidates
|
||||||
|
where
|
||||||
|
MultipleNested: Trait
|
||||||
|
{}
|
||||||
|
|
||||||
|
// impl-two
|
||||||
|
impl Trait for MultipleCandidates
|
||||||
|
where
|
||||||
|
MultipleNested: Trait,
|
||||||
|
{}
|
||||||
|
|
||||||
|
impl Trait for MultipleNested
|
||||||
|
where
|
||||||
|
MultipleCandidates: Trait,
|
||||||
|
DoesNotImpl: Trait,
|
||||||
|
{}
|
||||||
|
|
||||||
|
fn impls_trait<T: Trait>() {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
impls_trait::<MultipleCandidates>();
|
||||||
|
//~^ ERROR the trait bound `MultipleCandidates: Trait` is not satisfied
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
error[E0277]: the trait bound `MultipleCandidates: Trait` is not satisfied
|
||||||
|
--> $DIR/inductive-cycle-but-err.rs:46:19
|
||||||
|
|
|
||||||
|
LL | impls_trait::<MultipleCandidates>();
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `MultipleCandidates`
|
||||||
|
|
|
||||||
|
= help: the trait `Trait` is implemented for `MultipleCandidates`
|
||||||
|
note: required by a bound in `impls_trait`
|
||||||
|
--> $DIR/inductive-cycle-but-err.rs:43:19
|
||||||
|
|
|
||||||
|
LL | fn impls_trait<T: Trait>() {}
|
||||||
|
| ^^^^^ required by this bound in `impls_trait`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
44
tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs
Normal file
44
tests/ui/traits/new-solver/cycles/inductive-cycle-but-ok.rs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// compile-flags: -Ztrait-solver=next
|
||||||
|
// check-pass
|
||||||
|
#![feature(trivial_bounds, marker_trait_attr)]
|
||||||
|
#![allow(trivial_bounds)]
|
||||||
|
|
||||||
|
// This previously triggered a bug in the provisional cache.
|
||||||
|
//
|
||||||
|
// This has the proof tree
|
||||||
|
// - `Root: Trait` proven via impl
|
||||||
|
// - `MultipleCandidates: Trait`
|
||||||
|
// - candidate: overflow-impl
|
||||||
|
// - `Root: Trait` (inductive cycle ~> OVERFLOW)
|
||||||
|
// - candidate: trivial-impl ~> YES
|
||||||
|
// - merge respones ~> YES
|
||||||
|
// - `MultipleCandidates: Trait` (in provisional cache ~> OVERFLOW)
|
||||||
|
//
|
||||||
|
// We previously incorrectly treated the `MultipleCandidates: Trait` as
|
||||||
|
// overflow because it was in the cache and reached via an inductive cycle.
|
||||||
|
// It should be `YES`.
|
||||||
|
|
||||||
|
struct Root;
|
||||||
|
struct MultipleCandidates;
|
||||||
|
|
||||||
|
#[marker]
|
||||||
|
trait Trait {}
|
||||||
|
impl Trait for Root
|
||||||
|
where
|
||||||
|
MultipleCandidates: Trait,
|
||||||
|
MultipleCandidates: Trait,
|
||||||
|
{}
|
||||||
|
|
||||||
|
// overflow-impl
|
||||||
|
impl Trait for MultipleCandidates
|
||||||
|
where
|
||||||
|
Root: Trait,
|
||||||
|
{}
|
||||||
|
// trivial-impl
|
||||||
|
impl Trait for MultipleCandidates {}
|
||||||
|
|
||||||
|
fn impls_trait<T: Trait>() {}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
impls_trait::<Root>();
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
// check-pass
|
||||||
|
// compile-flags: -Ztrait-solver=next
|
||||||
|
#![feature(rustc_attrs, marker_trait_attr)]
|
||||||
|
#[rustc_coinductive]
|
||||||
|
trait Trait {}
|
||||||
|
|
||||||
|
impl<T, U> Trait for (T, U)
|
||||||
|
where
|
||||||
|
(U, T): Trait,
|
||||||
|
(T, U): Inductive,
|
||||||
|
(): ConstrainToU32<T>,
|
||||||
|
{}
|
||||||
|
|
||||||
|
trait ConstrainToU32<T> {}
|
||||||
|
impl ConstrainToU32<u32> for () {}
|
||||||
|
|
||||||
|
// We only prefer the candidate without an inductive cycle
|
||||||
|
// once the inductive cycle has the same constraints as the
|
||||||
|
// other goal.
|
||||||
|
#[marker]
|
||||||
|
trait Inductive {}
|
||||||
|
impl<T, U> Inductive for (T, U)
|
||||||
|
where
|
||||||
|
(T, U): Trait,
|
||||||
|
{}
|
||||||
|
|
||||||
|
impl Inductive for (u32, u32) {}
|
||||||
|
|
||||||
|
fn impls_trait<T, U>()
|
||||||
|
where
|
||||||
|
(T, U): Trait,
|
||||||
|
{}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
impls_trait::<_, _>();
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
// check-pass
|
|
||||||
// compile-flags: -Ztrait-solver=next
|
// compile-flags: -Ztrait-solver=next
|
||||||
|
// check-pass
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
|
|
||||||
#[rustc_coinductive]
|
#[rustc_coinductive]
|
|
@ -1,6 +1,10 @@
|
||||||
// compile-flags: -Ztrait-solver=next
|
// compile-flags: -Ztrait-solver=next
|
||||||
// check-pass
|
// check-pass
|
||||||
|
|
||||||
|
// Test that selection prefers the builtin trait object impl for `Any`
|
||||||
|
// instead of the user defined impl. Both impls apply to the trait
|
||||||
|
// object.
|
||||||
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
|
||||||
fn needs_usize(_: &usize) {}
|
fn needs_usize(_: &usize) {}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue