Skip to content

Commit

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

Rollup of 7 pull requests

Successful merges:

 - rust-lang#123942 (`x vendor`)
 - rust-lang#124165 (add test for incremental ICE: slice-pattern-const.rs rust-lang#83085)
 - rust-lang#124210 (Abort a process when FD ownership is violated)
 - rust-lang#124242 (bootstrap: Describe build_steps modules)
 - rust-lang#124406 (Remove unused `[patch]` for clippy_lints)
 - rust-lang#124429 (bootstrap: Document `struct Builder` and its fields)
 - rust-lang#124447 (Unconditionally call `really_init` on GNU/Linux)

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Apr 27, 2024
2 parents aed2187 + 0b5e173 commit cdd02e9
Show file tree
Hide file tree
Showing 25 changed files with 489 additions and 32 deletions.
3 changes: 0 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,3 @@ strip = true
rustc-std-workspace-core = { path = 'library/rustc-std-workspace-core' }
rustc-std-workspace-alloc = { path = 'library/rustc-std-workspace-alloc' }
rustc-std-workspace-std = { path = 'library/rustc-std-workspace-std' }

[patch."https://github.com/rust-lang/rust-clippy"]
clippy_lints = { path = "src/tools/clippy/clippy_lints" }
2 changes: 1 addition & 1 deletion library/core/src/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2767,7 +2767,7 @@ pub const unsafe fn typed_swap<T>(x: *mut T, y: *mut T) {
#[unstable(feature = "core_intrinsics", issue = "none")]
#[inline(always)]
#[cfg_attr(not(bootstrap), rustc_intrinsic)] // just make it a regular fn in bootstrap
pub(crate) const fn ub_checks() -> bool {
pub const fn ub_checks() -> bool {
cfg!(debug_assertions)
}

Expand Down
4 changes: 3 additions & 1 deletion library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@
#![feature(str_split_inclusive_remainder)]
#![feature(str_split_remainder)]
#![feature(strict_provenance)]
#![feature(ub_checks)]
#![feature(unchecked_shifts)]
#![feature(utf16_extra)]
#![feature(utf16_extra_const)]
Expand Down Expand Up @@ -370,7 +371,8 @@ pub mod hint;
pub mod intrinsics;
pub mod mem;
pub mod ptr;
mod ub_checks;
#[unstable(feature = "ub_checks", issue = "none")]
pub mod ub_checks;

/* Core language traits */

Expand Down
8 changes: 6 additions & 2 deletions library/core/src/ub_checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ use crate::intrinsics::{self, const_eval_select};
/// variables cannot be optimized out in MIR, an innocent-looking `let` can produce enough
/// debuginfo to have a measurable compile-time impact on debug builds.
#[allow_internal_unstable(const_ub_checks)] // permit this to be called in stably-const fn
#[macro_export]
#[unstable(feature = "ub_checks", issue = "none")]
macro_rules! assert_unsafe_precondition {
($kind:ident, $message:expr, ($($name:ident:$ty:ty = $arg:expr),*$(,)?) => $e:expr $(,)?) => {
{
Expand Down Expand Up @@ -75,11 +77,13 @@ macro_rules! assert_unsafe_precondition {
}
};
}
pub(crate) use assert_unsafe_precondition;
#[unstable(feature = "ub_checks", issue = "none")]
pub use assert_unsafe_precondition;

/// Checking library UB is always enabled when UB-checking is done
/// (and we use a reexport so that there is no unnecessary wrapper function).
pub(crate) use intrinsics::ub_checks as check_library_ub;
#[unstable(feature = "ub_checks", issue = "none")]
pub use intrinsics::ub_checks as check_library_ub;

/// Determines whether we should check for language UB.
///
Expand Down
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@
#![feature(str_internals)]
#![feature(strict_provenance)]
#![feature(strict_provenance_atomic_ptr)]
#![feature(ub_checks)]
// tidy-alphabetical-end
//
// Library features (alloc):
Expand Down
5 changes: 4 additions & 1 deletion library/std/src/os/fd/owned.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,10 @@ impl Drop for OwnedFd {
// something like EINTR), we might close another valid file descriptor
// opened after we closed ours.
#[cfg(not(target_os = "hermit"))]
let _ = libc::close(self.fd);
{
crate::sys::fs::debug_assert_fd_is_open(self.fd);
let _ = libc::close(self.fd);
}
#[cfg(target_os = "hermit")]
let _ = hermit_abi::close(self.fd);
}
Expand Down
10 changes: 4 additions & 6 deletions library/std/src/sys/pal/unix/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,10 @@ mod imp {
}

#[inline(always)]
pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
// On Linux-GNU, we rely on `ARGV_INIT_ARRAY` below to initialize
// `ARGC` and `ARGV`. But in Miri that does not actually happen so we
// still initialize here.
#[cfg(any(miri, not(all(target_os = "linux", target_env = "gnu"))))]
really_init(_argc, _argv);
pub unsafe fn init(argc: isize, argv: *const *const u8) {
// on GNU/Linux if we are main then we will init argv and argc twice, it "duplicates work"
// BUT edge-cases are real: only using .init_array can break most emulators, dlopen, etc.
really_init(argc, argv);
}

/// glibc passes argc, argv, and envp to functions in .init_array, as a non-standard extension.
Expand Down
32 changes: 32 additions & 0 deletions library/std/src/sys/pal/unix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -864,8 +864,40 @@ impl Iterator for ReadDir {
}
}

/// Aborts the process if a file desceriptor is not open, if debug asserts are enabled
///
/// Many IO syscalls can't be fully trusted about EBADF error codes because those
/// might get bubbled up from a remote FUSE server rather than the file descriptor
/// in the current process being invalid.
///
/// So we check file flags instead which live on the file descriptor and not the underlying file.
/// The downside is that it costs an extra syscall, so we only do it for debug.
#[inline]
pub(crate) fn debug_assert_fd_is_open(fd: RawFd) {
use crate::sys::os::errno;

// this is similar to assert_unsafe_precondition!() but it doesn't require const
if core::ub_checks::check_library_ub() {
if unsafe { libc::fcntl(fd, libc::F_GETFD) } == -1 && errno() == libc::EBADF {
rtabort!("IO Safety violation: owned file descriptor already closed");
}
}
}

impl Drop for Dir {
fn drop(&mut self) {
// dirfd isn't supported everywhere
#[cfg(not(any(
miri,
target_os = "redox",
target_os = "nto",
target_os = "vita",
target_os = "hurd",
)))]
{
let fd = unsafe { libc::dirfd(self.0) };
debug_assert_fd_is_open(fd);
}
let r = unsafe { libc::closedir(self.0) };
assert!(
r == 0 || crate::io::Error::last_os_error().is_interrupted(),
Expand Down
8 changes: 1 addition & 7 deletions src/bootstrap/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -1035,14 +1035,8 @@ def check_vendored_status(self):
if self.use_vendored_sources:
vendor_dir = os.path.join(self.rust_root, 'vendor')
if not os.path.exists(vendor_dir):
sync_dirs = "--sync ./src/tools/cargo/Cargo.toml " \
"--sync ./src/tools/rust-analyzer/Cargo.toml " \
"--sync ./compiler/rustc_codegen_cranelift/Cargo.toml " \
"--sync ./compiler/rustc_codegen_gcc/Cargo.toml " \
"--sync ./src/bootstrap/Cargo.toml "
eprint('ERROR: vendoring required, but vendor directory does not exist.')
eprint(' Run `cargo vendor {}` to initialize the '
'vendor directory.'.format(sync_dirs))
eprint(' Run `x.py vendor` to initialize the vendor directory.')
eprint(' Alternatively, use the pre-vendored `rustc-src` dist component.')
eprint(' To get a stable/beta/nightly version, download it from: ')
eprint(' '
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/src/core/build_steps/clean.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Implementation of `make clean` in rustbuild.
//! `./x.py clean`
//!
//! Responsible for cleaning out a build directory of all old and stale
//! artifacts to prepare for a fresh build. Currently doesn't remove the
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/src/core/build_steps/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ pub(crate) mod synthetic_targets;
pub(crate) mod test;
pub(crate) mod tool;
pub(crate) mod toolstate;
pub(crate) mod vendor;
5 changes: 5 additions & 0 deletions src/bootstrap/src/core/build_steps/run.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
//! Build-and-run steps for in-repo tools
//!
//! A bit of a hodge-podge as e.g. if a tool's a test fixture it should be in `build_steps::test`.
//! If it can be reached from `./x.py run` it can go here.
use std::path::PathBuf;
use std::process::Command;

Expand Down
13 changes: 11 additions & 2 deletions src/bootstrap/src/core/build_steps/setup.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
//! First time setup of a dev environment
//!
//! These are build-and-run steps for `./x.py setup`, which allows quickly setting up the directory
//! for modifying, building, and running the compiler and library. Running arbitrary configuration
//! allows setting up things that cannot be simply captured inside the config.toml, in addition to
//! leading people away from manually editing most of the config.toml values.
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::t;
use crate::utils::change_tracker::CONFIG_CHANGE_HISTORY;
Expand Down Expand Up @@ -25,6 +32,8 @@ pub enum Profile {
None,
}

static PROFILE_DIR: &str = "src/bootstrap/defaults";

/// A list of historical hashes of `src/etc/rust_analyzer_settings.json`.
/// New entries should be appended whenever this is updated so we can detect
/// outdated vs. user-modified settings files.
Expand All @@ -41,7 +50,7 @@ static RUST_ANALYZER_SETTINGS: &str = include_str!("../../../../etc/rust_analyze

impl Profile {
fn include_path(&self, src_path: &Path) -> PathBuf {
PathBuf::from(format!("{}/src/bootstrap/defaults/config.{}.toml", src_path.display(), self))
PathBuf::from(format!("{}/{PROFILE_DIR}/config.{}.toml", src_path.display(), self))
}

pub fn all() -> impl Iterator<Item = Self> {
Expand Down Expand Up @@ -220,7 +229,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {

let latest_change_id = CONFIG_CHANGE_HISTORY.last().unwrap().change_id;
let settings = format!(
"# Includes one of the default files in src/bootstrap/defaults\n\
"# Includes one of the default files in {PROFILE_DIR}\n\
profile = \"{profile}\"\n\
change-id = {latest_change_id}\n"
);
Expand Down
2 changes: 2 additions & 0 deletions src/bootstrap/src/core/build_steps/suggest.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Attempt to magically identify good tests to run
#![cfg_attr(feature = "build-metrics", allow(unused))]

use clap::Parser;
Expand Down
6 changes: 3 additions & 3 deletions src/bootstrap/src/core/build_steps/test.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Implementation of the test-related targets of the build system.
//! Build-and-run steps for `./x.py test` test fixtures
//!
//! This file implements the various regression test suites that we execute on
//! our CI.
//! `./x.py test` (aka [`Kind::Test`]) is currently allowed to reach build steps in other modules.
//! However, this contains ~all test parts we expect people to be able to build and run locally.
use std::env;
use std::ffi::OsStr;
Expand Down
6 changes: 6 additions & 0 deletions src/bootstrap/src/core/build_steps/toolstate.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
//! [Toolstate] checks to keep tools building
//!
//! Reachable via `./x.py test` but mostly relevant for CI, since it isn't run locally by default.
//!
//! [Toolstate]: https://forge.rust-lang.org/infra/toolstate.html
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
use crate::utils::helpers::t;
use serde_derive::{Deserialize, Serialize};
Expand Down
61 changes: 61 additions & 0 deletions src/bootstrap/src/core/build_steps/vendor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use crate::core::builder::{Builder, RunConfig, ShouldRun, Step};
use std::path::PathBuf;
use std::process::Command;

#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub(crate) struct Vendor {
sync_args: Vec<PathBuf>,
versioned_dirs: bool,
root_dir: PathBuf,
}

impl Step for Vendor {
type Output = ();
const DEFAULT: bool = true;
const ONLY_HOSTS: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.alias("placeholder").default_condition(true)
}

fn make_run(run: RunConfig<'_>) {
run.builder.ensure(Vendor {
sync_args: run.builder.config.cmd.vendor_sync_args(),
versioned_dirs: run.builder.config.cmd.vendor_versioned_dirs(),
root_dir: run.builder.src.clone(),
});
}

fn run(self, builder: &Builder<'_>) -> Self::Output {
let mut cmd = Command::new(&builder.initial_cargo);
cmd.arg("vendor");

if self.versioned_dirs {
cmd.arg("--versioned-dirs");
}

// Sync these paths by default.
for p in [
"src/tools/cargo/Cargo.toml",
"src/tools/rust-analyzer/Cargo.toml",
"compiler/rustc_codegen_cranelift/Cargo.toml",
"compiler/rustc_codegen_gcc/Cargo.toml",
"src/bootstrap/Cargo.toml",
] {
cmd.arg("--sync").arg(builder.src.join(p));
}

// Also sync explicitly requested paths.
for sync_arg in self.sync_args {
cmd.arg("--sync").arg(sync_arg);
}

// Will read the libstd Cargo.toml
// which uses the unstable `public-dependency` feature.
cmd.env("RUSTC_BOOTSTRAP", "1");

cmd.current_dir(self.root_dir);

builder.run(&mut cmd);
}
}
30 changes: 28 additions & 2 deletions src/bootstrap/src/core/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ use std::sync::OnceLock;
use std::time::{Duration, Instant};

use crate::core::build_steps::tool::{self, SourceType};
use crate::core::build_steps::{check, clean, compile, dist, doc, install, run, setup, test};
use crate::core::build_steps::{clippy, llvm};
use crate::core::build_steps::{
check, clean, clippy, compile, dist, doc, install, llvm, run, setup, test, vendor,
};
use crate::core::config::flags::{Color, Subcommand};
use crate::core::config::{DryRun, SplitDebuginfo, TargetSelection};
use crate::prepare_behaviour_dump_dir;
Expand All @@ -34,13 +35,34 @@ use once_cell::sync::Lazy;
#[cfg(test)]
mod tests;

/// Builds and performs different [`Self::kind`]s of stuff and actions, taking
/// into account build configuration from e.g. config.toml.
pub struct Builder<'a> {
/// Build configuration from e.g. config.toml.
pub build: &'a Build,

/// The stage to use. Either implicitly determined based on subcommand, or
/// explicitly specified with `--stage N`. Normally this is the stage we
/// use, but sometimes we want to run steps with a lower stage than this.
pub top_stage: u32,

/// What to build or what action to perform.
pub kind: Kind,

/// A cache of outputs of [`Step`]s so we can avoid running steps we already
/// ran.
cache: Cache,

/// A stack of [`Step`]s to run before we can run this builder. The output
/// of steps is cached in [`Self::cache`].
stack: RefCell<Vec<Box<dyn Any>>>,

/// The total amount of time we spent running [`Step`]s in [`Self::stack`].
time_spent_on_dependencies: Cell<Duration>,

/// The paths passed on the command line. Used by steps to figure out what
/// to do. For example: with `./x check foo bar` we get `paths=["foo",
/// "bar"]`.
pub paths: Vec<PathBuf>,
}

Expand Down Expand Up @@ -638,6 +660,7 @@ pub enum Kind {
Run,
Setup,
Suggest,
Vendor,
}

impl Kind {
Expand All @@ -658,6 +681,7 @@ impl Kind {
Kind::Run => "run",
Kind::Setup => "setup",
Kind::Suggest => "suggest",
Kind::Vendor => "vendor",
}
}

Expand Down Expand Up @@ -921,6 +945,7 @@ impl<'a> Builder<'a> {
),
Kind::Setup => describe!(setup::Profile, setup::Hook, setup::Link, setup::Vscode),
Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std),
Kind::Vendor => describe!(vendor::Vendor),
// special-cased in Build::build()
Kind::Format | Kind::Suggest => vec![],
}
Expand Down Expand Up @@ -993,6 +1018,7 @@ impl<'a> Builder<'a> {
Kind::Setup,
path.as_ref().map_or([].as_slice(), |path| std::slice::from_ref(path)),
),
Subcommand::Vendor { .. } => (Kind::Vendor, &paths[..]),
};

Self::new_internal(build, kind, paths.to_owned())
Expand Down
Loading

0 comments on commit cdd02e9

Please sign in to comment.