Skip to content

Commit 965ce16

Browse files
committed
Auto merge of #68189 - jonas-schievink:beta-next, r=Mark-Simulacrum
[Beta] Backports I did not include #67134 and #67289 since they seem to be on beta already. * Fix up Command Debug output when arg0 is specified. #67219 * Do not ICE on unnamed future #67289 * Don't suppress move errors for union fields #67314 * Reenable static linking of libstdc++ on windows-gnu #67410 * Use the correct type for static qualifs #67621 * Treat extern statics just like statics in the "const pointer to static" representation #67630 * Do not ICE on lifetime error involving closures #67687
2 parents eb3f7c2 + 289cd17 commit 965ce16

17 files changed

+241
-25
lines changed

src/bootstrap/compile.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: Interne
563563
// not for MSVC or macOS
564564
if builder.config.llvm_static_stdcpp &&
565565
!target.contains("freebsd") &&
566-
!target.contains("windows") &&
566+
!target.contains("msvc") &&
567567
!target.contains("apple") {
568568
let file = compiler_file(builder,
569569
builder.cxx(target).unwrap(),

src/librustc/ty/util.rs

-2
Original file line numberDiff line numberDiff line change
@@ -692,8 +692,6 @@ impl<'tcx> TyCtxt<'tcx> {
692692

693693
if self.is_mutable_static(def_id) {
694694
self.mk_mut_ptr(static_ty)
695-
} else if self.is_foreign_item(def_id) {
696-
self.mk_imm_ptr(static_ty)
697695
} else {
698696
self.mk_imm_ref(self.lifetimes.re_erased, static_ty)
699697
}

src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -951,9 +951,27 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
951951
err.span_label(
952952
drop_span,
953953
format!(
954-
"...but `{}` will be dropped here, when the function `{}` returns",
954+
"...but `{}` will be dropped here, when the {} returns",
955955
name,
956-
self.infcx.tcx.hir().name(fn_hir_id),
956+
self.infcx
957+
.tcx
958+
.hir()
959+
.opt_name(fn_hir_id)
960+
.map(|name| format!("function `{}`", name))
961+
.unwrap_or_else(|| {
962+
match &self
963+
.infcx
964+
.tcx
965+
.typeck_tables_of(self.mir_def_id)
966+
.node_type(fn_hir_id)
967+
.kind
968+
{
969+
ty::Closure(..) => "enclosing closure",
970+
ty::Generator(..) => "enclosing generator",
971+
kind => bug!("expected closure or generator, found {:?}", kind),
972+
}
973+
.to_string()
974+
})
957975
),
958976
);
959977

src/librustc_mir/dataflow/move_paths/builder.rs

+22-9
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
103103
}
104104
};
105105

106+
// The move path index of the first union that we find. Once this is
107+
// some we stop creating child move paths, since moves from unions
108+
// move the whole thing.
109+
// We continue looking for other move errors though so that moving
110+
// from `*(u.f: &_)` isn't allowed.
111+
let mut union_path = None;
112+
106113
for (i, elem) in place.projection.iter().enumerate() {
107114
let proj_base = &place.projection[..i];
108115
let body = self.builder.body;
@@ -127,9 +134,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
127134
InteriorOfTypeWithDestructor { container_ty: place_ty },
128135
));
129136
}
130-
// move out of union - always move the entire union
131137
ty::Adt(adt, _) if adt.is_union() => {
132-
return Err(MoveError::UnionMove { path: base });
138+
union_path.get_or_insert(base);
133139
}
134140
ty::Slice(_) => {
135141
return Err(MoveError::cannot_move_out_of(
@@ -155,15 +161,22 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
155161
_ => {}
156162
};
157163

158-
base = self.add_move_path(base, elem, |tcx| {
159-
Place {
160-
base: place.base.clone(),
161-
projection: tcx.intern_place_elems(&place.projection[..i+1]),
162-
}
163-
});
164+
if union_path.is_none() {
165+
base = self.add_move_path(base, elem, |tcx| {
166+
Place {
167+
base: place.base.clone(),
168+
projection: tcx.intern_place_elems(&place.projection[..i+1]),
169+
}
170+
});
171+
}
164172
}
165173

166-
Ok(base)
174+
if let Some(base) = union_path {
175+
// Move out of union - always move the entire union.
176+
Err(MoveError::UnionMove { path: base })
177+
} else {
178+
Ok(base)
179+
}
167180
}
168181

169182
fn add_move_path(

src/librustc_mir/transform/check_consts/qualifs.rs

+8-9
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
33
use rustc::mir::*;
44
use rustc::ty::{self, Ty};
5-
use rustc::hir::def_id::DefId;
65
use syntax_pos::DUMMY_SP;
76

87
use super::Item as ConstCx;
@@ -33,12 +32,6 @@ pub trait Qualif {
3332
/// of the type.
3433
fn in_any_value_of_ty(_cx: &ConstCx<'_, 'tcx>, _ty: Ty<'tcx>) -> bool;
3534

36-
fn in_static(cx: &ConstCx<'_, 'tcx>, def_id: DefId) -> bool {
37-
// `mir_const_qualif` does return the qualifs in the final value of a `static`, so we could
38-
// use value-based qualification here, but we shouldn't do this without a good reason.
39-
Self::in_any_value_of_ty(cx, cx.tcx.type_of(def_id))
40-
}
41-
4235
fn in_projection_structurally(
4336
cx: &ConstCx<'_, 'tcx>,
4437
per_local: &impl Fn(Local) -> bool,
@@ -108,8 +101,14 @@ pub trait Qualif {
108101
Operand::Move(ref place) => Self::in_place(cx, per_local, place.as_ref()),
109102

110103
Operand::Constant(ref constant) => {
111-
if let Some(static_) = constant.check_static_ptr(cx.tcx) {
112-
Self::in_static(cx, static_)
104+
if constant.check_static_ptr(cx.tcx).is_some() {
105+
// `mir_const_qualif` does return the qualifs in the final value of a `static`,
106+
// so we could use value-based qualification here, but we shouldn't do this
107+
// without a good reason.
108+
//
109+
// Note: this uses `constant.literal.ty` which is a reference or pointer to the
110+
// type of the actual `static` item.
111+
Self::in_any_value_of_ty(cx, constant.literal.ty)
113112
} else if let ty::ConstKind::Unevaluated(def_id, _) = constant.literal.val {
114113
// Don't peek inside trait associated constants.
115114
if cx.tcx.trait_of_item(def_id).is_some() {

src/libstd/sys/unix/process/process_common.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -375,8 +375,12 @@ impl ChildStdio {
375375

376376
impl fmt::Debug for Command {
377377
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
378-
write!(f, "{:?}", self.program)?;
379-
for arg in &self.args {
378+
if self.program != self.args[0] {
379+
write!(f, "[{:?}] ", self.program)?;
380+
}
381+
write!(f, "{:?}", self.args[0])?;
382+
383+
for arg in &self.args[1..] {
380384
write!(f, " {:?}", arg)?;
381385
}
382386
Ok(())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
extern "C" {
2+
static X: i32;
3+
}
4+
5+
static Y: i32 = 42;
6+
7+
static mut BAR: *const &'static i32 = [&Y].as_ptr();
8+
9+
static mut FOO: *const &'static i32 = [unsafe { &X }].as_ptr();
10+
11+
fn main() {}
12+
13+
// END RUST SOURCE
14+
// START rustc.FOO.PromoteTemps.before.mir
15+
// bb0: {
16+
// ...
17+
// _5 = const Scalar(AllocId(1).0x0) : &i32;
18+
// _4 = &(*_5);
19+
// _3 = [move _4];
20+
// _2 = &_3;
21+
// _1 = move _2 as &[&'static i32] (Pointer(Unsize));
22+
// _0 = const core::slice::<impl [&'static i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
23+
// }
24+
// ...
25+
// bb2: {
26+
// StorageDead(_5);
27+
// StorageDead(_3);
28+
// return;
29+
// }
30+
// END rustc.FOO.PromoteTemps.before.mir
31+
// START rustc.BAR.PromoteTemps.before.mir
32+
// bb0: {
33+
// ...
34+
// _5 = const Scalar(AllocId(0).0x0) : &i32;
35+
// _4 = &(*_5);
36+
// _3 = [move _4];
37+
// _2 = &_3;
38+
// _1 = move _2 as &[&'static i32] (Pointer(Unsize));
39+
// _0 = const core::slice::<impl [&'static i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
40+
// }
41+
// ...
42+
// bb2: {
43+
// StorageDead(_5);
44+
// StorageDead(_3);
45+
// return;
46+
// }
47+
// END rustc.BAR.PromoteTemps.before.mir
48+
// START rustc.BAR.PromoteTemps.after.mir
49+
// bb0: {
50+
// ...
51+
// _2 = &(promoted[0]: [&'static i32; 1]);
52+
// _1 = move _2 as &[&'static i32] (Pointer(Unsize));
53+
// _0 = const core::slice::<impl [&'static i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
54+
// }
55+
// ...
56+
// bb2: {
57+
// return;
58+
// }
59+
// END rustc.BAR.PromoteTemps.after.mir
60+
// START rustc.FOO.PromoteTemps.after.mir
61+
// bb0: {
62+
// ...
63+
// _2 = &(promoted[0]: [&'static i32; 1]);
64+
// _1 = move _2 as &[&'static i32] (Pointer(Unsize));
65+
// _0 = const core::slice::<impl [&'static i32]>::as_ptr(move _1) -> [return: bb2, unwind: bb1];
66+
// }
67+
// ...
68+
// bb2: {
69+
// return;
70+
// }
71+
// END rustc.FOO.PromoteTemps.after.mir
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Moving from a reference/raw pointer should be an error, even when they're
2+
// the field of a union.
3+
4+
#![feature(untagged_unions)]
5+
6+
union Pointers {
7+
a: &'static String,
8+
b: &'static mut String,
9+
c: *const String,
10+
d: *mut String,
11+
}
12+
13+
unsafe fn move_ref(u: Pointers) -> String {
14+
*u.a
15+
//~^ ERROR cannot move out of `*u.a`
16+
}
17+
unsafe fn move_ref_mut(u: Pointers) -> String {
18+
*u.b
19+
//~^ ERROR cannot move out of `*u.b`
20+
}
21+
unsafe fn move_ptr(u: Pointers) -> String {
22+
*u.c
23+
//~^ ERROR cannot move out of `*u.c`
24+
}
25+
unsafe fn move_ptr_mut(u: Pointers) -> String {
26+
*u.d
27+
//~^ ERROR cannot move out of `*u.d`
28+
}
29+
30+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
error[E0507]: cannot move out of `*u.a` which is behind a shared reference
2+
--> $DIR/move-from-union-field-issue-66500.rs:14:5
3+
|
4+
LL | *u.a
5+
| ^^^^ move occurs because `*u.a` has type `std::string::String`, which does not implement the `Copy` trait
6+
7+
error[E0507]: cannot move out of `*u.b` which is behind a mutable reference
8+
--> $DIR/move-from-union-field-issue-66500.rs:18:5
9+
|
10+
LL | *u.b
11+
| ^^^^ move occurs because `*u.b` has type `std::string::String`, which does not implement the `Copy` trait
12+
13+
error[E0507]: cannot move out of `*u.c` which is behind a raw pointer
14+
--> $DIR/move-from-union-field-issue-66500.rs:22:5
15+
|
16+
LL | *u.c
17+
| ^^^^ move occurs because `*u.c` has type `std::string::String`, which does not implement the `Copy` trait
18+
19+
error[E0507]: cannot move out of `*u.d` which is behind a raw pointer
20+
--> $DIR/move-from-union-field-issue-66500.rs:26:5
21+
|
22+
LL | *u.d
23+
| ^^^^ move occurs because `*u.d` has type `std::string::String`, which does not implement the `Copy` trait
24+
25+
error: aborting due to 4 previous errors
26+
27+
For more information about this error, try `rustc --explain E0507`.
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// run-pass
2+
3+
// ignore-windows - this is a unix-specific test
4+
// ignore-cloudabi no processes
5+
// ignore-emscripten no processes
6+
// ignore-sgx no processes
7+
#![feature(process_set_argv0)]
8+
9+
use std::os::unix::process::CommandExt;
10+
use std::process::Command;
11+
12+
fn main() {
13+
let mut command = Command::new("some-boring-name");
14+
15+
assert_eq!(format!("{:?}", command), r#""some-boring-name""#);
16+
17+
command.args(&["1", "2", "3"]);
18+
19+
assert_eq!(format!("{:?}", command), r#""some-boring-name" "1" "2" "3""#);
20+
21+
command.arg0("exciting-name");
22+
23+
assert_eq!(format!("{:?}", command), r#"["some-boring-name"] "exciting-name" "1" "2" "3""#);
24+
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// regression test for #67609.
2+
3+
// check-pass
4+
5+
static NONE: Option<String> = None;
6+
7+
static NONE_REF_REF: &&Option<String> = {
8+
let x = &&NONE;
9+
x
10+
};
11+
12+
fn main() {
13+
println!("{:?}", NONE_REF_REF);
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
fn main() {
2+
[0].iter().flat_map(|a| [0].iter().map(|_| &a)); //~ ERROR `a` does not live long enough
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0597]: `a` does not live long enough
2+
--> $DIR/unnamed-closure-doesnt-life-long-enough-issue-67634.rs:2:49
3+
|
4+
LL | [0].iter().flat_map(|a| [0].iter().map(|_| &a));
5+
| - ^- ...but `a` will be dropped here, when the enclosing closure returns
6+
| | |
7+
| | `a` would have to be valid for `'_`...
8+
| has type `&i32`
9+
|
10+
= note: functions cannot return a borrow to data owned within the function's scope, functions can only return borrows to data passed as arguments
11+
= note: to learn more, visit <https://doc.rust-lang.org/book/ch04-02-references-and-borrowing.html#dangling-references>
12+
13+
error: aborting due to previous error
14+
15+
For more information about this error, try `rustc --explain E0597`.

0 commit comments

Comments
 (0)