Skip to content

Commit 24368ec

Browse files
committed
Auto merge of rust-lang#105849 - matthiaskrgr:rollup-ya4s1n2, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - rust-lang#104854 (Symlink `build/host` -> `build/$HOST_TRIPLE`) - rust-lang#105458 (Allow blocking `Command::output`) - rust-lang#105559 (bootstrap: Allow installing `llvm-tools`) - rust-lang#105789 (rustdoc: clean up margin CSS for scraped examples) - rust-lang#105792 (docs: add long error explanation for error E0320) - rust-lang#105814 (Support call and drop terminators in custom mir) - rust-lang#105829 (Speed up tidy) - rust-lang#105836 (std::fmt: Use args directly in example code) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 0468a00 + 8fc1a72 commit 24368ec

33 files changed

+476
-55
lines changed

compiler/rustc_error_codes/src/error_codes.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ E0311: include_str!("./error_codes/E0311.md"),
163163
E0312: include_str!("./error_codes/E0312.md"),
164164
E0316: include_str!("./error_codes/E0316.md"),
165165
E0317: include_str!("./error_codes/E0317.md"),
166+
E0320: include_str!("./error_codes/E0320.md"),
166167
E0321: include_str!("./error_codes/E0321.md"),
167168
E0322: include_str!("./error_codes/E0322.md"),
168169
E0323: include_str!("./error_codes/E0323.md"),
@@ -575,7 +576,6 @@ E0791: include_str!("./error_codes/E0791.md"),
575576
// E0314, // closure outlives stack frame
576577
// E0315, // cannot invoke closure outside of its lifetime
577578
// E0319, // trait impls for defaulted traits allowed just for structs/enums
578-
E0320, // recursive overflow during dropck
579579
// E0372, // coherence not object safe
580580
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
581581
// between structures with the same definition
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Recursion limit reached while creating drop-check rules.
2+
3+
Example of erroneous code:
4+
5+
```compile_fail,E0320
6+
enum A<T> {
7+
B,
8+
C(T, Box<A<(T, T)>>)
9+
}
10+
11+
fn foo<T>() {
12+
A::<T>::B; // error: overflow while adding drop-check rules for A<T>
13+
}
14+
```
15+
16+
The Rust compiler must be able to reason about how a type is [`Drop`]ped, and
17+
by extension the types of its fields, to be able to generate the glue to
18+
properly drop a value. The code example above shows a type where this inference
19+
is impossible because it is recursive. Note that this is *not* the same as
20+
[E0072](E0072.html), where a type has an infinite size; the type here has a
21+
finite size but any attempt to `Drop` it would recurse infinitely. For more
22+
information, read [the `Drop` docs](../std/ops/trait.Drop.html).
23+
24+
It is not possible to define a type with recursive drop-check rules. All such
25+
recursion must be removed.
26+
27+
[`Drop`]: ../std/ops/trait.Drop.html

compiler/rustc_mir_build/src/build/custom/parse/instruction.rs

+49
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,29 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
4242
@call("mir_goto", args) => {
4343
Ok(TerminatorKind::Goto { target: self.parse_block(args[0])? } )
4444
},
45+
@call("mir_unreachable", _args) => {
46+
Ok(TerminatorKind::Unreachable)
47+
},
48+
@call("mir_drop", args) => {
49+
Ok(TerminatorKind::Drop {
50+
place: self.parse_place(args[0])?,
51+
target: self.parse_block(args[1])?,
52+
unwind: None,
53+
})
54+
},
55+
@call("mir_drop_and_replace", args) => {
56+
Ok(TerminatorKind::DropAndReplace {
57+
place: self.parse_place(args[0])?,
58+
value: self.parse_operand(args[1])?,
59+
target: self.parse_block(args[2])?,
60+
unwind: None,
61+
})
62+
},
63+
@call("mir_call", args) => {
64+
let destination = self.parse_place(args[0])?;
65+
let target = self.parse_block(args[1])?;
66+
self.parse_call(args[2], destination, target)
67+
},
4568
ExprKind::Match { scrutinee, arms } => {
4669
let discr = self.parse_operand(*scrutinee)?;
4770
self.parse_match(arms, expr.span).map(|t| TerminatorKind::SwitchInt { discr, targets: t })
@@ -86,6 +109,32 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
86109
Ok(SwitchTargets::new(values.into_iter().zip(targets), otherwise))
87110
}
88111

112+
fn parse_call(
113+
&self,
114+
expr_id: ExprId,
115+
destination: Place<'tcx>,
116+
target: BasicBlock,
117+
) -> PResult<TerminatorKind<'tcx>> {
118+
parse_by_kind!(self, expr_id, _, "function call",
119+
ExprKind::Call { fun, args, from_hir_call, fn_span, .. } => {
120+
let fun = self.parse_operand(*fun)?;
121+
let args = args
122+
.iter()
123+
.map(|arg| self.parse_operand(*arg))
124+
.collect::<PResult<Vec<_>>>()?;
125+
Ok(TerminatorKind::Call {
126+
func: fun,
127+
args,
128+
destination,
129+
target: Some(target),
130+
cleanup: None,
131+
from_hir_call: *from_hir_call,
132+
fn_span: *fn_span,
133+
})
134+
},
135+
)
136+
}
137+
89138
fn parse_rvalue(&self, expr_id: ExprId) -> PResult<Rvalue<'tcx>> {
90139
parse_by_kind!(self, expr_id, _, "rvalue",
91140
@call("mir_discriminant", args) => self.parse_place(args[0]).map(Rvalue::Discriminant),

library/alloc/src/fmt.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@
419419
//! // documentation for details, and the function `pad` can be used
420420
//! // to pad strings.
421421
//! let decimals = f.precision().unwrap_or(3);
422-
//! let string = format!("{:.*}", decimals, magnitude);
422+
//! let string = format!("{magnitude:.decimals$}");
423423
//! f.pad_integral(true, "", &string)
424424
//! }
425425
//! }
@@ -518,7 +518,7 @@
518518
//! write!(&mut some_writer, "{}", format_args!("print with a {}", "macro"));
519519
//!
520520
//! fn my_fmt_fn(args: fmt::Arguments) {
521-
//! write!(&mut io::stdout(), "{}", args);
521+
//! write!(&mut io::stdout(), "{args}");
522522
//! }
523523
//! my_fmt_fn(format_args!(", or a {} too", "function"));
524524
//! ```

library/core/src/intrinsics/mir.rs

+37-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@
4444
//! if you want your MIR to be modified by the full MIR pipeline, or `#![custom_mir(dialect =
4545
//! "runtime", phase = "optimized")] if you don't.
4646
//!
47-
//! [dialect docs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.MirPhase.html
47+
//! [dialect docs]:
48+
//! https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.MirPhase.html
4849
//!
4950
//! The input to the [`mir!`] macro is:
5051
//!
@@ -99,6 +100,30 @@
99100
//! Return()
100101
//! })
101102
//! }
103+
//!
104+
//! #[custom_mir(dialect = "runtime", phase = "optimized")]
105+
//! fn push_and_pop<T>(v: &mut Vec<T>, value: T) {
106+
//! mir!(
107+
//! let unused;
108+
//! let popped;
109+
//!
110+
//! {
111+
//! Call(unused, pop, Vec::push(v, value))
112+
//! }
113+
//!
114+
//! pop = {
115+
//! Call(popped, drop, Vec::pop(v))
116+
//! }
117+
//!
118+
//! drop = {
119+
//! Drop(popped, ret)
120+
//! }
121+
//!
122+
//! ret = {
123+
//! Return()
124+
//! }
125+
//! )
126+
//! }
102127
//! ```
103128
//!
104129
//! We can also set off compilation failures that happen in sufficiently late stages of the
@@ -195,10 +220,16 @@
195220
//!
196221
//! #### Terminators
197222
//!
198-
//! - [`Goto`] and [`Return`] have associated functions.
223+
//! Custom MIR does not currently support cleanup blocks or non-trivial unwind paths. As such, there
224+
//! are no resume and abort terminators, and terminators that might unwind do not have any way to
225+
//! indicate the unwind block.
226+
//!
227+
//! - [`Goto`], [`Return`], [`Unreachable`], [`Drop`](Drop()), and [`DropAndReplace`] have associated functions.
199228
//! - `match some_int_operand` becomes a `SwitchInt`. Each arm should be `literal => basic_block`
200229
//! - The exception is the last arm, which must be `_ => basic_block` and corresponds to the
201230
//! otherwise branch.
231+
//! - [`Call`] has an associated function as well. The third argument of this function is a normal
232+
//! function call expresion, for example `my_other_function(a, 5)`.
202233
//!
203234
204235
#![unstable(
@@ -223,6 +254,10 @@ macro_rules! define {
223254

224255
define!("mir_return", fn Return() -> BasicBlock);
225256
define!("mir_goto", fn Goto(destination: BasicBlock) -> BasicBlock);
257+
define!("mir_unreachable", fn Unreachable() -> BasicBlock);
258+
define!("mir_drop", fn Drop<T>(place: T, goto: BasicBlock));
259+
define!("mir_drop_and_replace", fn DropAndReplace<T>(place: T, value: T, goto: BasicBlock));
260+
define!("mir_call", fn Call<T>(place: T, goto: BasicBlock, call: T));
226261
define!("mir_retag", fn Retag<T>(place: T));
227262
define!("mir_retag_raw", fn RetagRaw<T>(place: T));
228263
define!("mir_move", fn Move<T>(place: T) -> T);

library/std/src/process.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,10 @@ impl Read for ChildStdout {
362362
fn is_read_vectored(&self) -> bool {
363363
self.inner.is_read_vectored()
364364
}
365+
366+
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
367+
self.inner.read_to_end(buf)
368+
}
365369
}
366370

367371
impl AsInner<AnonPipe> for ChildStdout {
@@ -907,10 +911,8 @@ impl Command {
907911
/// ```
908912
#[stable(feature = "process", since = "1.0.0")]
909913
pub fn output(&mut self) -> io::Result<Output> {
910-
self.inner
911-
.spawn(imp::Stdio::MakePipe, false)
912-
.map(Child::from_inner)
913-
.and_then(|p| p.wait_with_output())
914+
let (status, stdout, stderr) = self.inner.output()?;
915+
Ok(Output { status: ExitStatus(status), stdout, stderr })
914916
}
915917

916918
/// Executes a command as a child process, waiting for it to finish and

library/std/src/sys/unix/pipe.rs

+4
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ impl AnonPipe {
5858
self.0.is_read_vectored()
5959
}
6060

61+
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
62+
self.0.read_to_end(buf)
63+
}
64+
6165
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
6266
self.0.write(buf)
6367
}

library/std/src/sys/unix/process/process_fuchsia.rs

+5
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ impl Command {
3535
Ok((Process { handle: Handle::new(process_handle) }, ours))
3636
}
3737

38+
pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
39+
let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
40+
crate::sys_common::process::wait_with_output(proc, pipes)
41+
}
42+
3843
pub fn exec(&mut self, default: Stdio) -> io::Error {
3944
if self.saw_nul() {
4045
return io::const_io_error!(

library/std/src/sys/unix/process/process_unix.rs

+5
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ impl Command {
133133
}
134134
}
135135

136+
pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
137+
let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
138+
crate::sys_common::process::wait_with_output(proc, pipes)
139+
}
140+
136141
// Attempts to fork the process. If successful, returns Ok((0, -1))
137142
// in the child, and Ok((child_pid, -1)) in the parent.
138143
#[cfg(not(target_os = "linux"))]

library/std/src/sys/unix/process/process_unsupported.rs

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ impl Command {
2020
unsupported()
2121
}
2222

23+
pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
24+
unsupported()
25+
}
26+
2327
pub fn exec(&mut self, _default: Stdio) -> io::Error {
2428
unsupported_err()
2529
}

library/std/src/sys/unix/process/process_vxworks.rs

+5
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,11 @@ impl Command {
108108
}
109109
}
110110

111+
pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
112+
let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
113+
crate::sys_common::process::wait_with_output(proc, pipes)
114+
}
115+
111116
pub fn exec(&mut self, default: Stdio) -> io::Error {
112117
let ret = Command::spawn(self, default, false);
113118
match ret {

library/std/src/sys/unsupported/pipe.rs

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ impl AnonPipe {
1515
self.0
1616
}
1717

18+
pub fn read_to_end(&self, _buf: &mut Vec<u8>) -> io::Result<usize> {
19+
self.0
20+
}
21+
1822
pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
1923
self.0
2024
}

library/std/src/sys/unsupported/process.rs

+4
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,10 @@ impl Command {
7575
) -> io::Result<(Process, StdioPipes)> {
7676
unsupported()
7777
}
78+
79+
pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
80+
unsupported()
81+
}
7882
}
7983

8084
impl From<AnonPipe> for Stdio {

library/std/src/sys/windows/pipe.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::os::windows::prelude::*;
22

33
use crate::ffi::OsStr;
4-
use crate::io::{self, IoSlice, IoSliceMut};
4+
use crate::io::{self, IoSlice, IoSliceMut, Read};
55
use crate::mem;
66
use crate::path::Path;
77
use crate::ptr;
@@ -261,6 +261,10 @@ impl AnonPipe {
261261
self.inner.is_read_vectored()
262262
}
263263

264+
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
265+
self.handle().read_to_end(buf)
266+
}
267+
264268
pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
265269
unsafe {
266270
let len = crate::cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD;

library/std/src/sys/windows/process.rs

+5
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,11 @@ impl Command {
351351
))
352352
}
353353
}
354+
355+
pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
356+
let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
357+
crate::sys_common::process::wait_with_output(proc, pipes)
358+
}
354359
}
355360

356361
impl fmt::Debug for Command {

library/std/src/sys_common/process.rs

+30-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
use crate::collections::BTreeMap;
55
use crate::env;
66
use crate::ffi::{OsStr, OsString};
7-
use crate::sys::process::EnvKey;
7+
use crate::io;
8+
use crate::sys::pipe::read2;
9+
use crate::sys::process::{EnvKey, ExitStatus, Process, StdioPipes};
810

911
// Stores a set of changes to an environment
1012
#[derive(Clone, Debug)]
@@ -117,3 +119,30 @@ impl<'a> ExactSizeIterator for CommandEnvs<'a> {
117119
self.iter.is_empty()
118120
}
119121
}
122+
123+
pub fn wait_with_output(
124+
mut process: Process,
125+
mut pipes: StdioPipes,
126+
) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
127+
drop(pipes.stdin.take());
128+
129+
let (mut stdout, mut stderr) = (Vec::new(), Vec::new());
130+
match (pipes.stdout.take(), pipes.stderr.take()) {
131+
(None, None) => {}
132+
(Some(out), None) => {
133+
let res = out.read_to_end(&mut stdout);
134+
res.unwrap();
135+
}
136+
(None, Some(err)) => {
137+
let res = err.read_to_end(&mut stderr);
138+
res.unwrap();
139+
}
140+
(Some(out), Some(err)) => {
141+
let res = read2(out, &mut stdout, err, &mut stderr);
142+
res.unwrap();
143+
}
144+
}
145+
146+
let status = process.wait()?;
147+
Ok((status, stdout, stderr))
148+
}

src/bootstrap/builder.rs

+1
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,7 @@ impl<'a> Builder<'a> {
744744
install::RustDemangler,
745745
install::Clippy,
746746
install::Miri,
747+
install::LlvmTools,
747748
install::Analysis,
748749
install::Src,
749750
install::Rustc

0 commit comments

Comments
 (0)