]> git.lizzy.rs Git - rust.git/blob - src/test/ui/associated-types/cache/project-fn-ret-contravariant.rs
Rollup merge of #105567 - TimNN:kcfi16, r=nikic
[rust.git] / src / test / ui / associated-types / cache / project-fn-ret-contravariant.rs
1 #![feature(unboxed_closures)]
2
3 // Test for projection cache. We should be able to project distinct
4 // lifetimes from `foo` as we reinstantiate it multiple times, but not
5 // if we do it just once. In this variant, the region `'a` is used in
6 // an contravariant position, which affects the results.
7
8 // revisions: ok oneuse transmute krisskross
9 //[ok] check-pass
10 //[oneuse] check-pass
11
12 #![allow(dead_code, unused_variables)]
13
14 fn foo<'a>() -> &'a u32 { loop { } }
15
16 fn bar<T>(t: T, x: T::Output) -> T::Output
17     where T: FnOnce<()>
18 {
19     t()
20 }
21
22 #[cfg(ok)] // two instantiations: OK
23 fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
24     let a = bar(foo, x);
25     let b = bar(foo, y);
26     (a, b)
27 }
28
29 #[cfg(oneuse)] // one instantiation: OK (surprisingly)
30 fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
31     let f /* : fn() -> &'static u32 */ = foo; // <-- inferred type annotated
32     let a = bar(f, x); // this is considered ok because fn args are contravariant...
33     let b = bar(f, y); // ...and hence we infer T to distinct values in each call.
34     (a, b)
35 }
36
37 #[cfg(transmute)] // one instantiations: BAD
38 fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
39    bar(foo, x) //[transmute]~ ERROR lifetime may not live long enough
40 }
41
42 #[cfg(krisskross)] // two instantiations, mixing and matching: BAD
43 fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
44    let a = bar(foo, y);
45    let b = bar(foo, x);
46    (a, b) //[krisskross]~ ERROR lifetime may not live long enough
47    //[krisskross]~^ ERROR lifetime may not live long enough
48 }
49
50 fn main() { }