]> git.lizzy.rs Git - rust.git/blob - src/test/compile-fail/associated-types/cache/project-fn-ret-contravariant.rs
Improve SubSupConflict case with one named, one anonymous lifetime parameter #42701
[rust.git] / src / test / compile-fail / associated-types / cache / project-fn-ret-contravariant.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #![feature(unboxed_closures)]
12 #![feature(rustc_attrs)]
13
14 // Test for projection cache. We should be able to project distinct
15 // lifetimes from `foo` as we reinstantiate it multiple times, but not
16 // if we do it just once. In this variant, the region `'a` is used in
17 // an contravariant position, which affects the results.
18
19 // revisions: ok oneuse transmute krisskross
20
21 #![allow(dead_code, unused_variables)]
22
23 fn foo<'a>() -> &'a u32 { loop { } }
24
25 fn bar<T>(t: T, x: T::Output) -> T::Output
26     where T: FnOnce<()>
27 {
28     t()
29 }
30
31 #[cfg(ok)] // two instantiations: OK
32 fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
33     let a = bar(foo, x);
34     let b = bar(foo, y);
35     (a, b)
36 }
37
38 #[cfg(oneuse)] // one instantiation: OK (surprisingly)
39 fn baz<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
40     let f /* : fn() -> &'static u32 */ = foo; // <-- inferred type annotated
41     let a = bar(f, x); // this is considered ok because fn args are contravariant...
42     let b = bar(f, y); // ...and hence we infer T to distinct values in each call.
43     (a, b)
44 }
45
46 #[cfg(transmute)] // one instantiations: BAD
47 fn baz<'a,'b>(x: &'a u32) -> &'static u32 {
48    bar(foo, x) //[transmute]~ ERROR E0495
49 }
50
51 #[cfg(krisskross)] // two instantiations, mixing and matching: BAD
52 fn transmute<'a,'b>(x: &'a u32, y: &'b u32) -> (&'a u32, &'b u32) {
53    let a = bar(foo, y);
54    let b = bar(foo, x);
55    (a, b) //[krisskross]~ ERROR 55:5: 55:6: lifetime mismatch [E0623]
56    //[krisskross]~^ ERROR 55:8: 55:9: lifetime mismatch [E0623]
57 }
58
59 #[rustc_error]
60 fn main() { }
61 //[ok]~^ ERROR compilation successful
62 //[oneuse]~^^ ERROR compilation successful