diff options
Diffstat (limited to 'src/test/ui/associated-types/cache/project-fn-ret-invariant.rs')
-rw-r--r-- | src/test/ui/associated-types/cache/project-fn-ret-invariant.rs | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs b/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs new file mode 100644 index 000000000..1075fd6e0 --- /dev/null +++ b/src/test/ui/associated-types/cache/project-fn-ret-invariant.rs @@ -0,0 +1,64 @@ +#![feature(unboxed_closures)] +// Test for projection cache. We should be able to project distinct +// lifetimes from `foo` as we reinstantiate it multiple times, but not +// if we do it just once. In this variant, the region `'a` is used in +// an invariant position, which affects the results. + +// revisions: ok oneuse transmute krisskross +//[ok] check-pass + +#![allow(dead_code, unused_variables)] + +use std::marker::PhantomData; + +struct Type<'a> { + // Invariant + data: PhantomData<fn(&'a u32) -> &'a u32>, +} + +fn foo<'a>() -> Type<'a> { + loop {} +} + +fn bar<T>(t: T, x: T::Output) -> T::Output +where + T: FnOnce<()>, +{ + t() +} + +#[cfg(ok)] // two instantiations: OK +fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) { + let a = bar(foo, x); + let b = bar(foo, y); + (a, b) +} + +#[cfg(oneuse)] // one instantiation: BAD +fn baz<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) { + let f = foo; // <-- No consistent type can be inferred for `f` here. + let a = bar(f, x); + //[oneuse]~^ ERROR lifetime may not live long enough + //[oneuse]~| ERROR lifetime may not live long enough + let b = bar(f, y); + (a, b) +} + +#[cfg(transmute)] // one instantiations: BAD +fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> { + // Cannot instantiate `foo` with any lifetime other than `'a`, + // since it is provided as input. + + bar(foo, x) //[transmute]~ ERROR lifetime may not live long enough +} + +#[cfg(krisskross)] // two instantiations, mixing and matching: BAD +fn transmute<'a, 'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) { + let a = bar(foo, y); + let b = bar(foo, x); + (a, b) + //[krisskross]~^ ERROR lifetime may not live long enough + //[krisskross]~| ERROR lifetime may not live long enough +} + +fn main() {} |