blob: 5756b76d7131c78616dc57e9d2857ec33e72c8f0 [file] [edit]
//@ compile-flags: -Znext-solver
//@ check-pass
// Regression test for trait-system-refactor-initiative#246
// Fixed by eager norm and marking param env as rigid.
#![feature(rustc_attrs)]
#![rustc_no_implicit_bounds]
// makes it work:
// #![recursion_limit = "512"]
pub trait Trait {
type K;
}
// two different types
pub struct T1;
pub struct T2;
// a type that's easy to make really large
pub struct Growing<T>(T);
// for which proving that it implements foo grows with that size
pub trait Foo {
type Output;
}
impl<T: Foo> Foo for Growing<T> {
type Output = <T as Foo>::Output;
}
impl Foo for T2 {
type Output = T1;
}
// a simple way to do this proof
pub type Eval<T> = <T as Foo>::Output;
// a trivial trait bound for one of the types
pub trait Trivial {}
impl Trivial for T1 {}
// and one for which one of the possible impls diverges
pub trait Diverges<T> {}
impl<I> Diverges<T2> for I {}
impl<I, R> Diverges<R> for I
where
R: Trivial, // move this bound down
Growing<I>: Diverges<T2>,
{
}
// Our large type
type LargeToEval = Growing<Growing<Growing<Growing<T2>>>>;
impl<K> Trait for K
where
(): Diverges<T2>,
T1: Trivial,
Eval<LargeToEval>: Trivial,
{
type K = K;
}
fn foo()
where
Eval<LargeToEval>: Trivial,
Eval<<LargeToEval as Trait>::K>: Trivial,
{
}
fn main() {
foo()
}