]> git.lizzy.rs Git - rust.git/blob - tests/ui/dropck/dropck-eyepatch-reorder.rs
Rollup merge of #106797 - FawazTirmizi:dev/issues/104284, r=bjorn3
[rust.git] / tests / ui / dropck / dropck-eyepatch-reorder.rs
1 #![feature(dropck_eyepatch)]
2
3 // The point of this test is to test uses of `#[may_dangle]` attribute
4 // where the formal declaration order (in the impl generics) does not
5 // match the actual usage order (in the type instantiation).
6 //
7 // See also dropck-eyepatch.rs for more information about the general
8 // structure of the test.
9
10 use std::fmt;
11
12 struct Dt<A: fmt::Debug>(&'static str, A);
13 struct Dr<'a, B:'a+fmt::Debug>(&'static str, &'a B);
14 struct Pt<A: fmt::Debug, B: fmt::Debug>(&'static str, A, B);
15 struct Pr<'a, 'b, B:'a+'b+fmt::Debug>(&'static str, &'a B, &'b B);
16 struct St<A: fmt::Debug>(&'static str, A);
17 struct Sr<'a, B:'a+fmt::Debug>(&'static str, &'a B);
18
19 impl<A: fmt::Debug> Drop for Dt<A> {
20     fn drop(&mut self) { println!("drop {} {:?}", self.0, self.1); }
21 }
22 impl<'a, B: fmt::Debug> Drop for Dr<'a, B> {
23     fn drop(&mut self) { println!("drop {} {:?}", self.0, self.1); }
24 }
25 unsafe impl<B: fmt::Debug, #[may_dangle] A: fmt::Debug> Drop for Pt<A, B> {
26     // (unsafe to access self.1  due to #[may_dangle] on A)
27     fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); }
28 }
29 unsafe impl<'b, #[may_dangle] 'a, B: fmt::Debug> Drop for Pr<'a, 'b, B> {
30     // (unsafe to access self.1 due to #[may_dangle] on 'a)
31     fn drop(&mut self) { println!("drop {} {:?}", self.0, self.2); }
32 }
33
34 fn main() {
35     use std::cell::Cell;
36
37     // We use separate blocks with separate variable to prevent the error
38     // messages from being deduplicated.
39
40     {
41         let c_long;
42         let (mut dt, mut dr): (Dt<_>, Dr<_>);
43         c_long = Cell::new(1);
44
45         // No error: sufficiently long-lived state can be referenced in dtors
46         dt = Dt("dt", &c_long);
47         dr = Dr("dr", &c_long);
48     }
49
50     {
51         let (c, mut dt, mut dr): (Cell<_>, Dt<_>, Dr<_>);
52         c = Cell::new(1);
53
54         // No Error: destructor order precisely modelled
55         dt = Dt("dt", &c);
56         dr = Dr("dr", &c);
57     }
58
59     {
60         let (mut dt, mut dr, c_shortest): (Dt<_>, Dr<_>, Cell<_>);
61         c_shortest = Cell::new(1);
62
63         // Error: `c_shortest` dies too soon for the references in dtors to be valid.
64         dt = Dt("dt", &c_shortest);
65         //~^ ERROR `c_shortest` does not live long enough
66         dr = Dr("dr", &c_shortest);
67     }
68
69     {
70         let c_long;
71         let (mut pt, mut pr, c_shortest): (Pt<_, _>, Pr<_>, Cell<_>);
72         c_long = Cell::new(1);
73         c_shortest = Cell::new(1);
74
75         // No error: Drop impl asserts .1 (A and &'a _) are not accessed
76         pt = Pt("pt", &c_shortest, &c_long);
77         pr = Pr("pr", &c_shortest, &c_long);
78     }
79
80     {
81         let c_long;
82         let (mut pt, mut pr, c_shortest): (Pt<_, _>, Pr<_>, Cell<_>);
83         c_long = Cell::new(1);
84         c_shortest = Cell::new(1);
85         // Error: Drop impl's assertion does not apply to `B` nor `&'b _`
86         pt = Pt("pt", &c_long, &c_shortest);
87         //~^ ERROR `c_shortest` does not live long enough
88         pr = Pr("pr", &c_long, &c_shortest);
89     }
90
91     {
92         let (st, sr, c_shortest): (St<_>, Sr<_>, Cell<_>);
93         c_shortest = Cell::new(1);
94         // No error: St and Sr have no destructor.
95         st = St("st", &c_shortest);
96         sr = Sr("sr", &c_shortest);
97     }
98 }
99
100 fn use_imm<T>(_: &T) { }