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