1 // Issue 34101: Circa 2016-06-05, `fn inline` below issued an
2 // erroneous warning from the elaborate_drops pass about moving out of
3 // a field in `Foo`, which has a destructor (and thus cannot have
4 // content moved out of it). The reason that the warning is erroneous
5 // in this case is that we are doing a *replace*, not a move, of the
6 // content in question, and it is okay to replace fields within `Foo`.
7 //
8 // Another more subtle problem was that the elaborate_drops was
9 // creating a separate drop flag for that internally replaced content,
10 // even though the compiler should enforce an invariant that any drop
11 // flag for such subcontent of `Foo` will always have the same value
12 // as the drop flag for `Foo` itself.
13 
14 
15 
16 
17 
18 
19 
20 
21 // check-pass
22 
23 struct Foo(String);
24 
25 impl Drop for Foo {
drop(&mut self)26     fn drop(&mut self) {}
27 }
28 
inline()29 fn inline() {
30     // (dummy variable so `f` gets assigned `var1` in MIR for both fn's)
31     let _s = ();
32     let mut f = Foo(String::from("foo"));
33     f.0 = String::from("bar");
34 }
35 
outline()36 fn outline() {
37     let _s = String::from("foo");
38     let mut f = Foo(_s);
39     f.0 = String::from("bar");
40 }
41 
42 
main()43 fn main() {
44     inline();
45     outline();
46 }
47