]> git.lizzy.rs Git - rust.git/blob - src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs
ebf52918153c1678c15cd0d080faddb127dce564
[rust.git] / src / test / ui / associated-types / cache / project-fn-ret-contravariant.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 contravariant position, which affects the results.
8
9 // revisions: ok oneuse transmute krisskross
10
11 #![allow(dead_code, unused_variables)]
12
13 fn foo<'a>() -> &'a u32 { loop { } }
14
15 fn bar<T>(t: T, x: T::Output) -> T::Output
16     where T: FnOnce<()>
17 {
18     t()
19 }
20
21 #[cfg(ok)] // two instantiations: OK
22 fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
23     let a = bar(foo, x);
24     let b = bar(foo, y);
25     (a, b)
26 }
27
28 #[cfg(oneuse)] // one instantiation: OK (surprisingly)
29 fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
30     let f /* : fn() -> &'static u32 */ = foo; // <-- inferred type annotated
31     let a = bar(f, x); // this is considered ok because fn args are contravariant...
32     let b = bar(f, y); // ...and hence we infer T to distinct values in each call.
33     (a, b)
34 }
35
36 #[cfg(transmute)] // one instantiations: BAD
37 fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
38    bar(foo, x) //[transmute]~ ERROR E0495
39 }
40
41 #[cfg(krisskross)] // two instantiations, mixing and matching: BAD
42 fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
43    let a = bar(foo, y);
44    let b = bar(foo, x);
45    (a, b) //[krisskross]~ ERROR lifetime mismatch [E0623]
46    //[krisskross]~^ ERROR lifetime mismatch [E0623]
47 }
48
49 #[rustc_error]
50 fn main() { }
51 //[ok]~^ ERROR fatal error triggered by #[rustc_error]
52 //[oneuse]~^^ ERROR fatal error triggered by #[rustc_error]