mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
add and move trait solver cycle tests
This commit is contained in:
parent
d558353f28
commit
02529d2cbe
@ -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
|
||||
// check-pass
|
||||
#![feature(rustc_attrs)]
|
||||
|
||||
#[rustc_coinductive]
|
@ -1,6 +1,10 @@
|
||||
// compile-flags: -Ztrait-solver=next
|
||||
// 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;
|
||||
|
||||
fn needs_usize(_: &usize) {}
|
||||
|
Loading…
Reference in New Issue
Block a user