]> git.lizzy.rs Git - rust.git/blob - src/test/ui/associated-types/cache/project-fn-ret-invariant.rs
54b6e3642c2eacfc6be858e757e531566df923b7
[rust.git] / src / test / ui / associated-types / cache / project-fn-ret-invariant.rs
1 #![feature(unboxed_closures)]
2 #![feature(rustc_attrs)]
3
4 // Test for projection cache. We should be able to project distinct
5 // lifetimes from `foo` as we reinstantiate it multiple times, but not
6 // if we do it just once. In this variant, the region `'a` is used in
7 // an invariant position, which affects the results.
8
9 // revisions: ok oneuse transmute krisskross
10
11 #![allow(dead_code, unused_variables)]
12
13 use std::marker::PhantomData;
14
15 struct Type<'a> {
16     // Invariant
17     data: PhantomData<fn(&'a u32) -> &'a u32>
18 }
19
20 fn foo<'a>() -> Type<'a> { loop { } }
21
22 fn bar<T>(t: T, x: T::Output) -> T::Output
23     where T: FnOnce<()>
24 {
25     t()
26 }
27
28 #[cfg(ok)] // two instantiations: OK
29 fn baz<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
30     let a = bar(foo, x);
31     let b = bar(foo, y);
32     (a, b)
33 }
34
35 #[cfg(oneuse)] // one instantiation: BAD
36 fn baz<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
37    let f = foo; // <-- No consistent type can be inferred for `f` here.
38    let a = bar(f, x);
39    let b = bar(f, y); //[oneuse]~ ERROR lifetime mismatch [E0623]
40    (a, b)
41 }
42
43 #[cfg(transmute)] // one instantiations: BAD
44 fn baz<'a,'b>(x: Type<'a>) -> Type<'static> {
45    // Cannot instantiate `foo` with any lifetime other than `'a`,
46    // since it is provided as input.
47
48    bar(foo, x) //[transmute]~ ERROR E0495
49 }
50
51 #[cfg(krisskross)] // two instantiations, mixing and matching: BAD
52 fn transmute<'a,'b>(x: Type<'a>, y: Type<'b>) -> (Type<'a>, Type<'b>) {
53    let a = bar(foo, y); //[krisskross]~ ERROR E0623
54    let b = bar(foo, x); //[krisskross]~ ERROR E0623
55    (a, b)
56 }
57
58 #[rustc_error]
59 fn main() { }
60 //[ok]~^ ERROR compilation successful