]> git.lizzy.rs Git - rust.git/blob - tests/ui/span/dropck_direct_cycle_with_drop.rs
Rollup merge of #106441 - mllken:abstract-socket-noref, r=joshtriplett
[rust.git] / tests / ui / span / dropck_direct_cycle_with_drop.rs
1 // A simple example of an unsound mixing of cyclic structure and Drop.
2 //
3 // Each `D` has a name and an optional reference to another `D`
4 // sibling, but also implements a drop method that prints out its own
5 // name as well as the name of its sibling.
6 //
7 // By setting up a cyclic structure, the drop code cannot possibly
8 // work. Therefore this code must be rejected.
9 //
10 // (As it turns out, essentially any attempt to install a sibling here
11 //  will be rejected, regardless of whether it forms a cyclic
12 //  structure or not. This is because the use of the same lifetime
13 //  `'a` in `&'a D<'a>` cannot be satisfied when `D<'a>` implements
14 //  `Drop`.)
15
16 use std::cell::Cell;
17
18 struct D<'a> {
19     name: String,
20     p: Cell<Option<&'a D<'a>>>,
21 }
22
23 impl<'a> D<'a> {
24     fn new(name: String) -> D<'a> { D { name: name, p: Cell::new(None) } }
25 }
26
27 impl<'a> Drop for D<'a> {
28     fn drop(&mut self) {
29         println!("dropping {} whose sibling is {:?}",
30                  self.name, self.p.get().map(|d| &d.name));
31     }
32 }
33
34 fn g() {
35     let (d1, d2) = (D::new(format!("d1")), D::new(format!("d2")));
36     d1.p.set(Some(&d2));
37     //~^ ERROR `d2` does not live long enough
38     d2.p.set(Some(&d1));
39     //~^ ERROR `d1` does not live long enough
40 }
41
42 fn main() {
43     g();
44 }