From 32d0dbd49a372b9d2e000587497de6ffca9e1cca Mon Sep 17 00:00:00 2001 From: Kevin Butler Date: Fri, 14 Nov 2014 15:14:52 -0800 Subject: librustc: Forbid partial reinitialization of uninitialized structures or enumerations that implement the `Drop` trait. This breaks code like: struct Struct { f: String, g: String, } impl Drop for Struct { ... } fn main() { let x = Struct { ... }; drop(x); x.f = ...; } Change this code to not create partially-initialized structures. For example: struct Struct { f: String, g: String, } impl Drop for Struct { ... } fn main() { let x = Struct { ... }; drop(x); x = Struct { f: ..., g: ..., } } Closes #18571. [breaking-change] ---- (Joint authorship by pcwalton and Ryman; thanks all!) --- src/test/compile-fail/borrowck-partial-reinit-1.rs | 49 ++++++++++++++++++++++ src/test/compile-fail/borrowck-partial-reinit-2.rs | 34 +++++++++++++++ src/test/compile-fail/borrowck-partial-reinit-3.rs | 22 ++++++++++ src/test/compile-fail/borrowck-partial-reinit-4.rs | 33 +++++++++++++++ 4 files changed, 138 insertions(+) create mode 100644 src/test/compile-fail/borrowck-partial-reinit-1.rs create mode 100644 src/test/compile-fail/borrowck-partial-reinit-2.rs create mode 100644 src/test/compile-fail/borrowck-partial-reinit-3.rs create mode 100644 src/test/compile-fail/borrowck-partial-reinit-4.rs (limited to 'src/test') diff --git a/src/test/compile-fail/borrowck-partial-reinit-1.rs b/src/test/compile-fail/borrowck-partial-reinit-1.rs new file mode 100644 index 00000000000..1ee040a0705 --- /dev/null +++ b/src/test/compile-fail/borrowck-partial-reinit-1.rs @@ -0,0 +1,49 @@ +// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Test; + +struct Test2 { + b: Option, +} + +struct Test3(Option); + +impl Drop for Test { + fn drop(&mut self) { + println!("dropping!"); + } +} + +impl Drop for Test2 { + fn drop(&mut self) {} +} + +impl Drop for Test3 { + fn drop(&mut self) {} +} + +fn stuff() { + let mut t = Test2 { b: None }; + let u = Test; + drop(t); + t.b = Some(u); + //~^ ERROR partial reinitialization of uninitialized structure `t` + + let mut t = Test3(None); + let u = Test; + drop(t); + t.0 = Some(u); + //~^ ERROR partial reinitialization of uninitialized structure `t` +} + +fn main() { + stuff() +} diff --git a/src/test/compile-fail/borrowck-partial-reinit-2.rs b/src/test/compile-fail/borrowck-partial-reinit-2.rs new file mode 100644 index 00000000000..0926ba6e432 --- /dev/null +++ b/src/test/compile-fail/borrowck-partial-reinit-2.rs @@ -0,0 +1,34 @@ +// Copyright 2014-2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Test { + a: isize, + b: Option>, +} + +impl Drop for Test { + fn drop(&mut self) { + println!("Dropping {}", self.a); + } +} + +fn stuff() { + let mut t = Test { a: 1, b: None}; + let mut u = Test { a: 2, b: Some(Box::new(t))}; + t.b = Some(Box::new(u)); + //~^ ERROR partial reinitialization of uninitialized structure `t` + println!("done"); +} + +fn main() { + stuff(); + println!("Hello, world!") +} + diff --git a/src/test/compile-fail/borrowck-partial-reinit-3.rs b/src/test/compile-fail/borrowck-partial-reinit-3.rs new file mode 100644 index 00000000000..0aa73892b82 --- /dev/null +++ b/src/test/compile-fail/borrowck-partial-reinit-3.rs @@ -0,0 +1,22 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. +use std::mem; + +struct Test { f: usize } +impl Drop for Test { + fn drop(&mut self) {} +} + +fn main() { + let mut x = (Test { f: 2 }, Test { f: 4 }); + mem::drop(x.0); + x.0.f = 3; + //~^ ERROR partial reinitialization of uninitialized structure `x.0` +} diff --git a/src/test/compile-fail/borrowck-partial-reinit-4.rs b/src/test/compile-fail/borrowck-partial-reinit-4.rs new file mode 100644 index 00000000000..774e04ecb29 --- /dev/null +++ b/src/test/compile-fail/borrowck-partial-reinit-4.rs @@ -0,0 +1,33 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +struct Test; + +struct Test2(Option); + +impl Drop for Test { + fn drop(&mut self) { + println!("dropping!"); + } +} + +impl Drop for Test2 { + fn drop(&mut self) {} +} + +fn stuff() { + let mut x : (Test2, Test2); + (x.0).0 = Some(Test); + //~^ ERROR partial reinitialization of uninitialized structure `x.0` +} + +fn main() { + stuff() +} -- cgit 1.4.1-3-g733a5