Skip to content

Commit

Permalink
Auto merge of rust-lang#105849 - matthiaskrgr:rollup-ya4s1n2, r=matth…
Browse files Browse the repository at this point in the history
…iaskrgr

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
  • Loading branch information
bors committed Dec 17, 2022
2 parents 0468a00 + 8fc1a72 commit 24368ec
Show file tree
Hide file tree
Showing 33 changed files with 476 additions and 55 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ E0311: include_str!("./error_codes/E0311.md"),
E0312: include_str!("./error_codes/E0312.md"),
E0316: include_str!("./error_codes/E0316.md"),
E0317: include_str!("./error_codes/E0317.md"),
E0320: include_str!("./error_codes/E0320.md"),
E0321: include_str!("./error_codes/E0321.md"),
E0322: include_str!("./error_codes/E0322.md"),
E0323: include_str!("./error_codes/E0323.md"),
Expand Down Expand Up @@ -575,7 +576,6 @@ E0791: include_str!("./error_codes/E0791.md"),
// E0314, // closure outlives stack frame
// E0315, // cannot invoke closure outside of its lifetime
// E0319, // trait impls for defaulted traits allowed just for structs/enums
E0320, // recursive overflow during dropck
// E0372, // coherence not object safe
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
// between structures with the same definition
Expand Down
27 changes: 27 additions & 0 deletions compiler/rustc_error_codes/src/error_codes/E0320.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Recursion limit reached while creating drop-check rules.

Example of erroneous code:

```compile_fail,E0320
enum A<T> {
B,
C(T, Box<A<(T, T)>>)
}
fn foo<T>() {
A::<T>::B; // error: overflow while adding drop-check rules for A<T>
}
```

The Rust compiler must be able to reason about how a type is [`Drop`]ped, and
by extension the types of its fields, to be able to generate the glue to
properly drop a value. The code example above shows a type where this inference
is impossible because it is recursive. Note that this is *not* the same as
[E0072](E0072.html), where a type has an infinite size; the type here has a
finite size but any attempt to `Drop` it would recurse infinitely. For more
information, read [the `Drop` docs](../std/ops/trait.Drop.html).

It is not possible to define a type with recursive drop-check rules. All such
recursion must be removed.

[`Drop`]: ../std/ops/trait.Drop.html
49 changes: 49 additions & 0 deletions compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,29 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
@call("mir_goto", args) => {
Ok(TerminatorKind::Goto { target: self.parse_block(args[0])? } )
},
@call("mir_unreachable", _args) => {
Ok(TerminatorKind::Unreachable)
},
@call("mir_drop", args) => {
Ok(TerminatorKind::Drop {
place: self.parse_place(args[0])?,
target: self.parse_block(args[1])?,
unwind: None,
})
},
@call("mir_drop_and_replace", args) => {
Ok(TerminatorKind::DropAndReplace {
place: self.parse_place(args[0])?,
value: self.parse_operand(args[1])?,
target: self.parse_block(args[2])?,
unwind: None,
})
},
@call("mir_call", args) => {
let destination = self.parse_place(args[0])?;
let target = self.parse_block(args[1])?;
self.parse_call(args[2], destination, target)
},
ExprKind::Match { scrutinee, arms } => {
let discr = self.parse_operand(*scrutinee)?;
self.parse_match(arms, expr.span).map(|t| TerminatorKind::SwitchInt { discr, targets: t })
Expand Down Expand Up @@ -86,6 +109,32 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
Ok(SwitchTargets::new(values.into_iter().zip(targets), otherwise))
}

fn parse_call(
&self,
expr_id: ExprId,
destination: Place<'tcx>,
target: BasicBlock,
) -> PResult<TerminatorKind<'tcx>> {
parse_by_kind!(self, expr_id, _, "function call",
ExprKind::Call { fun, args, from_hir_call, fn_span, .. } => {
let fun = self.parse_operand(*fun)?;
let args = args
.iter()
.map(|arg| self.parse_operand(*arg))
.collect::<PResult<Vec<_>>>()?;
Ok(TerminatorKind::Call {
func: fun,
args,
destination,
target: Some(target),
cleanup: None,
from_hir_call: *from_hir_call,
fn_span: *fn_span,
})
},
)
}

fn parse_rvalue(&self, expr_id: ExprId) -> PResult<Rvalue<'tcx>> {
parse_by_kind!(self, expr_id, _, "rvalue",
@call("mir_discriminant", args) => self.parse_place(args[0]).map(Rvalue::Discriminant),
Expand Down
4 changes: 2 additions & 2 deletions library/alloc/src/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@
//! // documentation for details, and the function `pad` can be used
//! // to pad strings.
//! let decimals = f.precision().unwrap_or(3);
//! let string = format!("{:.*}", decimals, magnitude);
//! let string = format!("{magnitude:.decimals$}");
//! f.pad_integral(true, "", &string)
//! }
//! }
Expand Down Expand Up @@ -518,7 +518,7 @@
//! write!(&mut some_writer, "{}", format_args!("print with a {}", "macro"));
//!
//! fn my_fmt_fn(args: fmt::Arguments) {
//! write!(&mut io::stdout(), "{}", args);
//! write!(&mut io::stdout(), "{args}");
//! }
//! my_fmt_fn(format_args!(", or a {} too", "function"));
//! ```
Expand Down
39 changes: 37 additions & 2 deletions library/core/src/intrinsics/mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
//! if you want your MIR to be modified by the full MIR pipeline, or `#![custom_mir(dialect =
//! "runtime", phase = "optimized")] if you don't.
//!
//! [dialect docs]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.MirPhase.html
//! [dialect docs]:
//! https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/mir/enum.MirPhase.html
//!
//! The input to the [`mir!`] macro is:
//!
Expand Down Expand Up @@ -99,6 +100,30 @@
//! Return()
//! })
//! }
//!
//! #[custom_mir(dialect = "runtime", phase = "optimized")]
//! fn push_and_pop<T>(v: &mut Vec<T>, value: T) {
//! mir!(
//! let unused;
//! let popped;
//!
//! {
//! Call(unused, pop, Vec::push(v, value))
//! }
//!
//! pop = {
//! Call(popped, drop, Vec::pop(v))
//! }
//!
//! drop = {
//! Drop(popped, ret)
//! }
//!
//! ret = {
//! Return()
//! }
//! )
//! }
//! ```
//!
//! We can also set off compilation failures that happen in sufficiently late stages of the
Expand Down Expand Up @@ -195,10 +220,16 @@
//!
//! #### Terminators
//!
//! - [`Goto`] and [`Return`] have associated functions.
//! Custom MIR does not currently support cleanup blocks or non-trivial unwind paths. As such, there
//! are no resume and abort terminators, and terminators that might unwind do not have any way to
//! indicate the unwind block.
//!
//! - [`Goto`], [`Return`], [`Unreachable`], [`Drop`](Drop()), and [`DropAndReplace`] have associated functions.
//! - `match some_int_operand` becomes a `SwitchInt`. Each arm should be `literal => basic_block`
//! - The exception is the last arm, which must be `_ => basic_block` and corresponds to the
//! otherwise branch.
//! - [`Call`] has an associated function as well. The third argument of this function is a normal
//! function call expresion, for example `my_other_function(a, 5)`.
//!
#![unstable(
Expand All @@ -223,6 +254,10 @@ macro_rules! define {

define!("mir_return", fn Return() -> BasicBlock);
define!("mir_goto", fn Goto(destination: BasicBlock) -> BasicBlock);
define!("mir_unreachable", fn Unreachable() -> BasicBlock);
define!("mir_drop", fn Drop<T>(place: T, goto: BasicBlock));
define!("mir_drop_and_replace", fn DropAndReplace<T>(place: T, value: T, goto: BasicBlock));
define!("mir_call", fn Call<T>(place: T, goto: BasicBlock, call: T));
define!("mir_retag", fn Retag<T>(place: T));
define!("mir_retag_raw", fn RetagRaw<T>(place: T));
define!("mir_move", fn Move<T>(place: T) -> T);
Expand Down
10 changes: 6 additions & 4 deletions library/std/src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,10 @@ impl Read for ChildStdout {
fn is_read_vectored(&self) -> bool {
self.inner.is_read_vectored()
}

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.inner.read_to_end(buf)
}
}

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

/// Executes a command as a child process, waiting for it to finish and
Expand Down
4 changes: 4 additions & 0 deletions library/std/src/sys/unix/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ impl AnonPipe {
self.0.is_read_vectored()
}

pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.0.read_to_end(buf)
}

pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
}
Expand Down
5 changes: 5 additions & 0 deletions library/std/src/sys/unix/process/process_fuchsia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ impl Command {
Ok((Process { handle: Handle::new(process_handle) }, ours))
}

pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
crate::sys_common::process::wait_with_output(proc, pipes)
}

pub fn exec(&mut self, default: Stdio) -> io::Error {
if self.saw_nul() {
return io::const_io_error!(
Expand Down
5 changes: 5 additions & 0 deletions library/std/src/sys/unix/process/process_unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ impl Command {
}
}

pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
crate::sys_common::process::wait_with_output(proc, pipes)
}

// Attempts to fork the process. If successful, returns Ok((0, -1))
// in the child, and Ok((child_pid, -1)) in the parent.
#[cfg(not(target_os = "linux"))]
Expand Down
4 changes: 4 additions & 0 deletions library/std/src/sys/unix/process/process_unsupported.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ impl Command {
unsupported()
}

pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
unsupported()
}

pub fn exec(&mut self, _default: Stdio) -> io::Error {
unsupported_err()
}
Expand Down
5 changes: 5 additions & 0 deletions library/std/src/sys/unix/process/process_vxworks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,11 @@ impl Command {
}
}

pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
crate::sys_common::process::wait_with_output(proc, pipes)
}

pub fn exec(&mut self, default: Stdio) -> io::Error {
let ret = Command::spawn(self, default, false);
match ret {
Expand Down
4 changes: 4 additions & 0 deletions library/std/src/sys/unsupported/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ impl AnonPipe {
self.0
}

pub fn read_to_end(&self, _buf: &mut Vec<u8>) -> io::Result<usize> {
self.0
}

pub fn write(&self, _buf: &[u8]) -> io::Result<usize> {
self.0
}
Expand Down
4 changes: 4 additions & 0 deletions library/std/src/sys/unsupported/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,10 @@ impl Command {
) -> io::Result<(Process, StdioPipes)> {
unsupported()
}

pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
unsupported()
}
}

impl From<AnonPipe> for Stdio {
Expand Down
6 changes: 5 additions & 1 deletion library/std/src/sys/windows/pipe.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::os::windows::prelude::*;

use crate::ffi::OsStr;
use crate::io::{self, IoSlice, IoSliceMut};
use crate::io::{self, IoSlice, IoSliceMut, Read};
use crate::mem;
use crate::path::Path;
use crate::ptr;
Expand Down Expand Up @@ -261,6 +261,10 @@ impl AnonPipe {
self.inner.is_read_vectored()
}

pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.handle().read_to_end(buf)
}

pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
unsafe {
let len = crate::cmp::min(buf.len(), c::DWORD::MAX as usize) as c::DWORD;
Expand Down
5 changes: 5 additions & 0 deletions library/std/src/sys/windows/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,11 @@ impl Command {
))
}
}

pub fn output(&mut self) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
let (proc, pipes) = self.spawn(Stdio::MakePipe, false)?;
crate::sys_common::process::wait_with_output(proc, pipes)
}
}

impl fmt::Debug for Command {
Expand Down
31 changes: 30 additions & 1 deletion library/std/src/sys_common/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
use crate::collections::BTreeMap;
use crate::env;
use crate::ffi::{OsStr, OsString};
use crate::sys::process::EnvKey;
use crate::io;
use crate::sys::pipe::read2;
use crate::sys::process::{EnvKey, ExitStatus, Process, StdioPipes};

// Stores a set of changes to an environment
#[derive(Clone, Debug)]
Expand Down Expand Up @@ -117,3 +119,30 @@ impl<'a> ExactSizeIterator for CommandEnvs<'a> {
self.iter.is_empty()
}
}

pub fn wait_with_output(
mut process: Process,
mut pipes: StdioPipes,
) -> io::Result<(ExitStatus, Vec<u8>, Vec<u8>)> {
drop(pipes.stdin.take());

let (mut stdout, mut stderr) = (Vec::new(), Vec::new());
match (pipes.stdout.take(), pipes.stderr.take()) {
(None, None) => {}
(Some(out), None) => {
let res = out.read_to_end(&mut stdout);
res.unwrap();
}
(None, Some(err)) => {
let res = err.read_to_end(&mut stderr);
res.unwrap();
}
(Some(out), Some(err)) => {
let res = read2(out, &mut stdout, err, &mut stderr);
res.unwrap();
}
}

let status = process.wait()?;
Ok((status, stdout, stderr))
}
1 change: 1 addition & 0 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,7 @@ impl<'a> Builder<'a> {
install::RustDemangler,
install::Clippy,
install::Miri,
install::LlvmTools,
install::Analysis,
install::Src,
install::Rustc
Expand Down
Loading

0 comments on commit 24368ec

Please sign in to comment.