From 50132c4ae36fe6fb0124c44700ce0cb576bf7e15 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Tue, 10 Dec 2019 23:32:52 -0800 Subject: [PATCH 1/8] Fix up Command Debug output when arg0 is specified. PR https://github.com/rust-lang/rust/pull/66512 added the ability to set argv[0] on Command. As a side effect, it changed the Debug output to print both the program and argv[0], which in practice results in stuttery output ("echo echo foo"). This PR reverts the behaviour to the the old one, so that the command is only printed once - unless arg0 has been set. In that case it emits "[command] arg0 arg1 ...". --- src/libstd/sys/unix/process/process_common.rs | 8 +++++-- src/test/ui/command-argv0-debug.rs | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/command-argv0-debug.rs diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index c9109b0c9d4d7..e66d6fdc56ac6 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -375,8 +375,12 @@ impl ChildStdio { impl fmt::Debug for Command { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{:?}", self.program)?; - for arg in &self.args { + if self.program != self.args[0] { + write!(f, "[{:?}] ", self.program)?; + } + write!(f, "{:?}", self.args[0])?; + + for arg in &self.args[1..] { write!(f, " {:?}", arg)?; } Ok(()) diff --git a/src/test/ui/command-argv0-debug.rs b/src/test/ui/command-argv0-debug.rs new file mode 100644 index 0000000000000..133d2ada2b263 --- /dev/null +++ b/src/test/ui/command-argv0-debug.rs @@ -0,0 +1,24 @@ +// run-pass + +// ignore-windows - this is a unix-specific test +// ignore-cloudabi no processes +// ignore-emscripten no processes +// ignore-sgx no processes +#![feature(process_set_argv0)] + +use std::os::unix::process::CommandExt; +use std::process::Command; + +fn main() { + let mut command = Command::new("some-boring-name"); + + assert_eq!(format!("{:?}", command), r#""some-boring-name""#); + + command.args(&["1", "2", "3"]); + + assert_eq!(format!("{:?}", command), r#""some-boring-name" "1" "2" "3""#); + + command.arg0("exciting-name"); + + assert_eq!(format!("{:?}", command), r#"["some-boring-name"] "exciting-name" "1" "2" "3""#); +} From 9efb92de719707fc3d6f7b50c7b15d705a300084 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 11 Dec 2019 21:39:57 -0800 Subject: [PATCH 2/8] Move command-related tests into command/ --- src/test/ui/{ => command}/command-argv0-debug.rs | 0 src/test/ui/{ => command}/command-argv0.rs | 0 src/test/ui/{ => command}/command-exec.rs | 0 src/test/ui/{ => command}/command-pre-exec.rs | 0 src/test/ui/{ => command}/command-uid-gid.rs | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename src/test/ui/{ => command}/command-argv0-debug.rs (100%) rename src/test/ui/{ => command}/command-argv0.rs (100%) rename src/test/ui/{ => command}/command-exec.rs (100%) rename src/test/ui/{ => command}/command-pre-exec.rs (100%) rename src/test/ui/{ => command}/command-uid-gid.rs (100%) diff --git a/src/test/ui/command-argv0-debug.rs b/src/test/ui/command/command-argv0-debug.rs similarity index 100% rename from src/test/ui/command-argv0-debug.rs rename to src/test/ui/command/command-argv0-debug.rs diff --git a/src/test/ui/command-argv0.rs b/src/test/ui/command/command-argv0.rs similarity index 100% rename from src/test/ui/command-argv0.rs rename to src/test/ui/command/command-argv0.rs diff --git a/src/test/ui/command-exec.rs b/src/test/ui/command/command-exec.rs similarity index 100% rename from src/test/ui/command-exec.rs rename to src/test/ui/command/command-exec.rs diff --git a/src/test/ui/command-pre-exec.rs b/src/test/ui/command/command-pre-exec.rs similarity index 100% rename from src/test/ui/command-pre-exec.rs rename to src/test/ui/command/command-pre-exec.rs diff --git a/src/test/ui/command-uid-gid.rs b/src/test/ui/command/command-uid-gid.rs similarity index 100% rename from src/test/ui/command-uid-gid.rs rename to src/test/ui/command/command-uid-gid.rs From 72b9452a4e82320f8f16375efa43f521e74860ee Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Sun, 15 Dec 2019 11:08:43 +0000 Subject: [PATCH 3/8] Don't suppress move errors for union fields --- .../dataflow/move_paths/builder.rs | 31 +++++++++++++------ .../move-from-union-field-issue-66500.rs | 30 ++++++++++++++++++ .../move-from-union-field-issue-66500.stderr | 27 ++++++++++++++++ 3 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 src/test/ui/borrowck/move-from-union-field-issue-66500.rs create mode 100644 src/test/ui/borrowck/move-from-union-field-issue-66500.stderr diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs index fa0864e0de760..971e9a1b3b281 100644 --- a/src/librustc_mir/dataflow/move_paths/builder.rs +++ b/src/librustc_mir/dataflow/move_paths/builder.rs @@ -103,6 +103,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { } }; + // The move path index of the first union that we find. Once this is + // some we stop creating child move paths, since moves from unions + // move the whole thing. + // We continue looking for other move errors though so that moving + // from `*(u.f: &_)` isn't allowed. + let mut union_path = None; + for (i, elem) in place.projection.iter().enumerate() { let proj_base = &place.projection[..i]; let body = self.builder.body; @@ -127,9 +134,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { InteriorOfTypeWithDestructor { container_ty: place_ty }, )); } - // move out of union - always move the entire union ty::Adt(adt, _) if adt.is_union() => { - return Err(MoveError::UnionMove { path: base }); + union_path.get_or_insert(base); } ty::Slice(_) => { return Err(MoveError::cannot_move_out_of( @@ -155,15 +161,22 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> { _ => {} }; - base = self.add_move_path(base, elem, |tcx| { - Place { - base: place.base.clone(), - projection: tcx.intern_place_elems(&place.projection[..i+1]), - } - }); + if union_path.is_none() { + base = self.add_move_path(base, elem, |tcx| { + Place { + base: place.base.clone(), + projection: tcx.intern_place_elems(&place.projection[..i+1]), + } + }); + } } - Ok(base) + if let Some(base) = union_path { + // Move out of union - always move the entire union. + Err(MoveError::UnionMove { path: base }) + } else { + Ok(base) + } } fn add_move_path( diff --git a/src/test/ui/borrowck/move-from-union-field-issue-66500.rs b/src/test/ui/borrowck/move-from-union-field-issue-66500.rs new file mode 100644 index 0000000000000..8fbf120fc1c78 --- /dev/null +++ b/src/test/ui/borrowck/move-from-union-field-issue-66500.rs @@ -0,0 +1,30 @@ +// Moving from a reference/raw pointer should be an error, even when they're +// the field of a union. + +#![feature(untagged_unions)] + +union Pointers { + a: &'static String, + b: &'static mut String, + c: *const String, + d: *mut String, +} + +unsafe fn move_ref(u: Pointers) -> String { + *u.a + //~^ ERROR cannot move out of `*u.a` +} +unsafe fn move_ref_mut(u: Pointers) -> String { + *u.b + //~^ ERROR cannot move out of `*u.b` +} +unsafe fn move_ptr(u: Pointers) -> String { + *u.c + //~^ ERROR cannot move out of `*u.c` +} +unsafe fn move_ptr_mut(u: Pointers) -> String { + *u.d + //~^ ERROR cannot move out of `*u.d` +} + +fn main() {} diff --git a/src/test/ui/borrowck/move-from-union-field-issue-66500.stderr b/src/test/ui/borrowck/move-from-union-field-issue-66500.stderr new file mode 100644 index 0000000000000..a7cb1c9e22135 --- /dev/null +++ b/src/test/ui/borrowck/move-from-union-field-issue-66500.stderr @@ -0,0 +1,27 @@ +error[E0507]: cannot move out of `*u.a` which is behind a shared reference + --> $DIR/move-from-union-field-issue-66500.rs:14:5 + | +LL | *u.a + | ^^^^ move occurs because `*u.a` has type `std::string::String`, which does not implement the `Copy` trait + +error[E0507]: cannot move out of `*u.b` which is behind a mutable reference + --> $DIR/move-from-union-field-issue-66500.rs:18:5 + | +LL | *u.b + | ^^^^ move occurs because `*u.b` has type `std::string::String`, which does not implement the `Copy` trait + +error[E0507]: cannot move out of `*u.c` which is behind a raw pointer + --> $DIR/move-from-union-field-issue-66500.rs:22:5 + | +LL | *u.c + | ^^^^ move occurs because `*u.c` has type `std::string::String`, which does not implement the `Copy` trait + +error[E0507]: cannot move out of `*u.d` which is behind a raw pointer + --> $DIR/move-from-union-field-issue-66500.rs:26:5 + | +LL | *u.d + | ^^^^ move occurs because `*u.d` has type `std::string::String`, which does not implement the `Copy` trait + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0507`. From 03436b7d01284e2fb219328d2ff4a9cebd572b7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Wed, 18 Dec 2019 22:48:24 +0100 Subject: [PATCH 4/8] Reenable static linking of libstdc++ on windows-gnu --- src/bootstrap/compile.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index baf9aabed00af..831053bc0f7e2 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -563,7 +563,7 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: Interne // not for MSVC or macOS if builder.config.llvm_static_stdcpp && !target.contains("freebsd") && - !target.contains("windows") && + !target.contains("msvc") && !target.contains("apple") { let file = compiler_file(builder, builder.cxx(target).unwrap(), From 7c4f9132e761e2fea099cb42f0930c2f114af920 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Wed, 25 Dec 2019 21:09:51 +0000 Subject: [PATCH 5/8] Use the correct type for static qualifs --- .../transform/check_consts/qualifs.rs | 16 ++++++++-------- src/test/ui/consts/const-eval/promote-static.rs | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 src/test/ui/consts/const-eval/promote-static.rs diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs index 223a5f8d605fc..56acd736f10cf 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -33,12 +33,6 @@ pub trait Qualif { /// of the type. fn in_any_value_of_ty(_cx: &ConstCx<'_, 'tcx>, _ty: Ty<'tcx>) -> bool; - fn in_static(cx: &ConstCx<'_, 'tcx>, def_id: DefId) -> bool { - // `mir_const_qualif` does return the qualifs in the final value of a `static`, so we could - // use value-based qualification here, but we shouldn't do this without a good reason. - Self::in_any_value_of_ty(cx, cx.tcx.type_of(def_id)) - } - fn in_projection_structurally( cx: &ConstCx<'_, 'tcx>, per_local: &impl Fn(Local) -> bool, @@ -108,8 +102,14 @@ pub trait Qualif { Operand::Move(ref place) => Self::in_place(cx, per_local, place.as_ref()), Operand::Constant(ref constant) => { - if let Some(static_) = constant.check_static_ptr(cx.tcx) { - Self::in_static(cx, static_) + if constant.check_static_ptr(cx.tcx).is_some() { + // `mir_const_qualif` does return the qualifs in the final value of a `static`, + // so we could use value-based qualification here, but we shouldn't do this + // without a good reason. + // + // Note: this uses `constant.literal.ty` which is a reference or pointer to the + // type of the actual `static` item. + Self::in_any_value_of_ty(cx, constant.literal.ty) } else if let ty::ConstKind::Unevaluated(def_id, _) = constant.literal.val { // Don't peek inside trait associated constants. if cx.tcx.trait_of_item(def_id).is_some() { diff --git a/src/test/ui/consts/const-eval/promote-static.rs b/src/test/ui/consts/const-eval/promote-static.rs new file mode 100644 index 0000000000000..d3c663c53e905 --- /dev/null +++ b/src/test/ui/consts/const-eval/promote-static.rs @@ -0,0 +1,14 @@ +// regression test for #67609. + +// check-pass + +static NONE: Option = None; + +static NONE_REF_REF: &&Option = { + let x = &&NONE; + x +}; + +fn main() { + println!("{:?}", NONE_REF_REF); +} From e7809333730bbdbe9264beff84a1a38df3e16062 Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Thu, 26 Dec 2019 14:50:40 +0100 Subject: [PATCH 6/8] Treat extern statics just like statics in the "const pointer to static" representation --- src/librustc/ty/util.rs | 2 - .../mir-opt/const-promotion-extern-static.rs | 71 +++++++++++++++++++ 2 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 src/test/mir-opt/const-promotion-extern-static.rs diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 0b11a9efd81d7..2b83cecf1ed43 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -692,8 +692,6 @@ impl<'tcx> TyCtxt<'tcx> { if self.is_mutable_static(def_id) { self.mk_mut_ptr(static_ty) - } else if self.is_foreign_item(def_id) { - self.mk_imm_ptr(static_ty) } else { self.mk_imm_ref(self.lifetimes.re_erased, static_ty) } diff --git a/src/test/mir-opt/const-promotion-extern-static.rs b/src/test/mir-opt/const-promotion-extern-static.rs new file mode 100644 index 0000000000000..d611ec22c38ec --- /dev/null +++ b/src/test/mir-opt/const-promotion-extern-static.rs @@ -0,0 +1,71 @@ +extern "C" { + static X: i32; +} + +static Y: i32 = 42; + +static mut BAR: *const &'static i32 = [&Y].as_ptr(); + +static mut FOO: *const &'static i32 = [unsafe { &X }].as_ptr(); + +fn main() {} + +// END RUST SOURCE +// START rustc.FOO.PromoteTemps.before.mir +// bb0: { +// ... +// _5 = const Scalar(AllocId(1).0x0) : &i32; +// _4 = &(*_5); +// _3 = [move _4]; +// _2 = &_3; +// _1 = move _2 as &[&'static i32] (Pointer(Unsize)); +// _0 = const core::slice::::as_ptr(move _1) -> [return: bb2, unwind: bb1]; +// } +// ... +// bb2: { +// StorageDead(_5); +// StorageDead(_3); +// return; +// } +// END rustc.FOO.PromoteTemps.before.mir +// START rustc.BAR.PromoteTemps.before.mir +// bb0: { +// ... +// _5 = const Scalar(AllocId(0).0x0) : &i32; +// _4 = &(*_5); +// _3 = [move _4]; +// _2 = &_3; +// _1 = move _2 as &[&'static i32] (Pointer(Unsize)); +// _0 = const core::slice::::as_ptr(move _1) -> [return: bb2, unwind: bb1]; +// } +// ... +// bb2: { +// StorageDead(_5); +// StorageDead(_3); +// return; +// } +// END rustc.BAR.PromoteTemps.before.mir +// START rustc.BAR.PromoteTemps.after.mir +// bb0: { +// ... +// _2 = &(promoted[0]: [&'static i32; 1]); +// _1 = move _2 as &[&'static i32] (Pointer(Unsize)); +// _0 = const core::slice::::as_ptr(move _1) -> [return: bb2, unwind: bb1]; +// } +// ... +// bb2: { +// return; +// } +// END rustc.BAR.PromoteTemps.after.mir +// START rustc.FOO.PromoteTemps.after.mir +// bb0: { +// ... +// _2 = &(promoted[0]: [&'static i32; 1]); +// _1 = move _2 as &[&'static i32] (Pointer(Unsize)); +// _0 = const core::slice::::as_ptr(move _1) -> [return: bb2, unwind: bb1]; +// } +// ... +// bb2: { +// return; +// } +// END rustc.FOO.PromoteTemps.after.mir From 097240b1103e80e1e7228448e1330ec1c309a538 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 28 Dec 2019 13:51:29 -0800 Subject: [PATCH 7/8] Do not ICE on lifetime error involving closures --- .../diagnostics/conflict_errors.rs | 22 +++++++++++++++++-- ...ure-doesnt-life-long-enough-issue-67634.rs | 3 +++ ...doesnt-life-long-enough-issue-67634.stderr | 15 +++++++++++++ 3 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs create mode 100644 src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs index 1cd43d4fdd411..d2aaee4d20fb5 100644 --- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs +++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs @@ -951,9 +951,27 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.span_label( drop_span, format!( - "...but `{}` will be dropped here, when the function `{}` returns", + "...but `{}` will be dropped here, when the {} returns", name, - self.infcx.tcx.hir().name(fn_hir_id), + self.infcx + .tcx + .hir() + .opt_name(fn_hir_id) + .map(|name| format!("function `{}`", name)) + .unwrap_or_else(|| { + match &self + .infcx + .tcx + .typeck_tables_of(self.mir_def_id) + .node_type(fn_hir_id) + .kind + { + ty::Closure(..) => "enclosing closure", + ty::Generator(..) => "enclosing generator", + kind => bug!("expected closure or generator, found {:?}", kind), + } + .to_string() + }) ), ); diff --git a/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs b/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs new file mode 100644 index 0000000000000..19d7f0190479e --- /dev/null +++ b/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.rs @@ -0,0 +1,3 @@ +fn main() { + [0].iter().flat_map(|a| [0].iter().map(|_| &a)); //~ ERROR `a` does not live long enough +} diff --git a/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr b/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr new file mode 100644 index 0000000000000..cb0b481e74876 --- /dev/null +++ b/src/test/ui/lifetimes/unnamed-closure-doesnt-life-long-enough-issue-67634.stderr @@ -0,0 +1,15 @@ +error[E0597]: `a` does not live long enough + --> $DIR/unnamed-closure-doesnt-life-long-enough-issue-67634.rs:2:49 + | +LL | [0].iter().flat_map(|a| [0].iter().map(|_| &a)); + | - ^- ...but `a` will be dropped here, when the enclosing closure returns + | | | + | | `a` would have to be valid for `'_`... + | has type `&i32` + | + = note: functions cannot return a borrow to data owned within the function's scope, functions can only return borrows to data passed as arguments + = note: to learn more, visit + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0597`. From 289cd177abd3af63748b602530f10bafd9a747a7 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 13 Jan 2020 22:42:58 +0100 Subject: [PATCH 8/8] Fix rebase damage --- src/librustc_mir/transform/check_consts/qualifs.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc_mir/transform/check_consts/qualifs.rs b/src/librustc_mir/transform/check_consts/qualifs.rs index 56acd736f10cf..1f58a05302589 100644 --- a/src/librustc_mir/transform/check_consts/qualifs.rs +++ b/src/librustc_mir/transform/check_consts/qualifs.rs @@ -2,7 +2,6 @@ use rustc::mir::*; use rustc::ty::{self, Ty}; -use rustc::hir::def_id::DefId; use syntax_pos::DUMMY_SP; use super::Item as ConstCx;