]> git.proxmox.com Git - rustc.git/blob - src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.rs
New upstream version 1.27.1+dfsg1
[rustc.git] / src / test / ui / nll / ty-outlives / ty-param-closure-outlives-from-where-clause.rs
1 // Copyright 2016 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 // Test that we can propagate `T: 'a` obligations to our caller. See
12 // `correct_region` for an explanation of how this test is setup; it's
13 // somewhat intricate.
14
15 // compile-flags:-Zborrowck=mir -Zverbose
16
17 #![allow(warnings)]
18 #![feature(rustc_attrs)]
19
20 use std::cell::Cell;
21
22 fn with_signature<'a, T, F>(a: Cell<&'a ()>, b: T, op: F)
23 where
24 F: FnOnce(Cell<&'a ()>, T),
25 {
26 op(a, b)
27 }
28
29 fn require<'a, T>(_a: &Cell<&'a ()>, _b: &T)
30 where
31 T: 'a,
32 {
33 }
34
35 #[rustc_regions]
36 fn no_region<'a, T>(a: Cell<&'a ()>, b: T) {
37 with_signature(a, b, |x, y| {
38 //~^ ERROR the parameter type `T` may not live long enough
39 //
40 // See `correct_region`, which explains the point of this
41 // test. The only difference is that, in the case of this
42 // function, there is no where clause *anywhere*, and hence we
43 // get an error (but reported by the closure creator).
44 require(&x, &y)
45 //~^ WARNING not reporting region error due to nll
46 })
47 }
48
49 #[rustc_regions]
50 fn correct_region<'a, T>(a: Cell<&'a ()>, b: T)
51 where
52 T: 'a,
53 {
54 with_signature(a, b, |x, y| {
55 // Key point of this test:
56 //
57 // The *closure* is being type-checked with all of its free
58 // regions "universalized". In particular, it does not know
59 // that `x` has the type `Cell<&'a ()>`, but rather treats it
60 // as if the type of `x` is `Cell<&'A ()>`, where `'A` is some
61 // fresh, independent region distinct from the `'a` which
62 // appears in the environment. The call to `require` here
63 // forces us then to prove that `T: 'A`, but the closure
64 // cannot do it on its own. It has to surface this requirement
65 // to its creator (which knows that `'a == 'A`).
66 require(&x, &y)
67 })
68 }
69
70 #[rustc_regions]
71 fn wrong_region<'a, 'b, T>(a: Cell<&'a ()>, b: T)
72 where
73 T: 'b,
74 {
75 with_signature(a, b, |x, y| {
76 //~^ ERROR the parameter type `T` may not live long enough
77 // See `correct_region`
78 require(&x, &y)
79 //~^ WARNING not reporting region error due to nll
80 })
81 }
82
83 #[rustc_regions]
84 fn outlives_region<'a, 'b, T>(a: Cell<&'a ()>, b: T)
85 where
86 T: 'b,
87 'b: 'a,
88 {
89 with_signature(a, b, |x, y| {
90 // See `correct_region`
91 require(&x, &y)
92 })
93 }
94
95 fn main() {}