From e56d1cec341c3d0473fa00804aafa20566b55bbd Mon Sep 17 00:00:00 2001 From: Aaron Power Date: Tue, 9 Jan 2018 01:38:58 +0000 Subject: [PATCH 1/6] Update release notes for 1.24.0 --- RELEASES.md | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 8fcd22b0b448f..3077d31c282b1 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -1,3 +1,117 @@ +Version 1.24.0 (2018-02-15) +========================== + +Language +-------- +- [External `sysv64` ffi is now available.][46528] + eg. `extern "sysv64" fn foo () {}` + +Compiler +-------- +- [rustc now uses 16 codegen units by default for release builds.][46910] + For the fastest builds, utilize `codegen-units=1`. +- [Added `armv4t-unknown-linux-gnueabi` target.][47018] +- [Add `aarch64-unknown-openbsd` support][46760] + +Libraries +--------- +- [`str::find::` now uses memchr.][46735] This should lead to a 10x + improvement in performance in the majority of cases. +- [`OsStr`'s `Debug` implementation is now lossless and consistent + with Windows.][46798] +- [`time::{SystemTime, Instant}` now implement `Hash`.][46828] +- [impl `From` for `AtomicBool`][46293] +- [impl `From<{CString, &CStr}>` for `{Arc, Rc}`][45990] +- [impl `From<{OsString, &OsStr}>` for `{Arc, Rc}`][45990] +- [impl `From<{PathBuf, &Path}>` for `{Arc, Rc}`][45990] +- [float::from_bits now just uses transmute.][46012] This provides + some optimisations from LLVM. +- [Copied `AsciiExt` methods onto `char`][46077] +- [Remove `T: Sized` requirement on `ptr::is_null()`][46094] +- [impl `From` for `{TryRecvError, RecvTimeoutError}`][45506] +- [Optimised `f32::{min, max}` to generate more efficent x86 assembly][47080] +- [`[u8]::contains` now uses memchr which provides a 3x speed improvement][46713] + +Stabilized APIs +--------------- +- [`RefCell::replace`] +- [`RefCell::swap`] +- [`atomic::spin_loop_hint`] + +The following functions can now be used in a constant expression. +eg. `let buffer: [u8; size_of::()];`, `static COUNTER: AtomicUsize = AtomicUsize::new(1);` + +- [`AtomicBool::new`][46287] +- [`AtomicUsize::new`][46287] +- [`AtomicIsize::new`][46287] +- [`AtomicPtr::new`][46287] +- [`Cell::new`][46287] +- [`{integer}::min_value`][46287] +- [`{integer}::max_value`][46287] +- [`mem::size_of`][46287] +- [`mem::align_of`][46287] +- [`ptr::null`][46287] +- [`ptr::null_mut`][46287] +- [`RefCell::new`][46287] +- [`UnsafeCell::new`][46287] + +Cargo +----- +- [Added a `workspace.default-members` config that + overrides implied `--all` in virtual workspaces.][cargo/4743] +- [Enable incremental by default on development builds.][cargo/4817] Also added + configuration keys to `Cargo.toml` and `.cargo/config` to disable on a + per-project or global basis respectively. + +Misc +---- + +Compatibility Notes +------------------- +- [Floating point types `Debug` impl now always prints a decimal point.][46831] +- [`Ipv6Addr` now rejects superfluous `::`'s in IPv6 addresses][46671] This is + in accordance with IETF RFC 4291 ยง2.2. +- [Unwinding will no longer go past FFI boundaries, and will instead abort.][46833] +- [`Formatter::flags` method is now deprecated.][46284] The `sign_plus`, + `sign_minus`, `alternate`, and `sign_aware_zero_pad` should be used instead. +- [Leading zeros in tuple struct members is now an error][47084] +- [`column!()` macro is one-based instead of zero-based][46977] +- [`fmt::Arguments` can no longer be shared across threads][45198] +- [Access to `#[repr(packed)]` struct fields is now unsafe][44884] + +[44884]: https://github.com/rust-lang/rust/pull/44884 +[45198]: https://github.com/rust-lang/rust/pull/45198 +[45506]: https://github.com/rust-lang/rust/pull/45506 +[45904]: https://github.com/rust-lang/rust/pull/45904 +[45990]: https://github.com/rust-lang/rust/pull/45990 +[46012]: https://github.com/rust-lang/rust/pull/46012 +[46077]: https://github.com/rust-lang/rust/pull/46077 +[46094]: https://github.com/rust-lang/rust/pull/46094 +[46284]: https://github.com/rust-lang/rust/pull/46284 +[46287]: https://github.com/rust-lang/rust/pull/46287 +[46293]: https://github.com/rust-lang/rust/pull/46293 +[46528]: https://github.com/rust-lang/rust/pull/46528 +[46671]: https://github.com/rust-lang/rust/pull/46671 +[46713]: https://github.com/rust-lang/rust/pull/46713 +[46735]: https://github.com/rust-lang/rust/pull/46735 +[46749]: https://github.com/rust-lang/rust/pull/46749 +[46760]: https://github.com/rust-lang/rust/pull/46760 +[46798]: https://github.com/rust-lang/rust/pull/46798 +[46828]: https://github.com/rust-lang/rust/pull/46828 +[46831]: https://github.com/rust-lang/rust/pull/46831 +[46833]: https://github.com/rust-lang/rust/pull/46833 +[46910]: https://github.com/rust-lang/rust/pull/46910 +[46977]: https://github.com/rust-lang/rust/pull/46977 +[47018]: https://github.com/rust-lang/rust/pull/47018 +[47080]: https://github.com/rust-lang/rust/pull/47080 +[47084]: https://github.com/rust-lang/rust/pull/47084 +[cargo/4743]: https://github.com/rust-lang/cargo/pull/4743 +[cargo/4817]: https://github.com/rust-lang/cargo/pull/4817 +[`RefCell::replace`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.replace +[`RefCell::swap`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html#method.swap +[`atomic::spin_loop_hint`]: https://doc.rust-lang.org/std/sync/atomic/fn.spin_loop_hint.html + + Version 1.23.0 (2018-01-04) ========================== From 23773b717426a4ffadeffb732202c4bd56e3cfcb Mon Sep 17 00:00:00 2001 From: Onur Aslan Date: Mon, 5 Feb 2018 11:39:54 +0300 Subject: [PATCH 2/6] Use time crate in bootstrap dist instead of date --- src/Cargo.lock | 34 ++++++++++++++++++++++++++++++++++ src/bootstrap/Cargo.toml | 1 + src/bootstrap/dist.rs | 6 +++--- src/bootstrap/lib.rs | 1 + 4 files changed, 39 insertions(+), 3 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index a21ad12700b3b..56db3ad74a7f9 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -136,6 +136,7 @@ dependencies = [ "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "serde_derive 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", + "time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", "toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2583,6 +2584,16 @@ dependencies = [ name = "tidy" version = "0.1.0" +[[package]] +name = "time" +version = "0.1.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", + "redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "toml" version = "0.2.1" @@ -2739,11 +2750,30 @@ name = "winapi" version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "winapi-build" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "wincolor" version = "0.1.4" @@ -2980,6 +3010,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03" "checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5" "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963" +"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098" "checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4" "checksum toml 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a7540f4ffc193e0d3c94121edb19b055670d369f77d5804db11ae053a45b6e7e" "checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" @@ -3001,7 +3032,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff" "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" +"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" "checksum wincolor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a39ee4464208f6430992ff20154216ab2357772ac871d994c51628d60e58b8b0" "checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" "checksum xattr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "5f04de8a1346489a2f9e9bd8526b73d135ec554227b17568456e86aa35b6f3fc" diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index bbbbf0e191555..2d47834131784 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -41,3 +41,4 @@ serde_derive = "1.0.8" serde_json = "1.0.2" toml = "0.4" lazy_static = "0.2" +time = "0.1" diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 57f0cde574a71..f011069a700ee 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -33,6 +33,7 @@ use builder::{Builder, RunConfig, ShouldRun, Step}; use compile; use tool::{self, Tool}; use cache::{INTERNER, Interned}; +use time; pub fn pkgname(build: &Build, component: &str) -> String { if component == "cargo" { @@ -436,8 +437,7 @@ impl Step for Rustc { t!(fs::create_dir_all(image.join("share/man/man1"))); let man_src = build.src.join("src/doc/man"); let man_dst = image.join("share/man/man1"); - let date_output = output(Command::new("date").arg("+%B %Y")); - let month_year = date_output.trim(); + let month_year = t!(time::strftime("%B %Y", &time::now())); // don't use our `bootstrap::util::{copy, cp_r}`, because those try // to hardlink, and we don't want to edit the source templates for entry_result in t!(fs::read_dir(man_src)) { @@ -447,7 +447,7 @@ impl Step for Rustc { t!(fs::copy(&page_src, &page_dst)); // template in month/year and version number replace_in_file(&page_dst, - &[("", month_year), + &[("", &month_year), ("", channel::CFG_RELEASE_NUM)]); } diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index ae53c054e414b..63a9c3ab905de 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -130,6 +130,7 @@ extern crate cc; extern crate getopts; extern crate num_cpus; extern crate toml; +extern crate time; #[cfg(unix)] extern crate libc; From 6369d43efb4645d4ae19d0e2a7f0c45cbb4326b9 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Thu, 8 Feb 2018 17:15:41 +0200 Subject: [PATCH 3/6] rustc: don't ICE when using Rvalue::Discriminant on a non-ADT. --- src/librustc/mir/tcx.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs index 23f360d5c3922..c7b26d97da8f4 100644 --- a/src/librustc/mir/tcx.rs +++ b/src/librustc/mir/tcx.rs @@ -182,9 +182,8 @@ impl<'tcx> Rvalue<'tcx> { if let ty::TyAdt(adt_def, _) = ty.sty { adt_def.repr.discr_type().to_ty(tcx) } else { - // Undefined behaviour, bug for now; may want to return something for - // the `discriminant` intrinsic later. - bug!("Rvalue::Discriminant on Place of type {:?}", ty); + // This can only be `0`, for now, so `u8` will suffice. + tcx.types.u8 } } Rvalue::NullaryOp(NullOp::Box, t) => tcx.mk_box(t), From 3ed76978d2aab9de53756091a5f7ea32a0648a3e Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 9 Feb 2018 16:49:38 +0200 Subject: [PATCH 4/6] rustc_mir: insert a dummy access to places being matched on, when building MIR. --- src/librustc_mir/build/matches/mod.rs | 16 +++ .../borrowck/borrowck-describe-lvalue.rs | 28 ++--- .../borrowck-match-already-borrowed.rs | 4 +- src/test/compile-fail/issue-47412.rs | 31 +++++ src/test/mir-opt/match_false_edges.rs | 107 +++++++++--------- 5 files changed, 118 insertions(+), 68 deletions(-) create mode 100644 src/test/compile-fail/issue-47412.rs diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs index 6cb9217776648..6b0b5b0ab9e88 100644 --- a/src/librustc_mir/build/matches/mod.rs +++ b/src/librustc_mir/build/matches/mod.rs @@ -38,6 +38,22 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { -> BlockAnd<()> { let discriminant_place = unpack!(block = self.as_place(block, discriminant)); + // Matching on a `discriminant_place` with an uninhabited type doesn't + // generate any memory reads by itself, and so if the place "expression" + // contains unsafe operations like raw pointer dereferences or union + // field projections, we wouldn't know to require an `unsafe` block + // around a `match` equivalent to `std::intrinsics::unreachable()`. + // See issue #47412 for this hole being discovered in the wild. + // + // HACK(eddyb) Work around the above issue by adding a dummy inspection + // of `discriminant_place`, specifically by applying `Rvalue::Discriminant` + // (which will work regardless of type) and storing the result in a temp. + let dummy_source_info = self.source_info(span); + let dummy_access = Rvalue::Discriminant(discriminant_place.clone()); + let dummy_ty = dummy_access.ty(&self.local_decls, self.hir.tcx()); + let dummy_temp = self.temp(dummy_ty, dummy_source_info.span); + self.cfg.push_assign(block, dummy_source_info, &dummy_temp, dummy_access); + let mut arm_blocks = ArmBlocks { blocks: arms.iter() .map(|_| self.cfg.start_new_block()) diff --git a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs index 062cc976a3dc1..1d08b80746582 100644 --- a/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs +++ b/src/test/compile-fail/borrowck/borrowck-describe-lvalue.rs @@ -72,7 +72,7 @@ fn main() { { let mut e = Baz::X(2); let _e0 = e.x(); - match e { + match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed Baz::X(value) => value //[ast]~^ ERROR cannot use `e.0` because it was mutably borrowed //[mir]~^^ ERROR cannot use `e.0` because it was mutably borrowed @@ -110,7 +110,7 @@ fn main() { { let mut e = Box::new(Baz::X(3)); let _e0 = e.x(); - match *e { + match *e { //[mir]~ ERROR cannot use `*e` because it was mutably borrowed Baz::X(value) => value //[ast]~^ ERROR cannot use `e.0` because it was mutably borrowed //[mir]~^^ ERROR cannot use `e.0` because it was mutably borrowed @@ -127,25 +127,25 @@ fn main() { { let mut v = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; let _v = &mut v; - match v { + match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed &[x, _, .., _, _] => println!("{}", x), //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed _ => panic!("other case"), } - match v { + match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed &[_, x, .., _, _] => println!("{}", x), //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed _ => panic!("other case"), } - match v { + match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed &[_, _, .., x, _] => println!("{}", x), //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed _ => panic!("other case"), } - match v { + match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed &[_, _, .., _, x] => println!("{}", x), //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed @@ -156,25 +156,25 @@ fn main() { { let mut v = &[1, 2, 3, 4, 5]; let _v = &mut v; - match v { + match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed &[x..] => println!("{:?}", x), //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed _ => panic!("other case"), } - match v { + match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed &[_, x..] => println!("{:?}", x), //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed _ => panic!("other case"), } - match v { + match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed &[x.., _] => println!("{:?}", x), //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed _ => panic!("other case"), } - match v { + match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed &[_, x.., _] => println!("{:?}", x), //[ast]~^ ERROR cannot use `v[..]` because it was mutably borrowed //[mir]~^^ ERROR cannot use `v[..]` because it was mutably borrowed @@ -187,7 +187,7 @@ fn main() { let mut e = E::A(3); let _e = &mut e; - match e { + match e { //[mir]~ ERROR cannot use `e` because it was mutably borrowed E::A(ref ax) => //[ast]~^ ERROR cannot borrow `e.0` as immutable because `e` is also borrowed as mutable //[mir]~^^ ERROR cannot borrow `e.0` as immutable because it is also borrowed as mutable @@ -205,14 +205,14 @@ fn main() { struct S { x: F, y: (u32, u32), }; let mut s = S { x: F { x: 1, y: 2}, y: (999, 998) }; let _s = &mut s; - match s { + match s { //[mir]~ ERROR cannot use `s` because it was mutably borrowed S { y: (ref y0, _), .. } => //[ast]~^ ERROR cannot borrow `s.y.0` as immutable because `s` is also borrowed as mutable //[mir]~^^ ERROR cannot borrow `s.y.0` as immutable because it is also borrowed as mutable println!("y0: {:?}", y0), _ => panic!("other case"), } - match s { + match s { //[mir]~ ERROR cannot use `s` because it was mutably borrowed S { x: F { y: ref x0, .. }, .. } => //[ast]~^ ERROR cannot borrow `s.x.y` as immutable because `s` is also borrowed as mutable //[mir]~^^ ERROR cannot borrow `s.x.y` as immutable because it is also borrowed as mutable @@ -263,7 +263,7 @@ fn main() { struct F {x: u32, y: u32}; let mut v = &[F{x: 1, y: 2}, F{x: 3, y: 4}]; let _v = &mut v; - match v { + match v { //[mir]~ ERROR cannot use `v` because it was mutably borrowed &[_, F {x: ref xf, ..}] => println!("{}", xf), //[mir]~^ ERROR cannot borrow `v[..].x` as immutable because it is also borrowed as mutable // No errors in AST diff --git a/src/test/compile-fail/borrowck/borrowck-match-already-borrowed.rs b/src/test/compile-fail/borrowck/borrowck-match-already-borrowed.rs index 4336812af9b58..3e57ac0ca1910 100644 --- a/src/test/compile-fail/borrowck/borrowck-match-already-borrowed.rs +++ b/src/test/compile-fail/borrowck/borrowck-match-already-borrowed.rs @@ -19,7 +19,7 @@ enum Foo { fn match_enum() { let mut foo = Foo::B; let p = &mut foo; - let _ = match foo { + let _ = match foo { //[mir]~ ERROR [E0503] Foo::B => 1, //[mir]~ ERROR [E0503] _ => 2, Foo::A(x) => x //[ast]~ ERROR [E0503] @@ -31,7 +31,7 @@ fn match_enum() { fn main() { let mut x = 1; let _x = &mut x; - let _ = match x { + let _ = match x { //[mir]~ ERROR [E0503] x => x + 1, //[ast]~ ERROR [E0503] //[mir]~^ ERROR [E0503] y => y + 2, //[ast]~ ERROR [E0503] diff --git a/src/test/compile-fail/issue-47412.rs b/src/test/compile-fail/issue-47412.rs new file mode 100644 index 0000000000000..7481befcb7952 --- /dev/null +++ b/src/test/compile-fail/issue-47412.rs @@ -0,0 +1,31 @@ +// Copyright 2018 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. + +#[derive(Copy, Clone)] +enum Void {} + +// Tests that we detect unsafe places (specifically, union fields and +// raw pointer dereferences), even when they're matched on while having +// an uninhabited type (equivalent to `std::intrinsics::unreachable()`). + +fn union_field() { + union Union { unit: (), void: Void } + let u = Union { unit: () }; + match u.void {} + //~^ ERROR access to union field requires unsafe function or block +} + +fn raw_ptr_deref() { + let ptr = std::ptr::null::(); + match *ptr {} + //~^ ERROR dereference of raw pointer requires unsafe function or block +} + +fn main() {} diff --git a/src/test/mir-opt/match_false_edges.rs b/src/test/mir-opt/match_false_edges.rs index 1f892b0f9587a..ba1b54d59f69a 100644 --- a/src/test/mir-opt/match_false_edges.rs +++ b/src/test/mir-opt/match_false_edges.rs @@ -53,17 +53,18 @@ fn main() { // bb0: { // ... // _2 = std::option::Option::Some(const 42i32,); -// _5 = discriminant(_2); -// switchInt(move _5) -> [0isize: bb6, 1isize: bb4, otherwise: bb8]; +// _3 = discriminant(_2); +// _6 = discriminant(_2); +// switchInt(move _6) -> [0isize: bb6, 1isize: bb4, otherwise: bb8]; // } // bb1: { // resume; // } // bb2: { // arm1 -// StorageLive(_7); -// _7 = _3; -// _1 = (const 1i32, move _7); -// StorageDead(_7); +// StorageLive(_8); +// _8 = _4; +// _1 = (const 1i32, move _8); +// StorageDead(_8); // goto -> bb13; // } // bb3: { // binding3(empty) and arm3 @@ -86,24 +87,24 @@ fn main() { // unreachable; // } // bb9: { // binding1 and guard -// StorageLive(_3); -// _3 = ((_2 as Some).0: i32); -// StorageLive(_6); -// _6 = const guard() -> [return: bb10, unwind: bb1]; +// StorageLive(_4); +// _4 = ((_2 as Some).0: i32); +// StorageLive(_7); +// _7 = const guard() -> [return: bb10, unwind: bb1]; // } // bb10: { // end of guard -// switchInt(move _6) -> [0u8: bb11, otherwise: bb2]; +// switchInt(move _7) -> [0u8: bb11, otherwise: bb2]; // } // bb11: { // to pre_binding2 // falseEdges -> [real: bb5, imaginary: bb5]; // } // bb12: { // bindingNoLandingPads.before.mir2 and arm2 -// StorageLive(_4); -// _4 = ((_2 as Some).0: i32); -// StorageLive(_8); -// _8 = _4; -// _1 = (const 2i32, move _8); -// StorageDead(_8); +// StorageLive(_5); +// _5 = ((_2 as Some).0: i32); +// StorageLive(_9); +// _9 = _5; +// _1 = (const 2i32, move _9); +// StorageDead(_9); // goto -> bb13; // } // bb13: { @@ -116,17 +117,18 @@ fn main() { // bb0: { // ... // _2 = std::option::Option::Some(const 42i32,); -// _5 = discriminant(_2); -// switchInt(move _5) -> [0isize: bb5, 1isize: bb4, otherwise: bb8]; +// _3 = discriminant(_2); +// _6 = discriminant(_2); +// switchInt(move _6) -> [0isize: bb5, 1isize: bb4, otherwise: bb8]; // } // bb1: { // resume; // } // bb2: { // arm1 -// StorageLive(_7); -// _7 = _3; -// _1 = (const 1i32, move _7); -// StorageDead(_7); +// StorageLive(_8); +// _8 = _4; +// _1 = (const 1i32, move _8); +// StorageDead(_8); // goto -> bb13; // } // bb3: { // binding3(empty) and arm3 @@ -149,24 +151,24 @@ fn main() { // unreachable; // } // bb9: { // binding1 and guard -// StorageLive(_3); -// _3 = ((_2 as Some).0: i32); -// StorageLive(_6); -// _6 = const guard() -> [return: bb10, unwind: bb1]; +// StorageLive(_4); +// _4 = ((_2 as Some).0: i32); +// StorageLive(_7); +// _7 = const guard() -> [return: bb10, unwind: bb1]; // } // bb10: { // end of guard -// switchInt(move _6) -> [0u8: bb11, otherwise: bb2]; +// switchInt(move _7) -> [0u8: bb11, otherwise: bb2]; // } // bb11: { // to pre_binding2 // falseEdges -> [real: bb6, imaginary: bb5]; // } // bb12: { // binding2 and arm2 -// StorageLive(_4); -// _4 = ((_2 as Some).0: i32); -// StorageLive(_8); -// _8 = _4; -// _1 = (const 2i32, move _8); -// StorageDead(_8); +// StorageLive(_5); +// _5 = ((_2 as Some).0: i32); +// StorageLive(_9); +// _9 = _5; +// _1 = (const 2i32, move _9); +// StorageDead(_9); // goto -> bb13; // } // bb13: { @@ -179,8 +181,9 @@ fn main() { // bb0: { // ... // _2 = std::option::Option::Some(const 1i32,); -// _7 = discriminant(_2); -// switchInt(move _7) -> [1isize: bb4, otherwise: bb5]; +// _3 = discriminant(_2); +// _8 = discriminant(_2); +// switchInt(move _8) -> [1isize: bb4, otherwise: bb5]; // } // bb1: { // resume; @@ -210,41 +213,41 @@ fn main() { // unreachable; // } // bb9: { // binding1: Some(w) if guard() -// StorageLive(_3); -// _3 = ((_2 as Some).0: i32); -// StorageLive(_8); -// _8 = const guard() -> [return: bb10, unwind: bb1]; +// StorageLive(_4); +// _4 = ((_2 as Some).0: i32); +// StorageLive(_9); +// _9 = const guard() -> [return: bb10, unwind: bb1]; // } // bb10: { //end of guard -// switchInt(move _8) -> [0u8: bb11, otherwise: bb2]; +// switchInt(move _9) -> [0u8: bb11, otherwise: bb2]; // } // bb11: { // to pre_binding2 // falseEdges -> [real: bb5, imaginary: bb5]; // } // bb12: { // binding2 & arm2 -// StorageLive(_4); -// _4 = _2; +// StorageLive(_5); +// _5 = _2; // _1 = const 2i32; // goto -> bb17; // } // bb13: { // binding3: Some(y) if guard2(y) -// StorageLive(_5); -// _5 = ((_2 as Some).0: i32); -// StorageLive(_10); +// StorageLive(_6); +// _6 = ((_2 as Some).0: i32); // StorageLive(_11); -// _11 = _5; -// _10 = const guard2(move _11) -> [return: bb14, unwind: bb1]; +// StorageLive(_12); +// _12 = _6; +// _11 = const guard2(move _12) -> [return: bb14, unwind: bb1]; // } // bb14: { // end of guard2 -// StorageDead(_11); -// switchInt(move _10) -> [0u8: bb15, otherwise: bb3]; +// StorageDead(_12); +// switchInt(move _11) -> [0u8: bb15, otherwise: bb3]; // } // bb15: { // to pre_binding4 // falseEdges -> [real: bb7, imaginary: bb7]; // } // bb16: { // binding4 & arm4 -// StorageLive(_6); -// _6 = _2; +// StorageLive(_7); +// _7 = _2; // _1 = const 4i32; // goto -> bb17; // } From 8088e202b2e9fcc6aab63fb0b10781933ab520f3 Mon Sep 17 00:00:00 2001 From: kennytm Date: Mon, 12 Feb 2018 03:04:43 +0800 Subject: [PATCH 5/6] compiletest: Delete the executable immediately after running. This should save a lot of space on musl test cases (whose standard library are linked statically). --- src/tools/compiletest/src/runtest.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 25605cebba0d3..f6abf07f33d0c 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1255,7 +1255,7 @@ impl<'test> TestCx<'test> { fn exec_compiled_test(&self) -> ProcRes { let env = &self.props.exec_env; - match &*self.config.target { + let proc_res = match &*self.config.target { // This is pretty similar to below, we're transforming: // // program arg1 arg2 @@ -1310,7 +1310,13 @@ impl<'test> TestCx<'test> { None, ) } - } + }; + + // delete the executable after running it to save space. + // it is ok if the deletion failed. + let _ = fs::remove_file(self.make_exe_name()); + + proc_res } /// For each `aux-build: foo/bar` annotation, we check to find the From 17d0d6a8b35241cd8d393ca746399a8cb6b6051a Mon Sep 17 00:00:00 2001 From: Mark Simulacrum Date: Sun, 11 Feb 2018 16:27:33 -0700 Subject: [PATCH 6/6] Delete executables if the test ran successfully. This isn't a perfect heuristic, but since the amount of run-fail tests is far lower than run-pass tests for now, it should be sufficient to ensure that we don't run into CI limits. This makes it possible to run the test binary manually (e.g., under gdb/lldb) if it failed to attempt to find out why. --- src/tools/compiletest/src/runtest.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index f6abf07f33d0c..7612b2d6e810e 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1312,9 +1312,11 @@ impl<'test> TestCx<'test> { } }; - // delete the executable after running it to save space. - // it is ok if the deletion failed. - let _ = fs::remove_file(self.make_exe_name()); + if proc_res.status.success() { + // delete the executable after running it to save space. + // it is ok if the deletion failed. + let _ = fs::remove_file(self.make_exe_name()); + } proc_res }