Skip to content

Rollup of 5 pull requests #128330

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jul 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions library/alloc/src/collections/btree/map.rs
Original file line number Diff line number Diff line change
@@ -2921,7 +2921,7 @@ impl<'a, K, V> Cursor<'a, K, V> {
/// Returns a reference to the key and value of the next element without
/// moving the cursor.
///
/// If the cursor is at the end of the map then `None` is returned
/// If the cursor is at the end of the map then `None` is returned.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn peek_next(&self) -> Option<(&'a K, &'a V)> {
self.clone().next()
@@ -2963,7 +2963,7 @@ impl<'a, K, V, A> CursorMut<'a, K, V, A> {
/// Returns a reference to the key and value of the next element without
/// moving the cursor.
///
/// If the cursor is at the end of the map then `None` is returned
/// If the cursor is at the end of the map then `None` is returned.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn peek_next(&mut self) -> Option<(&K, &mut V)> {
let (k, v) = self.inner.peek_next()?;
@@ -3061,7 +3061,7 @@ impl<'a, K, V, A> CursorMutKey<'a, K, V, A> {
/// Returns a reference to the key and value of the next element without
/// moving the cursor.
///
/// If the cursor is at the end of the map then `None` is returned
/// If the cursor is at the end of the map then `None` is returned.
#[unstable(feature = "btree_cursors", issue = "107540")]
pub fn peek_next(&mut self) -> Option<(&mut K, &mut V)> {
let current = self.current.as_mut()?;
65 changes: 35 additions & 30 deletions library/std/src/io/cursor.rs
Original file line number Diff line number Diff line change
@@ -209,55 +209,60 @@ impl<T> Cursor<T>
where
T: AsRef<[u8]>,
{
/// Returns the remaining slice.
/// Splits the underlying slice at the cursor position and returns them.
///
/// # Examples
///
/// ```
/// #![feature(cursor_remaining)]
/// #![feature(cursor_split)]
/// use std::io::Cursor;
///
/// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
///
/// assert_eq!(buff.remaining_slice(), &[1, 2, 3, 4, 5]);
/// assert_eq!(buff.split(), ([].as_slice(), [1, 2, 3, 4, 5].as_slice()));
///
/// buff.set_position(2);
/// assert_eq!(buff.remaining_slice(), &[3, 4, 5]);
///
/// buff.set_position(4);
/// assert_eq!(buff.remaining_slice(), &[5]);
/// assert_eq!(buff.split(), ([1, 2].as_slice(), [3, 4, 5].as_slice()));
///
/// buff.set_position(6);
/// assert_eq!(buff.remaining_slice(), &[]);
/// assert_eq!(buff.split(), ([1, 2, 3, 4, 5].as_slice(), [].as_slice()));
/// ```
#[unstable(feature = "cursor_remaining", issue = "86369")]
pub fn remaining_slice(&self) -> &[u8] {
let len = self.pos.min(self.inner.as_ref().len() as u64);
&self.inner.as_ref()[(len as usize)..]
#[unstable(feature = "cursor_split", issue = "86369")]
pub fn split(&self) -> (&[u8], &[u8]) {
let slice = self.inner.as_ref();
let pos = self.pos.min(slice.len() as u64);
slice.split_at(pos as usize)
}
}

/// Returns `true` if the remaining slice is empty.
impl<T> Cursor<T>
where
T: AsMut<[u8]>,
{
/// Splits the underlying slice at the cursor position and returns them
/// mutably.
///
/// # Examples
///
/// ```
/// #![feature(cursor_remaining)]
/// #![feature(cursor_split)]
/// use std::io::Cursor;
///
/// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]);
///
/// buff.set_position(2);
/// assert!(!buff.is_empty());
/// assert_eq!(buff.split_mut(), ([].as_mut_slice(), [1, 2, 3, 4, 5].as_mut_slice()));
///
/// buff.set_position(5);
/// assert!(buff.is_empty());
/// buff.set_position(2);
/// assert_eq!(buff.split_mut(), ([1, 2].as_mut_slice(), [3, 4, 5].as_mut_slice()));
///
/// buff.set_position(10);
/// assert!(buff.is_empty());
/// buff.set_position(6);
/// assert_eq!(buff.split_mut(), ([1, 2, 3, 4, 5].as_mut_slice(), [].as_mut_slice()));
/// ```
#[unstable(feature = "cursor_remaining", issue = "86369")]
pub fn is_empty(&self) -> bool {
self.pos >= self.inner.as_ref().len() as u64
#[unstable(feature = "cursor_split", issue = "86369")]
pub fn split_mut(&mut self) -> (&mut [u8], &mut [u8]) {
let slice = self.inner.as_mut();
let pos = self.pos.min(slice.len() as u64);
slice.split_at_mut(pos as usize)
}
}

@@ -319,15 +324,15 @@ where
T: AsRef<[u8]>,
{
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let n = Read::read(&mut self.remaining_slice(), buf)?;
let n = Read::read(&mut Cursor::split(self).1, buf)?;
self.pos += n as u64;
Ok(n)
}

fn read_buf(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
let prev_written = cursor.written();

Read::read_buf(&mut self.remaining_slice(), cursor.reborrow())?;
Read::read_buf(&mut Cursor::split(self).1, cursor.reborrow())?;

self.pos += (cursor.written() - prev_written) as u64;

@@ -351,7 +356,7 @@ where
}

fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
let result = Read::read_exact(&mut self.remaining_slice(), buf);
let result = Read::read_exact(&mut Cursor::split(self).1, buf);

match result {
Ok(_) => self.pos += buf.len() as u64,
@@ -365,14 +370,14 @@ where
fn read_buf_exact(&mut self, mut cursor: BorrowedCursor<'_>) -> io::Result<()> {
let prev_written = cursor.written();

let result = Read::read_buf_exact(&mut self.remaining_slice(), cursor.reborrow());
let result = Read::read_buf_exact(&mut Cursor::split(self).1, cursor.reborrow());
self.pos += (cursor.written() - prev_written) as u64;

result
}

fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
let content = self.remaining_slice();
let content = Cursor::split(self).1;
let len = content.len();
buf.try_reserve(len)?;
buf.extend_from_slice(content);
@@ -383,7 +388,7 @@ where

fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
let content =
crate::str::from_utf8(self.remaining_slice()).map_err(|_| io::Error::INVALID_UTF8)?;
crate::str::from_utf8(Cursor::split(self).1).map_err(|_| io::Error::INVALID_UTF8)?;
let len = content.len();
buf.try_reserve(len)?;
buf.push_str(content);
@@ -399,7 +404,7 @@ where
T: AsRef<[u8]>,
{
fn fill_buf(&mut self) -> io::Result<&[u8]> {
Ok(self.remaining_slice())
Ok(Cursor::split(self).1)
}
fn consume(&mut self, amt: usize) {
self.pos += amt as u64;
4 changes: 2 additions & 2 deletions library/std/src/io/tests.rs
Original file line number Diff line number Diff line change
@@ -676,13 +676,13 @@ fn cursor_read_exact_eof() {

let mut r = slice.clone();
assert!(r.read_exact(&mut [0; 10]).is_err());
assert!(r.is_empty());
assert!(Cursor::split(&r).1.is_empty());

let mut r = slice;
let buf = &mut [0; 10];
let mut buf = BorrowedBuf::from(buf.as_mut_slice());
assert!(r.read_buf_exact(buf.unfilled()).is_err());
assert!(r.is_empty());
assert!(Cursor::split(&r).1.is_empty());
assert_eq!(buf.filled(), b"123456");
}

112 changes: 60 additions & 52 deletions library/std/src/sys/personality/dwarf/eh.rs
Original file line number Diff line number Diff line change
@@ -70,45 +70,51 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result

let func_start = context.func_start;
let mut reader = DwarfReader::new(lsda);

let start_encoding = reader.read::<u8>();
// base address for landing pad offsets
let lpad_base = if start_encoding != DW_EH_PE_omit {
read_encoded_pointer(&mut reader, context, start_encoding)?
} else {
func_start
let lpad_base = unsafe {
let start_encoding = reader.read::<u8>();
// base address for landing pad offsets
if start_encoding != DW_EH_PE_omit {
read_encoded_pointer(&mut reader, context, start_encoding)?
} else {
func_start
}
};
let call_site_encoding = unsafe {
let ttype_encoding = reader.read::<u8>();
if ttype_encoding != DW_EH_PE_omit {
// Rust doesn't analyze exception types, so we don't care about the type table
reader.read_uleb128();
}

let ttype_encoding = reader.read::<u8>();
if ttype_encoding != DW_EH_PE_omit {
// Rust doesn't analyze exception types, so we don't care about the type table
reader.read_uleb128();
}

let call_site_encoding = reader.read::<u8>();
let call_site_table_length = reader.read_uleb128();
let action_table = reader.ptr.add(call_site_table_length as usize);
reader.read::<u8>()
};
let action_table = unsafe {
let call_site_table_length = reader.read_uleb128();
reader.ptr.add(call_site_table_length as usize)
};
let ip = context.ip;

if !USING_SJLJ_EXCEPTIONS {
// read the callsite table
while reader.ptr < action_table {
// these are offsets rather than pointers;
let cs_start = read_encoded_offset(&mut reader, call_site_encoding)?;
let cs_len = read_encoded_offset(&mut reader, call_site_encoding)?;
let cs_lpad = read_encoded_offset(&mut reader, call_site_encoding)?;
let cs_action_entry = reader.read_uleb128();
// Callsite table is sorted by cs_start, so if we've passed the ip, we
// may stop searching.
if ip < func_start.wrapping_add(cs_start) {
break;
}
if ip < func_start.wrapping_add(cs_start + cs_len) {
if cs_lpad == 0 {
return Ok(EHAction::None);
} else {
let lpad = lpad_base.wrapping_add(cs_lpad);
return Ok(interpret_cs_action(action_table, cs_action_entry, lpad));
unsafe {
// these are offsets rather than pointers;
let cs_start = read_encoded_offset(&mut reader, call_site_encoding)?;
let cs_len = read_encoded_offset(&mut reader, call_site_encoding)?;
let cs_lpad = read_encoded_offset(&mut reader, call_site_encoding)?;
let cs_action_entry = reader.read_uleb128();
// Callsite table is sorted by cs_start, so if we've passed the ip, we
// may stop searching.
if ip < func_start.wrapping_add(cs_start) {
break;
}
if ip < func_start.wrapping_add(cs_start + cs_len) {
if cs_lpad == 0 {
return Ok(EHAction::None);
} else {
let lpad = lpad_base.wrapping_add(cs_lpad);
return Ok(interpret_cs_action(action_table, cs_action_entry, lpad));
}
}
}
}
@@ -125,15 +131,15 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
}
let mut idx = ip.addr();
loop {
let cs_lpad = reader.read_uleb128();
let cs_action_entry = reader.read_uleb128();
let cs_lpad = unsafe { reader.read_uleb128() };
let cs_action_entry = unsafe { reader.read_uleb128() };
idx -= 1;
if idx == 0 {
// Can never have null landing pad for sjlj -- that would have
// been indicated by a -1 call site index.
// FIXME(strict provenance)
let lpad = ptr::with_exposed_provenance((cs_lpad + 1) as usize);
return Ok(interpret_cs_action(action_table, cs_action_entry, lpad));
return Ok(unsafe { interpret_cs_action(action_table, cs_action_entry, lpad) });
}
}
}
@@ -151,9 +157,9 @@ unsafe fn interpret_cs_action(
} else {
// If lpad != 0 and cs_action_entry != 0, we have to check ttype_index.
// If ttype_index == 0 under the condition, we take cleanup action.
let action_record = action_table.offset(cs_action_entry as isize - 1);
let action_record = unsafe { action_table.offset(cs_action_entry as isize - 1) };
let mut action_reader = DwarfReader::new(action_record);
let ttype_index = action_reader.read_sleb128();
let ttype_index = unsafe { action_reader.read_sleb128() };
if ttype_index == 0 {
EHAction::Cleanup(lpad)
} else if ttype_index > 0 {
@@ -186,18 +192,20 @@ unsafe fn read_encoded_offset(reader: &mut DwarfReader, encoding: u8) -> Result<
if encoding == DW_EH_PE_omit || encoding & 0xF0 != 0 {
return Err(());
}
let result = match encoding & 0x0F {
// despite the name, LLVM also uses absptr for offsets instead of pointers
DW_EH_PE_absptr => reader.read::<usize>(),
DW_EH_PE_uleb128 => reader.read_uleb128() as usize,
DW_EH_PE_udata2 => reader.read::<u16>() as usize,
DW_EH_PE_udata4 => reader.read::<u32>() as usize,
DW_EH_PE_udata8 => reader.read::<u64>() as usize,
DW_EH_PE_sleb128 => reader.read_sleb128() as usize,
DW_EH_PE_sdata2 => reader.read::<i16>() as usize,
DW_EH_PE_sdata4 => reader.read::<i32>() as usize,
DW_EH_PE_sdata8 => reader.read::<i64>() as usize,
_ => return Err(()),
let result = unsafe {
match encoding & 0x0F {
// despite the name, LLVM also uses absptr for offsets instead of pointers
DW_EH_PE_absptr => reader.read::<usize>(),
DW_EH_PE_uleb128 => reader.read_uleb128() as usize,
DW_EH_PE_udata2 => reader.read::<u16>() as usize,
DW_EH_PE_udata4 => reader.read::<u32>() as usize,
DW_EH_PE_udata8 => reader.read::<u64>() as usize,
DW_EH_PE_sleb128 => reader.read_sleb128() as usize,
DW_EH_PE_sdata2 => reader.read::<i16>() as usize,
DW_EH_PE_sdata4 => reader.read::<i32>() as usize,
DW_EH_PE_sdata8 => reader.read::<i64>() as usize,
_ => return Err(()),
}
};
Ok(result)
}
@@ -250,14 +258,14 @@ unsafe fn read_encoded_pointer(
if encoding & 0x0F != DW_EH_PE_absptr {
return Err(());
}
reader.read::<*const u8>()
unsafe { reader.read::<*const u8>() }
} else {
let offset = read_encoded_offset(reader, encoding & 0x0F)?;
let offset = unsafe { read_encoded_offset(reader, encoding & 0x0F)? };
base_ptr.wrapping_add(offset)
};

if encoding & DW_EH_PE_indirect != 0 {
ptr = *(ptr.cast::<*const u8>());
ptr = unsafe { *(ptr.cast::<*const u8>()) };
}

Ok(ptr)
2 changes: 1 addition & 1 deletion library/std/src/sys/personality/dwarf/mod.rs
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
// This module is used only by x86_64-pc-windows-gnu for now, but we
// are compiling it everywhere to avoid regressions.
#![allow(unused)]
#![forbid(unsafe_op_in_unsafe_fn)]

#[cfg(test)]
mod tests;
@@ -17,7 +18,6 @@ pub struct DwarfReader {
pub ptr: *const u8,
}

#[forbid(unsafe_op_in_unsafe_fn)]
impl DwarfReader {
pub fn new(ptr: *const u8) -> DwarfReader {
DwarfReader { ptr }
58 changes: 37 additions & 21 deletions src/bootstrap/src/core/build_steps/check.rs
Original file line number Diff line number Diff line change
@@ -12,16 +12,6 @@ use crate::core::builder::{
use crate::core::config::TargetSelection;
use crate::{Compiler, Mode, Subcommand};

pub fn cargo_subcommand(kind: Kind) -> &'static str {
match kind {
Kind::Check
// We ensure check steps for both std and rustc from build_steps/clippy, so handle `Kind::Clippy` as well.
| Kind::Clippy => "check",
Kind::Fix => "fix",
_ => unreachable!(),
}
}

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Std {
pub target: TargetSelection,
@@ -31,11 +21,22 @@ pub struct Std {
///
/// [`compile::Rustc`]: crate::core::build_steps::compile::Rustc
crates: Vec<String>,
/// Override `Builder::kind` on cargo invocations.
///
/// By default, `Builder::kind` is propagated as the subcommand to the cargo invocations.
/// However, there are cases when this is not desirable. For example, when running `x clippy $tool_name`,
/// passing `Builder::kind` to cargo invocations would run clippy on the entire compiler and library,
/// which is not useful if we only want to lint a few crates with specific rules.
override_build_kind: Option<Kind>,
}

impl Std {
pub fn new(target: TargetSelection) -> Self {
Self { target, crates: vec![] }
Self::new_with_build_kind(target, None)
}

pub fn new_with_build_kind(target: TargetSelection, kind: Option<Kind>) -> Self {
Self { target, crates: vec![], override_build_kind: kind }
}
}

@@ -49,7 +50,7 @@ impl Step for Std {

fn make_run(run: RunConfig<'_>) {
let crates = run.make_run_crates(Alias::Library);
run.builder.ensure(Std { target: run.target, crates });
run.builder.ensure(Std { target: run.target, crates, override_build_kind: None });
}

fn run(self, builder: &Builder<'_>) {
@@ -64,7 +65,7 @@ impl Step for Std {
Mode::Std,
SourceType::InTree,
target,
cargo_subcommand(builder.kind),
self.override_build_kind.unwrap_or(builder.kind),
);

std_cargo(builder, target, compiler.stage, &mut cargo);
@@ -118,7 +119,7 @@ impl Step for Std {
Mode::Std,
SourceType::InTree,
target,
cargo_subcommand(builder.kind),
self.override_build_kind.unwrap_or(builder.kind),
);

// If we're not in stage 0, tests and examples will fail to compile
@@ -159,16 +160,31 @@ pub struct Rustc {
///
/// [`compile::Rustc`]: crate::core::build_steps::compile::Rustc
crates: Vec<String>,
/// Override `Builder::kind` on cargo invocations.
///
/// By default, `Builder::kind` is propagated as the subcommand to the cargo invocations.
/// However, there are cases when this is not desirable. For example, when running `x clippy $tool_name`,
/// passing `Builder::kind` to cargo invocations would run clippy on the entire compiler and library,
/// which is not useful if we only want to lint a few crates with specific rules.
override_build_kind: Option<Kind>,
}

impl Rustc {
pub fn new(target: TargetSelection, builder: &Builder<'_>) -> Self {
Self::new_with_build_kind(target, builder, None)
}

pub fn new_with_build_kind(
target: TargetSelection,
builder: &Builder<'_>,
kind: Option<Kind>,
) -> Self {
let crates = builder
.in_tree_crates("rustc-main", Some(target))
.into_iter()
.map(|krate| krate.name.to_string())
.collect();
Self { target, crates }
Self { target, crates, override_build_kind: kind }
}
}

@@ -183,7 +199,7 @@ impl Step for Rustc {

fn make_run(run: RunConfig<'_>) {
let crates = run.make_run_crates(Alias::Compiler);
run.builder.ensure(Rustc { target: run.target, crates });
run.builder.ensure(Rustc { target: run.target, crates, override_build_kind: None });
}

/// Builds the compiler.
@@ -204,7 +220,7 @@ impl Step for Rustc {
builder.ensure(crate::core::build_steps::compile::Std::new(compiler, compiler.host));
builder.ensure(crate::core::build_steps::compile::Std::new(compiler, target));
} else {
builder.ensure(Std::new(target));
builder.ensure(Std::new_with_build_kind(target, self.override_build_kind));
}

let mut cargo = builder::Cargo::new(
@@ -213,7 +229,7 @@ impl Step for Rustc {
Mode::Rustc,
SourceType::InTree,
target,
cargo_subcommand(builder.kind),
self.override_build_kind.unwrap_or(builder.kind),
);

rustc_cargo(builder, &mut cargo, target, &compiler);
@@ -291,7 +307,7 @@ impl Step for CodegenBackend {
Mode::Codegen,
SourceType::InTree,
target,
cargo_subcommand(builder.kind),
builder.kind,
);

cargo
@@ -349,7 +365,7 @@ impl Step for RustAnalyzer {
compiler,
Mode::ToolRustc,
target,
cargo_subcommand(builder.kind),
builder.kind,
"src/tools/rust-analyzer",
SourceType::InTree,
&["in-rust-tree".to_owned()],
@@ -417,7 +433,7 @@ macro_rules! tool_check_step {
compiler,
Mode::ToolRustc,
target,
cargo_subcommand(builder.kind),
builder.kind,
$path,
$source_type,
&[],
4 changes: 2 additions & 2 deletions src/bootstrap/src/core/build_steps/clean.rs
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ use std::path::Path;

use crate::core::builder::{crate_description, Builder, RunConfig, ShouldRun, Step};
use crate::utils::helpers::t;
use crate::{Build, Compiler, Mode, Subcommand};
use crate::{Build, Compiler, Kind, Mode, Subcommand};

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct CleanAll {}
@@ -66,7 +66,7 @@ macro_rules! clean_crate_tree {
fn run(self, builder: &Builder<'_>) -> Self::Output {
let compiler = self.compiler;
let target = compiler.host;
let mut cargo = builder.bare_cargo(compiler, $mode, target, "clean");
let mut cargo = builder.bare_cargo(compiler, $mode, target, Kind::Clean);

// Since https://github.com/rust-lang/rust/pull/111076 enables
// unstable cargo feature (`public-dependency`), we need to ensure
18 changes: 12 additions & 6 deletions src/bootstrap/src/core/build_steps/clippy.rs
Original file line number Diff line number Diff line change
@@ -116,8 +116,14 @@ impl Step for Std {
let target = self.target;
let compiler = builder.compiler(builder.top_stage, builder.config.build);

let mut cargo =
builder::Cargo::new(builder, compiler, Mode::Std, SourceType::InTree, target, "clippy");
let mut cargo = builder::Cargo::new(
builder,
compiler,
Mode::Std,
SourceType::InTree,
target,
Kind::Clippy,
);

std_cargo(builder, target, compiler.stage, &mut cargo);

@@ -178,7 +184,7 @@ impl Step for Rustc {
builder.ensure(compile::Std::new(compiler, compiler.host));
builder.ensure(compile::Std::new(compiler, target));
} else {
builder.ensure(check::Std::new(target));
builder.ensure(check::Std::new_with_build_kind(target, Some(Kind::Check)));
}

let mut cargo = builder::Cargo::new(
@@ -187,7 +193,7 @@ impl Step for Rustc {
Mode::Rustc,
SourceType::InTree,
target,
"clippy",
Kind::Clippy,
);

rustc_cargo(builder, &mut cargo, target, &compiler);
@@ -245,14 +251,14 @@ macro_rules! lint_any {
let compiler = builder.compiler(builder.top_stage, builder.config.build);
let target = self.target;

builder.ensure(check::Rustc::new(target, builder));
builder.ensure(check::Rustc::new_with_build_kind(target, builder, Some(Kind::Check)));

let cargo = prepare_tool_cargo(
builder,
compiler,
Mode::ToolRustc,
target,
"clippy",
Kind::Clippy,
$path,
SourceType::InTree,
&[],
8 changes: 4 additions & 4 deletions src/bootstrap/src/core/build_steps/compile.rs
Original file line number Diff line number Diff line change
@@ -247,7 +247,7 @@ impl Step for Std {
Mode::Std,
SourceType::InTree,
target,
"check",
Kind::Check,
);
cargo.rustflag("-Zalways-encode-mir");
cargo.arg("--manifest-path").arg(builder.src.join("library/sysroot/Cargo.toml"));
@@ -259,7 +259,7 @@ impl Step for Std {
Mode::Std,
SourceType::InTree,
target,
"build",
Kind::Build,
);
std_cargo(builder, target, compiler.stage, &mut cargo);
for krate in &*self.crates {
@@ -919,7 +919,7 @@ impl Step for Rustc {
Mode::Rustc,
SourceType::InTree,
target,
"build",
Kind::Build,
);

rustc_cargo(builder, &mut cargo, target, &compiler);
@@ -1359,7 +1359,7 @@ impl Step for CodegenBackend {
Mode::Codegen,
SourceType::InTree,
target,
"build",
Kind::Build,
);
cargo
.arg("--manifest-path")
14 changes: 10 additions & 4 deletions src/bootstrap/src/core/build_steps/doc.rs
Original file line number Diff line number Diff line change
@@ -714,7 +714,7 @@ fn doc_std(
let out_dir = target_dir.join(target.triple).join("doc");

let mut cargo =
builder::Cargo::new(builder, compiler, Mode::Std, SourceType::InTree, target, "doc");
builder::Cargo::new(builder, compiler, Mode::Std, SourceType::InTree, target, Kind::Doc);

compile::std_cargo(builder, target, compiler.stage, &mut cargo);
cargo
@@ -816,8 +816,14 @@ impl Step for Rustc {
);

// Build cargo command.
let mut cargo =
builder::Cargo::new(builder, compiler, Mode::Rustc, SourceType::InTree, target, "doc");
let mut cargo = builder::Cargo::new(
builder,
compiler,
Mode::Rustc,
SourceType::InTree,
target,
Kind::Doc,
);

cargo.rustdocflag("--document-private-items");
// Since we always pass --document-private-items, there's no need to warn about linking to private items.
@@ -964,7 +970,7 @@ macro_rules! tool_doc {
compiler,
Mode::ToolRustc,
target,
"doc",
Kind::Doc,
$path,
source_type,
&[],
4 changes: 2 additions & 2 deletions src/bootstrap/src/core/build_steps/run.rs
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ use std::path::PathBuf;
use crate::core::build_steps::dist::distdir;
use crate::core::build_steps::test;
use crate::core::build_steps::tool::{self, SourceType, Tool};
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step};
use crate::core::config::flags::get_completion;
use crate::core::config::TargetSelection;
use crate::utils::exec::command;
@@ -142,7 +142,7 @@ impl Step for Miri {
host_compiler,
Mode::ToolRustc,
host,
"run",
Kind::Run,
"src/tools/miri",
SourceType::InTree,
&[],
53 changes: 23 additions & 30 deletions src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ impl Step for CrateBootstrap {
compiler,
Mode::ToolBootstrap,
bootstrap_host,
"test",
Kind::Test,
path,
SourceType::InTree,
&[],
@@ -119,7 +119,7 @@ You can skip linkcheck with --skip src/tools/linkchecker"
compiler,
Mode::ToolBootstrap,
bootstrap_host,
"test",
Kind::Test,
"src/tools/linkchecker",
SourceType::InTree,
&[],
@@ -284,7 +284,7 @@ impl Step for Cargo {
compiler,
Mode::ToolRustc,
self.host,
"test",
Kind::Test,
"src/tools/cargo",
SourceType::Submodule,
&[],
@@ -355,7 +355,7 @@ impl Step for RustAnalyzer {
compiler,
Mode::ToolRustc,
host,
"test",
Kind::Test,
crate_path,
SourceType::InTree,
&["in-rust-tree".to_owned()],
@@ -407,7 +407,7 @@ impl Step for Rustfmt {
compiler,
Mode::ToolRustc,
host,
"test",
Kind::Test,
"src/tools/rustfmt",
SourceType::InTree,
&[],
@@ -442,7 +442,7 @@ impl Miri {
Mode::Std,
SourceType::Submodule,
target,
"miri-setup",
Kind::MiriSetup,
);

// Tell `cargo miri setup` where to find the sources.
@@ -527,7 +527,7 @@ impl Step for Miri {
host_compiler,
Mode::ToolRustc,
host,
"test",
Kind::Test,
"src/tools/miri",
SourceType::InTree,
&[],
@@ -617,7 +617,7 @@ impl Step for CargoMiri {
compiler,
Mode::ToolStd, // it's unclear what to use here, we're not building anything just doing a smoke test!
target,
"miri-test",
Kind::MiriTest,
"src/tools/miri/test-cargo-miri",
SourceType::Submodule,
&[],
@@ -677,7 +677,7 @@ impl Step for CompiletestTest {
// when std sources change.
Mode::ToolStd,
host,
"test",
Kind::Test,
"src/tools/compiletest",
SourceType::InTree,
&[],
@@ -727,7 +727,7 @@ impl Step for Clippy {
compiler,
Mode::ToolRustc,
host,
"test",
Kind::Test,
"src/tools/clippy",
SourceType::InTree,
&[],
@@ -1277,7 +1277,7 @@ impl Step for RunMakeSupport {
self.compiler,
Mode::ToolStd,
self.target,
"build",
Kind::Build,
"src/tools/run-make-support",
SourceType::InTree,
&[],
@@ -1321,7 +1321,7 @@ impl Step for CrateRunMakeSupport {
compiler,
Mode::ToolBootstrap,
host,
"test",
Kind::Test,
"src/tools/run-make-support",
SourceType::InTree,
&[],
@@ -1367,7 +1367,7 @@ impl Step for CrateBuildHelper {
compiler,
Mode::ToolBootstrap,
host,
"test",
Kind::Test,
"src/tools/build_helper",
SourceType::InTree,
&[],
@@ -2631,7 +2631,7 @@ impl Step for Crate {
mode,
SourceType::InTree,
target,
"miri-test",
Kind::MiriTest,
);
// This hack helps bootstrap run standard library tests in Miri. The issue is as
// follows: when running `cargo miri test` on libcore, cargo builds a local copy of core
@@ -2654,14 +2654,7 @@ impl Step for Crate {
}

// Build `cargo test` command
builder::Cargo::new(
builder,
compiler,
mode,
SourceType::InTree,
target,
builder.kind.as_str(),
)
builder::Cargo::new(builder, compiler, mode, SourceType::InTree, target, builder.kind)
};

match mode {
@@ -2753,7 +2746,7 @@ impl Step for CrateRustdoc {
compiler,
Mode::ToolRustc,
target,
builder.kind.as_str(),
builder.kind,
"src/tools/rustdoc",
SourceType::InTree,
&[],
@@ -2845,7 +2838,7 @@ impl Step for CrateRustdocJsonTypes {
compiler,
Mode::ToolRustc,
target,
builder.kind.as_str(),
builder.kind,
"src/rustdoc-json-types",
SourceType::InTree,
&[],
@@ -3079,7 +3072,7 @@ impl Step for TierCheck {
self.compiler,
Mode::ToolStd,
self.compiler.host,
"run",
Kind::Run,
"src/tools/tier-check",
SourceType::InTree,
&[],
@@ -3151,7 +3144,7 @@ impl Step for RustInstaller {
compiler,
Mode::ToolBootstrap,
bootstrap_host,
"test",
Kind::Test,
"src/tools/rust-installer",
SourceType::InTree,
&[],
@@ -3321,7 +3314,7 @@ impl Step for CodegenCranelift {
Mode::Codegen, // Must be codegen to ensure dlopen on compiled dylibs works
SourceType::InTree,
target,
"run",
Kind::Run,
);

cargo.current_dir(&builder.src.join("compiler/rustc_codegen_cranelift"));
@@ -3453,7 +3446,7 @@ impl Step for CodegenGCC {
Mode::Codegen, // Must be codegen to ensure dlopen on compiled dylibs works
SourceType::InTree,
target,
"run",
Kind::Run,
);

cargo.current_dir(&builder.src.join("compiler/rustc_codegen_gcc"));
@@ -3541,7 +3534,7 @@ impl Step for TestFloatParse {
compiler,
Mode::ToolStd,
bootstrap_host,
"test",
Kind::Test,
path,
SourceType::InTree,
&[],
@@ -3564,7 +3557,7 @@ impl Step for TestFloatParse {
compiler,
Mode::ToolStd,
bootstrap_host,
"run",
Kind::Run,
path,
SourceType::InTree,
&[],
10 changes: 5 additions & 5 deletions src/bootstrap/src/core/build_steps/tool.rs
Original file line number Diff line number Diff line change
@@ -90,7 +90,7 @@ impl Step for ToolBuild {
compiler,
self.mode,
target,
"build",
Kind::Build,
path,
self.source_type,
&self.extra_features,
@@ -136,12 +136,12 @@ pub fn prepare_tool_cargo(
compiler: Compiler,
mode: Mode,
target: TargetSelection,
command: &'static str,
cmd_kind: Kind,
path: &str,
source_type: SourceType,
extra_features: &[String],
) -> CargoCommand {
let mut cargo = builder::Cargo::new(builder, compiler, mode, source_type, target, command);
let mut cargo = builder::Cargo::new(builder, compiler, mode, source_type, target, cmd_kind);

let dir = builder.src.join(path);
cargo.arg("--manifest-path").arg(dir.join("Cargo.toml"));
@@ -646,7 +646,7 @@ impl Step for Rustdoc {
build_compiler,
Mode::ToolRustc,
target,
"build",
Kind::Build,
"src/tools/rustdoc",
SourceType::InTree,
features.as_slice(),
@@ -905,7 +905,7 @@ impl Step for LlvmBitcodeLinker {
self.compiler,
Mode::ToolRustc,
self.target,
"build",
Kind::Build,
"src/tools/llvm-bitcode-linker",
SourceType::InTree,
&self.extra_features,
99 changes: 56 additions & 43 deletions src/bootstrap/src/core/builder.rs
Original file line number Diff line number Diff line change
@@ -689,7 +689,7 @@ impl<'a> ShouldRun<'a> {
}
}

#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)]
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, PartialOrd, Ord, ValueEnum)]
pub enum Kind {
#[value(alias = "b")]
Build,
@@ -701,6 +701,8 @@ pub enum Kind {
#[value(alias = "t")]
Test,
Miri,
MiriSetup,
MiriTest,
Bench,
#[value(alias = "d")]
Doc,
@@ -725,6 +727,8 @@ impl Kind {
Kind::Format => "fmt",
Kind::Test => "test",
Kind::Miri => "miri",
Kind::MiriSetup => panic!("`as_str` is not supported for `Kind::MiriSetup`."),
Kind::MiriTest => panic!("`as_str` is not supported for `Kind::MiriTest`."),
Kind::Bench => "bench",
Kind::Doc => "doc",
Kind::Clean => "clean",
@@ -1000,6 +1004,7 @@ impl<'a> Builder<'a> {
Kind::Vendor => describe!(vendor::Vendor),
// special-cased in Build::build()
Kind::Format | Kind::Suggest | Kind::Perf => vec![],
Kind::MiriTest | Kind::MiriSetup => unreachable!(),
}
}

@@ -1386,23 +1391,30 @@ impl<'a> Builder<'a> {
compiler: Compiler,
mode: Mode,
target: TargetSelection,
cmd: &str, // FIXME make this properly typed
cmd_kind: Kind,
) -> BootstrapCommand {
let mut cargo;
if cmd == "clippy" {
cargo = self.cargo_clippy_cmd(compiler);
cargo.arg(cmd);
} else if let Some(subcmd) = cmd.strip_prefix("miri") {
// Command must be "miri-X".
let subcmd = subcmd
.strip_prefix('-')
.unwrap_or_else(|| panic!("expected `miri-$subcommand`, but got {}", cmd));
cargo = self.cargo_miri_cmd(compiler);
cargo.arg("miri").arg(subcmd);
} else {
cargo = command(&self.initial_cargo);
cargo.arg(cmd);
}
let mut cargo = match cmd_kind {
Kind::Clippy => {
let mut cargo = self.cargo_clippy_cmd(compiler);
cargo.arg(cmd_kind.as_str());
cargo
}
Kind::MiriSetup => {
let mut cargo = self.cargo_miri_cmd(compiler);
cargo.arg("miri").arg("setup");
cargo
}
Kind::MiriTest => {
let mut cargo = self.cargo_miri_cmd(compiler);
cargo.arg("miri").arg("test");
cargo
}
_ => {
let mut cargo = command(&self.initial_cargo);
cargo.arg(cmd_kind.as_str());
cargo
}
};

// Run cargo from the source root so it can find .cargo/config.
// This matters when using vendoring and the working directory is outside the repository.
@@ -1431,7 +1443,7 @@ impl<'a> Builder<'a> {
Color::Auto => {} // nothing to do
}

if cmd != "install" {
if cmd_kind != Kind::Install {
cargo.arg("--target").arg(target.rustc_target_arg());
} else {
assert_eq!(target, compiler.host);
@@ -1440,8 +1452,11 @@ impl<'a> Builder<'a> {
if self.config.rust_optimize.is_release() {
// FIXME: cargo bench/install do not accept `--release`
// and miri doesn't want it
if cmd != "bench" && cmd != "install" && !cmd.starts_with("miri-") {
cargo.arg("--release");
match cmd_kind {
Kind::Bench | Kind::Install | Kind::Miri | Kind::MiriSetup | Kind::MiriTest => {}
_ => {
cargo.arg("--release");
}
}
}

@@ -1464,9 +1479,9 @@ impl<'a> Builder<'a> {
mode: Mode,
source_type: SourceType,
target: TargetSelection,
cmd: &str, // FIXME make this properly typed
cmd_kind: Kind,
) -> Cargo {
let mut cargo = self.bare_cargo(compiler, mode, target, cmd);
let mut cargo = self.bare_cargo(compiler, mode, target, cmd_kind);
let out_dir = self.stage_out(compiler, mode);

let mut hostflags = HostFlags::default();
@@ -1477,7 +1492,7 @@ impl<'a> Builder<'a> {
self.clear_if_dirty(&out_dir, &backend);
}

if cmd == "doc" || cmd == "rustdoc" {
if cmd_kind == Kind::Doc {
let my_out = match mode {
// This is the intended out directory for compiler documentation.
Mode::Rustc | Mode::ToolRustc => self.compiler_doc_out(target),
@@ -1508,7 +1523,7 @@ impl<'a> Builder<'a> {

// Set a flag for `check`/`clippy`/`fix`, so that certain build
// scripts can do less work (i.e. not building/requiring LLVM).
if cmd == "check" || cmd == "clippy" || cmd == "fix" {
if matches!(cmd_kind, Kind::Check | Kind::Clippy | Kind::Fix) {
// If we've not yet built LLVM, or it's stale, then bust
// the rustc_llvm cache. That will always work, even though it
// may mean that on the next non-check build we'll need to rebuild
@@ -1558,7 +1573,7 @@ impl<'a> Builder<'a> {
rustflags.arg("--cfg=bootstrap");
}

if cmd == "clippy" {
if cmd_kind == Kind::Clippy {
// clippy overwrites sysroot if we pass it to cargo.
// Pass it directly to clippy instead.
// NOTE: this can't be fixed in clippy because we explicitly don't set `RUSTC`,
@@ -1654,7 +1669,7 @@ impl<'a> Builder<'a> {
Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {}
Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
// Build proc macros both for the host and the target
if target != compiler.host && cmd != "check" {
if target != compiler.host && cmd_kind != Kind::Check {
cargo.arg("-Zdual-proc-macros");
rustflags.arg("-Zdual-proc-macros");
}
@@ -1739,7 +1754,7 @@ impl<'a> Builder<'a> {
}
cargo.env("__CARGO_DEFAULT_LIB_METADATA", &metadata);

if cmd == "clippy" {
if cmd_kind == Kind::Clippy {
rustflags.arg("-Zforce-unstable-if-unmarked");
}

@@ -1755,10 +1770,15 @@ impl<'a> Builder<'a> {
//
// Only clear out the directory if we're compiling std; otherwise, we
// should let Cargo take care of things for us (via depdep info)
if !self.config.dry_run() && mode == Mode::Std && cmd == "build" {
if !self.config.dry_run() && mode == Mode::Std && cmd_kind == Kind::Build {
self.clear_if_dirty(&out_dir, &self.rustc(compiler));
}

let rustdoc_path = match cmd_kind {
Kind::Doc | Kind::Test | Kind::MiriTest => self.rustdoc(compiler),
_ => PathBuf::from("/path/to/nowhere/rustdoc/not/required"),
};

// Customize the compiler we're running. Specify the compiler to cargo
// as our shim and then pass it some various options used to configure
// how the actual compiler itself is called.
@@ -1772,15 +1792,7 @@ impl<'a> Builder<'a> {
.env("RUSTC_SYSROOT", sysroot)
.env("RUSTC_LIBDIR", libdir)
.env("RUSTDOC", self.bootstrap_out.join("rustdoc"))
.env(
"RUSTDOC_REAL",
// Make sure to handle both `test` and `miri-test` commands.
if cmd == "doc" || cmd == "rustdoc" || (cmd.ends_with("test") && want_rustdoc) {
self.rustdoc(compiler)
} else {
PathBuf::from("/path/to/nowhere/rustdoc/not/required")
},
)
.env("RUSTDOC_REAL", rustdoc_path)
.env("RUSTC_ERROR_METADATA_DST", self.extended_error_dir())
.env("RUSTC_BREAK_ON_ICE", "1");

@@ -1799,7 +1811,7 @@ impl<'a> Builder<'a> {
}

// If this is for `miri-test`, prepare the sysroots.
if cmd == "miri-test" {
if cmd_kind == Kind::MiriTest {
self.ensure(compile::Std::new(compiler, compiler.host));
let host_sysroot = self.sysroot(compiler);
let miri_sysroot = test::Miri::build_miri_sysroot(self, compiler, target);
@@ -1813,7 +1825,8 @@ impl<'a> Builder<'a> {
rustflags.arg(&format!("-Zstack-protector={stack_protector}"));
}

if !(["build", "check", "clippy", "fix", "rustc"].contains(&cmd)) && want_rustdoc {
if !matches!(cmd_kind, Kind::Build | Kind::Check | Kind::Clippy | Kind::Fix) && want_rustdoc
{
cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler));
}

@@ -2430,9 +2443,9 @@ impl Cargo {
mode: Mode,
source_type: SourceType,
target: TargetSelection,
cmd: &str, // FIXME make this properly typed
cmd_kind: Kind,
) -> Cargo {
let mut cargo = builder.cargo(compiler, mode, source_type, target, cmd);
let mut cargo = builder.cargo(compiler, mode, source_type, target, cmd_kind);
cargo.configure_linker(builder);
cargo
}
@@ -2448,9 +2461,9 @@ impl Cargo {
mode: Mode,
source_type: SourceType,
target: TargetSelection,
cmd: &str, // FIXME make this properly typed
cmd_kind: Kind,
) -> Cargo {
builder.cargo(compiler, mode, source_type, target, cmd)
builder.cargo(compiler, mode, source_type, target, cmd_kind)
}

pub fn rustdocflag(&mut self, arg: &str) -> &mut Cargo {
585 changes: 533 additions & 52 deletions src/rustdoc-json-types/lib.rs

Large diffs are not rendered by default.