diff options
| author | The Miri Cronjob Bot <miri@cron.bot> | 2024-12-31 05:12:50 +0000 |
|---|---|---|
| committer | The Miri Cronjob Bot <miri@cron.bot> | 2024-12-31 05:12:50 +0000 |
| commit | e898da11d2149358e87f7c4f89dcc0654fcfac3b (patch) | |
| tree | 6f09bd54aead12fa9e0155cda3dcb7e0f46f97ae /src | |
| parent | 332fefbd3e686d0d76a43119e374997543338389 (diff) | |
| parent | 5079acc060b1c7225de95ee3cdd84b5719ff189c (diff) | |
| download | rust-e898da11d2149358e87f7c4f89dcc0654fcfac3b.tar.gz rust-e898da11d2149358e87f7c4f89dcc0654fcfac3b.zip | |
Merge from rustc
Diffstat (limited to 'src')
86 files changed, 792 insertions, 419 deletions
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 6da716b7a89..d8775a67e19 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -7,7 +7,6 @@ default-run = "bootstrap" [features] build-metrics = ["sysinfo"] -bootstrap-self-test = [] # enabled in the bootstrap unit tests [lib] path = "src/lib.rs" diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs index 88595ff7e51..61045067592 100644 --- a/src/bootstrap/src/bin/rustc.rs +++ b/src/bootstrap/src/bin/rustc.rs @@ -28,6 +28,9 @@ use shared_helpers::{ #[path = "../utils/shared_helpers.rs"] mod shared_helpers; +#[path = "../utils/proc_macro_deps.rs"] +mod proc_macro_deps; + fn main() { let orig_args = env::args_os().skip(1).collect::<Vec<_>>(); let mut args = orig_args.clone(); @@ -167,7 +170,7 @@ fn main() { // issue https://github.com/rust-lang/rust/issues/100530 if env::var("RUSTC_TLS_MODEL_INITIAL_EXEC").is_ok() && crate_type != Some("proc-macro") - && !matches!(crate_name, Some("proc_macro2" | "quote" | "syn" | "synstructure")) + && proc_macro_deps::CRATES.binary_search(&crate_name.unwrap_or_default()).is_err() { cmd.arg("-Ztls-model=initial-exec"); } diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index f32d95fe836..b4d37b25a6c 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -501,6 +501,9 @@ tool_check_step!( ); tool_check_step!(Bootstrap, "bootstrap", "src/bootstrap", SourceType::InTree, false); +// Compiletest is implicitly "checked" when it gets built in order to run tests, +// so this is mainly for people working on compiletest to run locally. +tool_check_step!(Compiletest, "compiletest", "src/tools/compiletest", SourceType::InTree, false); /// Cargo's output path for the standard library in a given stage, compiled /// by a particular compiler for the specified target. diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index d30a0d028ff..ca337aa9f4c 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -396,7 +396,7 @@ fn copy_self_contained_objects( /// Resolves standard library crates for `Std::run_make` for any build kind (like check, build, clippy, etc.). pub fn std_crates_for_run_make(run: &RunConfig<'_>) -> Vec<String> { // FIXME: Extend builder tests to cover the `crates` field of `Std` instances. - if cfg!(feature = "bootstrap-self-test") { + if cfg!(test) { return vec![]; } @@ -984,6 +984,7 @@ impl Step for Rustc { true, // Only ship rustc_driver.so and .rmeta files, not all intermediate .rlib files. ); + let target_root_dir = stamp.parent().unwrap(); // When building `librustc_driver.so` (like `libLLVM.so`) on linux, it can contain // unexpected debuginfo from dependencies, for example from the C++ standard library used in // our LLVM wrapper. Unless we're explicitly requesting `librustc_driver` to be built with @@ -992,11 +993,16 @@ impl Step for Rustc { if builder.config.rust_debuginfo_level_rustc == DebuginfoLevel::None && builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None { - let target_root_dir = stamp.parent().unwrap(); let rustc_driver = target_root_dir.join("librustc_driver.so"); strip_debug(builder, target, &rustc_driver); } + if builder.config.rust_debuginfo_level_rustc == DebuginfoLevel::None { + // Due to LTO a lot of debug info from C++ dependencies such as jemalloc can make it into + // our final binaries + strip_debug(builder, target, &target_root_dir.join("rustc-main")); + } + builder.ensure(RustcLink::from_rustc( self, builder.compiler(compiler.stage, builder.config.build), diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 636c88b099b..6aa6e4e277d 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1133,69 +1133,21 @@ fn testdir(builder: &Builder<'_>, host: TargetSelection) -> PathBuf { builder.out.join(host).join("test") } -macro_rules! default_test { - ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr }) => { - test!($name { path: $path, mode: $mode, suite: $suite, default: true, host: false }); - }; -} - -macro_rules! default_test_with_compare_mode { - ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr, - compare_mode: $compare_mode:expr }) => { - test_with_compare_mode!($name { - path: $path, - mode: $mode, - suite: $suite, - default: true, - host: false, - compare_mode: $compare_mode - }); - }; -} - -macro_rules! host_test { - ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr }) => { - test!($name { path: $path, mode: $mode, suite: $suite, default: true, host: true }); - }; -} - +/// Declares a test step that invokes compiletest on a particular test suite. macro_rules! test { - ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr, default: $default:expr, - host: $host:expr }) => { - test_definitions!($name { - path: $path, - mode: $mode, - suite: $suite, - default: $default, - host: $host, - compare_mode: None - }); - }; -} - -macro_rules! test_with_compare_mode { - ($name:ident { path: $path:expr, mode: $mode:expr, suite: $suite:expr, default: $default:expr, - host: $host:expr, compare_mode: $compare_mode:expr }) => { - test_definitions!($name { - path: $path, - mode: $mode, - suite: $suite, - default: $default, - host: $host, - compare_mode: Some($compare_mode) - }); - }; -} - -macro_rules! test_definitions { - ($name:ident { - path: $path:expr, - mode: $mode:expr, - suite: $suite:expr, - default: $default:expr, - host: $host:expr, - compare_mode: $compare_mode:expr - }) => { + ( + $( #[$attr:meta] )* // allow docstrings and attributes + $name:ident { + path: $path:expr, + mode: $mode:expr, + suite: $suite:expr, + default: $default:expr + $( , only_hosts: $only_hosts:expr )? // default: false + $( , compare_mode: $compare_mode:expr )? // default: None + $( , )? // optional trailing comma + } + ) => { + $( #[$attr] )* #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct $name { pub compiler: Compiler, @@ -1205,7 +1157,12 @@ macro_rules! test_definitions { impl Step for $name { type Output = (); const DEFAULT: bool = $default; - const ONLY_HOSTS: bool = $host; + const ONLY_HOSTS: bool = (const { + #[allow(unused_assignments, unused_mut)] + let mut value = false; + $( value = $only_hosts; )? + value + }); fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { run.suite_path($path) @@ -1224,7 +1181,12 @@ macro_rules! test_definitions { mode: $mode, suite: $suite, path: $path, - compare_mode: $compare_mode, + compare_mode: (const { + #[allow(unused_assignments, unused_mut)] + let mut value = None; + $( value = $compare_mode; )? + value + }), }) } } @@ -1232,13 +1194,18 @@ macro_rules! test_definitions { } /// Declares an alias for running the [`Coverage`] tests in only one mode. -/// Adapted from [`test_definitions`]. +/// Adapted from [`test`]. macro_rules! coverage_test_alias { - ($name:ident { - alias_and_mode: $alias_and_mode:expr, // &'static str - default: $default:expr, // bool - only_hosts: $only_hosts:expr $(,)? // bool - }) => { + ( + $( #[$attr:meta] )* // allow docstrings and attributes + $name:ident { + alias_and_mode: $alias_and_mode:expr, // &'static str + default: $default:expr, // bool + only_hosts: $only_hosts:expr // bool + $( , )? // optional trailing comma + } + ) => { + $( #[$attr] )* #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct $name { pub compiler: Compiler, @@ -1410,37 +1377,74 @@ impl Step for CrateBuildHelper { } } -default_test!(Ui { path: "tests/ui", mode: "ui", suite: "ui" }); +test!(Ui { path: "tests/ui", mode: "ui", suite: "ui", default: true }); -default_test!(Crashes { path: "tests/crashes", mode: "crashes", suite: "crashes" }); +test!(Crashes { path: "tests/crashes", mode: "crashes", suite: "crashes", default: true }); -default_test!(Codegen { path: "tests/codegen", mode: "codegen", suite: "codegen" }); +test!(Codegen { path: "tests/codegen", mode: "codegen", suite: "codegen", default: true }); -default_test!(CodegenUnits { +test!(CodegenUnits { path: "tests/codegen-units", mode: "codegen-units", - suite: "codegen-units" + suite: "codegen-units", + default: true, }); -default_test!(Incremental { path: "tests/incremental", mode: "incremental", suite: "incremental" }); +test!(Incremental { + path: "tests/incremental", + mode: "incremental", + suite: "incremental", + default: true, +}); -default_test_with_compare_mode!(Debuginfo { +test!(Debuginfo { path: "tests/debuginfo", mode: "debuginfo", suite: "debuginfo", - compare_mode: "split-dwarf" + default: true, + compare_mode: Some("split-dwarf"), }); -host_test!(UiFullDeps { path: "tests/ui-fulldeps", mode: "ui", suite: "ui-fulldeps" }); +test!(UiFullDeps { + path: "tests/ui-fulldeps", + mode: "ui", + suite: "ui-fulldeps", + default: true, + only_hosts: true, +}); -host_test!(Rustdoc { path: "tests/rustdoc", mode: "rustdoc", suite: "rustdoc" }); -host_test!(RustdocUi { path: "tests/rustdoc-ui", mode: "ui", suite: "rustdoc-ui" }); +test!(Rustdoc { + path: "tests/rustdoc", + mode: "rustdoc", + suite: "rustdoc", + default: true, + only_hosts: true, +}); +test!(RustdocUi { + path: "tests/rustdoc-ui", + mode: "ui", + suite: "rustdoc-ui", + default: true, + only_hosts: true, +}); -host_test!(RustdocJson { path: "tests/rustdoc-json", mode: "rustdoc-json", suite: "rustdoc-json" }); +test!(RustdocJson { + path: "tests/rustdoc-json", + mode: "rustdoc-json", + suite: "rustdoc-json", + default: true, + only_hosts: true, +}); -host_test!(Pretty { path: "tests/pretty", mode: "pretty", suite: "pretty" }); +test!(Pretty { + path: "tests/pretty", + mode: "pretty", + suite: "pretty", + default: true, + only_hosts: true, +}); -/// Special-handling is needed for `run-make`, so don't use `default_test` for defining `RunMake` +/// Special-handling is needed for `run-make`, so don't use `test!` for defining `RunMake` /// tests. #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct RunMake { @@ -1475,7 +1479,7 @@ impl Step for RunMake { } } -default_test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly" }); +test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly", default: true }); /// Coverage tests are a bit more complicated than other test suites, because /// we want to run the same set of test files in multiple different modes, @@ -1552,27 +1556,33 @@ impl Step for Coverage { } } -// Runs `tests/coverage` in "coverage-map" mode only. -// Used by `x test` and `x test coverage-map`. -coverage_test_alias!(CoverageMap { - alias_and_mode: "coverage-map", - default: true, - only_hosts: false, -}); -// Runs `tests/coverage` in "coverage-run" mode only. -// Used by `x test` and `x test coverage-run`. -coverage_test_alias!(CoverageRun { - alias_and_mode: "coverage-run", - default: true, - // Compiletest knows how to automatically skip these tests when cross-compiling, - // but skipping the whole step here makes it clearer that they haven't run at all. - only_hosts: true, -}); +coverage_test_alias! { + /// Runs the `tests/coverage` test suite in "coverage-map" mode only. + /// Used by `x test` and `x test coverage-map`. + CoverageMap { + alias_and_mode: "coverage-map", + default: true, + only_hosts: false, + } +} +coverage_test_alias! { + /// Runs the `tests/coverage` test suite in "coverage-run" mode only. + /// Used by `x test` and `x test coverage-run`. + CoverageRun { + alias_and_mode: "coverage-run", + default: true, + // Compiletest knows how to automatically skip these tests when cross-compiling, + // but skipping the whole step here makes it clearer that they haven't run at all. + only_hosts: true, + } +} -host_test!(CoverageRunRustdoc { +test!(CoverageRunRustdoc { path: "tests/coverage-run-rustdoc", mode: "coverage-run", - suite: "coverage-run-rustdoc" + suite: "coverage-run-rustdoc", + default: true, + only_hosts: true, }); // For the mir-opt suite we do not use macros, as we need custom behavior when blessing. @@ -1829,6 +1839,10 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--force-rerun"); } + if builder.config.cmd.no_capture() { + cmd.arg("--no-capture"); + } + let compare_mode = builder.config.cmd.compare_mode().or_else(|| { if builder.config.test_compare_mode { self.compare_mode } else { None } @@ -2623,7 +2637,7 @@ fn prepare_cargo_test( ) -> BootstrapCommand { let mut cargo = cargo.into(); - // Propegate `--bless` if it has not already been set/unset + // Propagate `--bless` if it has not already been set/unset // Any tools that want to use this should bless if `RUSTC_BLESS` is set to // anything other than `0`. if builder.config.cmd.bless() && !cargo.get_envs().any(|v| v.0 == "RUSTC_BLESS") { @@ -3148,9 +3162,8 @@ impl Step for Bootstrap { let mut cmd = command(&builder.initial_cargo); cmd.arg("test") - .args(["--features", "bootstrap-self-test"]) .current_dir(builder.src.join("src/bootstrap")) - .env("RUSTFLAGS", "-Cdebuginfo=2") + .env("RUSTFLAGS", "--cfg test -Cdebuginfo=2") .env("CARGO_TARGET_DIR", builder.out.join("bootstrap")) .env("RUSTC_BOOTSTRAP", "1") .env("RUSTDOC", builder.rustdoc(compiler)) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 04f1e10f493..6b809a52bd2 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -5,7 +5,7 @@ use crate::core::build_steps::toolstate::ToolState; use crate::core::build_steps::{compile, llvm}; use crate::core::builder; use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step}; -use crate::core::config::TargetSelection; +use crate::core::config::{DebuginfoLevel, TargetSelection}; use crate::utils::channel::GitInfo; use crate::utils::exec::{BootstrapCommand, command}; use crate::utils::helpers::{add_dylib_path, exe, t}; @@ -671,6 +671,11 @@ impl Step for Rustdoc { // don't create a stage0-sysroot/bin directory. if target_compiler.stage > 0 { + if builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None { + // Due to LTO a lot of debug info from C++ dependencies such as jemalloc can make it into + // our final binaries + compile::strip_debug(builder, target, &tool_rustdoc); + } let bin_rustdoc = bin_rustdoc(); builder.copy_link(&tool_rustdoc, &bin_rustdoc); bin_rustdoc diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 98f765dbd0f..18beaf3676d 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -905,6 +905,7 @@ impl<'a> Builder<'a> { check::RustAnalyzer, check::TestFloatParse, check::Bootstrap, + check::Compiletest, ), Kind::Test => describe!( crate::core::build_steps::toolstate::ToolStateCheck, diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 819a552093b..a0acd839374 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -637,6 +637,7 @@ mod dist { run: None, only_modified: false, extra_checks: None, + no_capture: false, }; let build = Build::new(config); @@ -702,6 +703,7 @@ mod dist { run: None, only_modified: false, extra_checks: None, + no_capture: false, }; // Make sure rustfmt binary not being found isn't an error. config.channel = "beta".to_string(); diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 435216ef534..dd2f11ad469 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1154,7 +1154,6 @@ define_config! { debuginfo_level_tests: Option<DebuginfoLevel> = "debuginfo-level-tests", backtrace: Option<bool> = "backtrace", incremental: Option<bool> = "incremental", - parallel_compiler: Option<bool> = "parallel-compiler", default_linker: Option<String> = "default-linker", channel: Option<String> = "channel", description: Option<String> = "description", @@ -1325,23 +1324,14 @@ impl Config { .into_iter() .chain(flags.exclude) .map(|p| { - let p = if cfg!(windows) { + // Never return top-level path here as it would break `--skip` + // logic on rustc's internal test framework which is utilized + // by compiletest. + if cfg!(windows) { PathBuf::from(p.to_str().unwrap().replace('/', "\\")) } else { p - }; - - // Jump to top-level project path to support passing paths - // from sub directories. - let top_level_path = config.src.join(&p); - if !config.src.join(&top_level_path).exists() { - eprintln!("WARNING: '{}' does not exist.", top_level_path.display()); } - - // Never return top-level path here as it would break `--skip` - // logic on rustc's internal test framework which is utilized - // by compiletest. - p }) .collect(); @@ -1441,7 +1431,7 @@ impl Config { // Give a hard error if `--config` or `RUST_BOOTSTRAP_CONFIG` are set to a missing path, // but not if `config.toml` hasn't been created. let mut toml = if !using_default_path || toml_path.exists() { - config.config = Some(if cfg!(not(feature = "bootstrap-self-test")) { + config.config = Some(if cfg!(not(test)) { toml_path.canonicalize().unwrap() } else { toml_path.clone() @@ -1764,7 +1754,6 @@ impl Config { debuginfo_level_tests: debuginfo_level_tests_toml, backtrace, incremental, - parallel_compiler, randomize_layout, default_linker, channel: _, // already handled above @@ -1874,13 +1863,6 @@ impl Config { config.rust_randomize_layout = randomize_layout.unwrap_or_default(); config.llvm_tools_enabled = llvm_tools.unwrap_or(true); - // FIXME: Remove this option at the end of 2024. - if parallel_compiler.is_some() { - println!( - "WARNING: The `rust.parallel-compiler` option is deprecated and does nothing. The parallel compiler (with one thread) is now the default" - ); - } - config.llvm_enzyme = llvm_enzyme.unwrap_or(config.channel == "dev" || config.channel == "nightly"); config.rustc_default_linker = default_linker; @@ -2793,11 +2775,11 @@ impl Config { } } - #[cfg(feature = "bootstrap-self-test")] + #[cfg(test)] pub fn check_stage0_version(&self, _program_path: &Path, _component_name: &'static str) {} /// check rustc/cargo version is same or lower with 1 apart from the building one - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] pub fn check_stage0_version(&self, program_path: &Path, component_name: &'static str) { use build_helper::util::fail; @@ -2939,7 +2921,7 @@ impl Config { } // Fetching the LLVM submodule is unnecessary for self-tests. - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] self.update_submodule("src/llvm-project"); // Check for untracked changes in `src/llvm-project`. @@ -3014,7 +2996,7 @@ impl Config { /// Compares the current `Llvm` options against those in the CI LLVM builder and detects any incompatible options. /// It does this by destructuring the `Llvm` instance to make sure every `Llvm` field is covered and not missing. -#[cfg(not(feature = "bootstrap-self-test"))] +#[cfg(not(test))] pub(crate) fn check_incompatible_options_for_ci_llvm( current_config_toml: TomlConfig, ci_config_toml: TomlConfig, @@ -3222,7 +3204,6 @@ fn check_incompatible_options_for_ci_rustc( debuginfo_level_tools: _, debuginfo_level_tests: _, backtrace: _, - parallel_compiler: _, musl_root: _, verbose_tests: _, optimize_tests: _, diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs index 00bcbe9f86d..f17103f97dc 100644 --- a/src/bootstrap/src/core/config/flags.rs +++ b/src/bootstrap/src/core/config/flags.rs @@ -388,6 +388,9 @@ pub enum Subcommand { /// enable this to generate a Rustfix coverage file, which is saved in /// `/<build_base>/rustfix_missing_coverage.txt` rustfix_coverage: bool, + #[arg(long)] + /// don't capture stdout/stderr of tests + no_capture: bool, }, /// Build and run some test suites *in Miri* Miri { @@ -563,6 +566,13 @@ impl Subcommand { } } + pub fn no_capture(&self) -> bool { + match *self { + Subcommand::Test { no_capture, .. } => no_capture, + _ => false, + } + } + pub fn rustfix_coverage(&self) -> bool { match *self { Subcommand::Test { rustfix_coverage, .. } => rustfix_coverage, diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs index db35e6907e6..b5f7ed53131 100644 --- a/src/bootstrap/src/core/download.rs +++ b/src/bootstrap/src/core/download.rs @@ -197,8 +197,7 @@ impl Config { if !path_is_dylib(fname) { // Finally, set the correct .interp for binaries let dynamic_linker_path = nix_deps_dir.join("nix-support/dynamic-linker"); - // FIXME: can we support utf8 here? `args` doesn't accept Vec<u8>, only OsString ... - let dynamic_linker = t!(String::from_utf8(t!(fs::read(dynamic_linker_path)))); + let dynamic_linker = t!(fs::read_to_string(dynamic_linker_path)); patchelf.args(["--set-interpreter", dynamic_linker.trim_end()]); } @@ -444,14 +443,14 @@ impl Config { cargo_clippy } - #[cfg(feature = "bootstrap-self-test")] + #[cfg(test)] pub(crate) fn maybe_download_rustfmt(&self) -> Option<PathBuf> { None } /// NOTE: rustfmt is a completely different toolchain than the bootstrap compiler, so it can't /// reuse target directories or artifacts - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] pub(crate) fn maybe_download_rustfmt(&self) -> Option<PathBuf> { use build_helper::stage0_parser::VersionMetadata; @@ -534,10 +533,10 @@ impl Config { ); } - #[cfg(feature = "bootstrap-self-test")] + #[cfg(test)] pub(crate) fn download_beta_toolchain(&self) {} - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] pub(crate) fn download_beta_toolchain(&self) { self.verbose(|| println!("downloading stage0 beta artifacts")); @@ -714,10 +713,10 @@ download-rustc = false self.unpack(&tarball, &bin_root, prefix); } - #[cfg(feature = "bootstrap-self-test")] + #[cfg(test)] pub(crate) fn maybe_download_ci_llvm(&self) {} - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] pub(crate) fn maybe_download_ci_llvm(&self) { use build_helper::exit; @@ -789,7 +788,7 @@ download-rustc = false }; } - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] fn download_ci_llvm(&self, llvm_sha: &str) { let llvm_assertions = self.llvm_assertions; diff --git a/src/bootstrap/src/core/sanity.rs b/src/bootstrap/src/core/sanity.rs index dcf68cbeeda..ed0155622c2 100644 --- a/src/bootstrap/src/core/sanity.rs +++ b/src/bootstrap/src/core/sanity.rs @@ -14,10 +14,10 @@ use std::path::PathBuf; use std::{env, fs}; use crate::Build; -#[cfg(not(feature = "bootstrap-self-test"))] +#[cfg(not(test))] use crate::builder::Builder; use crate::builder::Kind; -#[cfg(not(feature = "bootstrap-self-test"))] +#[cfg(not(test))] use crate::core::build_steps::tool; use crate::core::config::Target; use crate::utils::exec::command; @@ -38,7 +38,7 @@ const STAGE0_MISSING_TARGETS: &[&str] = &[ /// Minimum version threshold for libstdc++ required when using prebuilt LLVM /// from CI (with`llvm.download-ci-llvm` option). -#[cfg(not(feature = "bootstrap-self-test"))] +#[cfg(not(test))] const LIBSTDCXX_MIN_VERSION_THRESHOLD: usize = 8; impl Finder { @@ -106,7 +106,7 @@ pub fn check(build: &mut Build) { } // Ensure that a compatible version of libstdc++ is available on the system when using `llvm.download-ci-llvm`. - #[cfg(not(feature = "bootstrap-self-test"))] + #[cfg(not(test))] if !build.config.dry_run() && !build.build.is_msvc() && build.config.llvm_from_ci { let builder = Builder::new(build); let libcxx_version = builder.ensure(tool::LibcxxVersionTool { target: build.build }); @@ -226,8 +226,7 @@ than building it. } // Ignore fake targets that are only used for unit tests in bootstrap. - if cfg!(not(feature = "bootstrap-self-test")) && !skip_target_sanity && !build.local_rebuild - { + if cfg!(not(test)) && !skip_target_sanity && !build.local_rebuild { let mut has_target = false; let target_str = target.to_string(); diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 0ecf61ffcd9..4cc812829f9 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -635,11 +635,12 @@ impl Build { if self.config.backtrace { features.insert("backtrace"); } + if self.config.profiler_enabled(target) { features.insert("profiler"); } - // Generate memcpy, etc. FIXME: Remove this once compiler-builtins - // automatically detects this target. + + // If zkvm target, generate memcpy, etc. if target.contains("zkvm") { features.insert("compiler-builtins-mem"); } @@ -1690,7 +1691,7 @@ Executed at: {executed_at}"#, } } if let Ok(()) = fs::hard_link(&src, dst) { - // Attempt to "easy copy" by creating a hard link (symlinks are priviledged on windows), + // Attempt to "easy copy" by creating a hard link (symlinks are privileged on windows), // but if that fails just fall back to a slow `copy` operation. } else { if let Err(e) = fs::copy(&src, dst) { diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index f4f189c718a..8fd6c8aa23a 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -315,4 +315,14 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "`build.vendor` is now enabled by default for dist/tarball sources when 'vendor' directory and '.cargo/config.toml' file are present.", }, + ChangeInfo { + change_id: 134809, + severity: ChangeSeverity::Warning, + summary: "compiletest now takes `--no-capture` instead of `--nocapture`; bootstrap now accepts `--no-capture` as an argument to test commands directly", + }, + ChangeInfo { + change_id: 134650, + severity: ChangeSeverity::Warning, + summary: "Removed `rust.parallel-compiler` as it was deprecated in #132282 long time ago.", + }, ]; diff --git a/src/bootstrap/src/utils/mod.rs b/src/bootstrap/src/utils/mod.rs index 53b41f15780..b5f5e2ba6dc 100644 --- a/src/bootstrap/src/utils/mod.rs +++ b/src/bootstrap/src/utils/mod.rs @@ -14,3 +14,5 @@ pub(crate) mod metrics; pub(crate) mod render_tests; pub(crate) mod shared_helpers; pub(crate) mod tarball; +#[cfg(test)] +mod tests; diff --git a/src/bootstrap/src/utils/proc_macro_deps.rs b/src/bootstrap/src/utils/proc_macro_deps.rs new file mode 100644 index 00000000000..dbfd6f47dc6 --- /dev/null +++ b/src/bootstrap/src/utils/proc_macro_deps.rs @@ -0,0 +1,71 @@ +/// Do not update manually - use `./x.py test tidy --bless` +/// Holds all direct and indirect dependencies of proc-macro crates in tree. +/// See <https://github.com/rust-lang/rust/issues/134863> +pub static CRATES: &[&str] = &[ + // tidy-alphabetical-start + "annotate-snippets", + "anstyle", + "basic-toml", + "block-buffer", + "bumpalo", + "cfg-if", + "cpufeatures", + "crypto-common", + "darling", + "darling_core", + "derive_builder_core", + "digest", + "fluent-bundle", + "fluent-langneg", + "fluent-syntax", + "fnv", + "generic-array", + "heck", + "ident_case", + "intl-memoizer", + "intl_pluralrules", + "libc", + "log", + "memchr", + "mime", + "mime_guess", + "minimal-lexical", + "nom", + "num-conv", + "once_cell", + "pest", + "pest_generator", + "pest_meta", + "proc-macro2", + "quote", + "rinja_parser", + "rustc-hash", + "self_cell", + "serde", + "sha2", + "smallvec", + "stable_deref_trait", + "strsim", + "syn", + "synstructure", + "thiserror", + "time-core", + "tinystr", + "type-map", + "typenum", + "ucd-trie", + "unic-langid", + "unic-langid-impl", + "unic-langid-macros", + "unicase", + "unicode-ident", + "unicode-width", + "version_check", + "wasm-bindgen-backend", + "wasm-bindgen-macro-support", + "wasm-bindgen-shared", + "yoke", + "zerofrom", + "zerovec", + // tidy-alphabetical-end +]; diff --git a/src/bootstrap/src/utils/shared_helpers.rs b/src/bootstrap/src/utils/shared_helpers.rs index 6d3c276cc05..7b206c3ffe8 100644 --- a/src/bootstrap/src/utils/shared_helpers.rs +++ b/src/bootstrap/src/utils/shared_helpers.rs @@ -13,8 +13,9 @@ use std::io::Write; use std::process::Command; use std::str::FromStr; -#[cfg(test)] -mod tests; +// If we were to declare a tests submodule here, the shim binaries that include this +// module via `#[path]` would fail to find it, which breaks `./x check bootstrap`. +// So instead the unit tests for this module are in `super::tests::shared_helpers_tests`. /// Returns the environment variable which the dynamic library lookup path /// resides in for this platform. diff --git a/src/bootstrap/src/utils/tarball.rs b/src/bootstrap/src/utils/tarball.rs index 3c6c7a7fa18..843ea65e838 100644 --- a/src/bootstrap/src/utils/tarball.rs +++ b/src/bootstrap/src/utils/tarball.rs @@ -1,7 +1,7 @@ //! Facilitates the management and generation of tarballs. //! //! Tarballs efficiently hold Rust compiler build artifacts and -//! capture a snapshot of each boostrap stage. +//! capture a snapshot of each bootstrap stage. //! In uplifting, a tarball from Stage N captures essential components //! to assemble Stage N + 1 compiler. diff --git a/src/bootstrap/src/utils/tests/mod.rs b/src/bootstrap/src/utils/tests/mod.rs new file mode 100644 index 00000000000..0791f7a6e20 --- /dev/null +++ b/src/bootstrap/src/utils/tests/mod.rs @@ -0,0 +1 @@ +mod shared_helpers_tests; diff --git a/src/bootstrap/src/utils/shared_helpers/tests.rs b/src/bootstrap/src/utils/tests/shared_helpers_tests.rs index da7924276f7..6c47e7f2438 100644 --- a/src/bootstrap/src/utils/shared_helpers/tests.rs +++ b/src/bootstrap/src/utils/tests/shared_helpers_tests.rs @@ -1,4 +1,11 @@ -use super::parse_value_from_args; +//! The `shared_helpers` module can't have its own tests submodule, because +//! that would cause problems for the shim binaries that include it via +//! `#[path]`, so instead those unit tests live here. +//! +//! To prevent tidy from complaining about this file not being named `tests.rs`, +//! it lives inside a submodule directory named `tests`. + +use crate::utils::shared_helpers::parse_value_from_args; #[test] fn test_parse_value_from_args() { diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md index 2f35e605026..508b7b40c01 100644 --- a/src/ci/docker/README.md +++ b/src/ci/docker/README.md @@ -26,6 +26,12 @@ DEPLOY=1 ./src/ci/docker/run.sh x86_64-gnu while locally, to the `obj/$image_name` directory. This is primarily to prevent strange linker errors when using multiple Docker images. +For some Linux workflows (for example `x86_64-gnu-llvm-18-N`), the process is more involved. You will need to see which script is executed for the given workflow inside the [`jobs.yml`](../github-actions/jobs.yml) file and pass it through the `DOCKER_SCRIPT` environment variable. For example, to reproduce the `x86_64-gnu-llvm-18-3` workflow, you can run the following script: + +``` +DOCKER_SCRIPT=x86_64-gnu-llvm3.sh ./src/ci/docker/run.sh x86_64-gnu-llvm-18 +``` + ## Local Development Refer to the [dev guide](https://rustc-dev-guide.rust-lang.org/tests/docker.html) for more information on testing locally. diff --git a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile index 414bcc52484..7e946df6163 100644 --- a/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-i686-linux/Dockerfile @@ -50,6 +50,7 @@ COPY host-x86_64/dist-x86_64-linux/shared.sh /tmp/ # Need at least GCC 5.1 to compile LLVM nowadays COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/ +ENV GCC_VERSION=9.5.0 RUN ./build-gcc.sh && yum remove -y gcc gcc-c++ COPY scripts/cmake.sh /tmp/ diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile index e857f38e68a..bbb4fe216a5 100644 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile @@ -44,12 +44,14 @@ RUN mkdir -p /rustroot/bin ENV PATH=/rustroot/bin:$PATH ENV LD_LIBRARY_PATH=/rustroot/lib64:/rustroot/lib32:/rustroot/lib ENV PKG_CONFIG_PATH=/rustroot/lib/pkgconfig +# Clang needs to access GCC headers to enable linker plugin LTO WORKDIR /tmp RUN mkdir /home/user COPY host-x86_64/dist-x86_64-linux/shared.sh /tmp/ # Need at least GCC 5.1 to compile LLVM nowadays COPY host-x86_64/dist-x86_64-linux/build-gcc.sh /tmp/ +ENV GCC_VERSION=9.5.0 RUN ./build-gcc.sh && yum remove -y gcc gcc-c++ # LLVM 17 needs cmake 3.20 or higher. @@ -89,6 +91,7 @@ ENV RUST_CONFIGURE_ARGS \ --set rust.lto=thin \ --set rust.codegen-units=1 +# Note that `rust.debug` is set to true *only* for `opt-dist` ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \ ./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \ --host $HOSTS --target $HOSTS \ @@ -104,3 +107,7 @@ ENV DIST_SRC 1 ENV LIBCURL_NO_PKG_CONFIG 1 ENV DIST_REQUIRE_ALL_TOOLS 1 + +# FIXME: Without this, LLVMgold.so incorrectly resolves to the system +# libstdc++, instead of the one we build. +ENV LD_PRELOAD=/rustroot/lib64/libstdc++.so.6 diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh index 2e08c87f278..3c8123d90de 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh @@ -39,6 +39,7 @@ hide_output \ -DLLVM_INCLUDE_TESTS=OFF \ -DLLVM_INCLUDE_EXAMPLES=OFF \ -DLLVM_ENABLE_PROJECTS="clang;lld;compiler-rt;bolt" \ + -DLLVM_BINUTILS_INCDIR="/rustroot/lib/gcc/x86_64-pc-linux-gnu/$GCC_VERSION/plugin/include/" \ -DC_INCLUDE_DIRS="$INC" hide_output make -j$(nproc) diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh index e939a5d7eac..57d4d338a50 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh @@ -1,10 +1,11 @@ #!/usr/bin/env bash -set -ex +set -eux source shared.sh # Note: in the future when bumping to version 10.1.0, also take care of the sed block below. -GCC=9.5.0 +# This version is specified in the Dockerfile +GCC=$GCC_VERSION curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.xz | xzcat | tar xf - cd gcc-$GCC diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index a0adf60b6b2..d1bc0519bc1 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -76,8 +76,9 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then # Include cache version. Can be used to manually bust the Docker cache. echo "2" >> $hash_key - echo "Image input" + echo "::group::Image checksum input" cat $hash_key + echo "::endgroup::" cksum=$(sha512sum $hash_key | \ awk '{print $1}') diff --git a/src/ci/scripts/install-clang.sh b/src/ci/scripts/install-clang.sh index 6103aa61248..5522095e304 100755 --- a/src/ci/scripts/install-clang.sh +++ b/src/ci/scripts/install-clang.sh @@ -15,7 +15,7 @@ LLVM_VERSION="18.1.4" if isMacOS; then # FIXME: This is the latest pre-built version of LLVM that's available for - # x86_64 MacOS. We may want to consider bulding our own LLVM binaries + # x86_64 MacOS. We may want to consider building our own LLVM binaries # instead, or set `USE_XCODE_CLANG` like AArch64 does. LLVM_VERSION="15.0.7" diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index 9743b3ba442..f0c3720eae1 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -56,6 +56,7 @@ - [csky-unknown-linux-gnuabiv2\*](platform-support/csky-unknown-linux-gnuabiv2.md) - [hexagon-unknown-linux-musl](platform-support/hexagon-unknown-linux-musl.md) - [hexagon-unknown-none-elf](platform-support/hexagon-unknown-none-elf.md) + - [illumos](platform-support/illumos.md) - [loongarch\*-unknown-linux-\*](platform-support/loongarch-linux.md) - [loongarch\*-unknown-none\*](platform-support/loongarch-none.md) - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 00ab61051c3..24e9a3c8121 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -32,8 +32,8 @@ All tier 1 targets with host tools support the full standard library. target | notes -------|------- -`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+) [`aarch64-apple-darwin`](platform-support/apple-darwin.md) | ARM64 macOS (11.0+, Big Sur+) +`aarch64-unknown-linux-gnu` | ARM64 Linux (kernel 4.1, glibc 2.17+) `i686-pc-windows-gnu` | 32-bit MinGW (Windows 10+, Windows Server 2016+) [^x86_32-floats-return-ABI] `i686-pc-windows-msvc` | 32-bit MSVC (Windows 10+, Windows Server 2016+) [^x86_32-floats-return-ABI] `i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+) [^x86_32-floats-return-ABI] @@ -102,7 +102,7 @@ target | notes [`riscv64gc-unknown-linux-musl`](platform-support/riscv64gc-unknown-linux-musl.md) | RISC-V Linux (kernel 4.20, musl 1.2.3) [`s390x-unknown-linux-gnu`](platform-support/s390x-unknown-linux-gnu.md) | S390x Linux (kernel 3.2, glibc 2.17) [`x86_64-unknown-freebsd`](platform-support/freebsd.md) | 64-bit amd64 FreeBSD -`x86_64-unknown-illumos` | illumos +[`x86_64-unknown-illumos`](platform-support/illumos.md) | illumos `x86_64-unknown-linux-musl` | 64-bit Linux with musl 1.2.3 [`x86_64-unknown-netbsd`](platform-support/netbsd.md) | NetBSD/amd64 @@ -139,12 +139,12 @@ target | std | notes [`aarch64-apple-ios`](platform-support/apple-ios.md) | ✓ | ARM64 iOS [`aarch64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | Mac Catalyst on ARM64 [`aarch64-apple-ios-sim`](platform-support/apple-ios.md) | ✓ | Apple iOS Simulator on ARM64 -[`aarch64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | ARM64 Fuchsia [`aarch64-linux-android`](platform-support/android.md) | ✓ | ARM64 Android [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ARM64 MinGW (Windows 10+), LLVM ABI +[`aarch64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | ARM64 Fuchsia [`aarch64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | ARM64 OpenHarmony -`aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat `aarch64-unknown-none` | * | Bare ARM64, hardfloat +`aarch64-unknown-none-softfloat` | * | Bare ARM64, softfloat [`aarch64-unknown-uefi`](platform-support/unknown-uefi.md) | ? | ARM64 UEFI [`arm-linux-androideabi`](platform-support/android.md) | ✓ | Armv6 Android `arm-unknown-linux-musleabi` | ✓ | Armv6 Linux with musl 1.2.3 @@ -173,11 +173,11 @@ target | std | notes [`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64D ABI) [`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * | LoongArch64 Bare-metal (LP64S ABI) [`nvptx64-nvidia-cuda`](platform-support/nvptx64-nvidia-cuda.md) | * | --emit=asm generates PTX code that [runs on NVIDIA GPUs] -[`riscv32imac-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAC ISA) [`riscv32i-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32I ISA) [`riscv32im-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IM ISA) -[`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) +[`riscv32imac-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAC ISA) [`riscv32imafc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMAFC ISA) +[`riscv32imc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | Bare RISC-V (RV32IMC ISA) `riscv64gc-unknown-none-elf` | * | Bare RISC-V (RV64IMAFDC ISA) `riscv64imac-unknown-none-elf` | * | Bare RISC-V (RV64IMAC ISA) `sparc64-unknown-linux-gnu` | ✓ | SPARC Linux (kernel 4.4, glibc 2.23) @@ -194,16 +194,16 @@ target | std | notes [`wasm32-unknown-emscripten`](platform-support/wasm32-unknown-emscripten.md) | ✓ | WebAssembly via Emscripten [`wasm32-unknown-unknown`](platform-support/wasm32-unknown-unknown.md) | ✓ | WebAssembly [`wasm32-wasip1`](platform-support/wasm32-wasip1.md) | ✓ | WebAssembly with WASIp1 -[`wasm32-wasip2`](platform-support/wasm32-wasip2.md) | ✓ | WebAssembly with WASIp2 [`wasm32-wasip1-threads`](platform-support/wasm32-wasip1-threads.md) | ✓ | WebAssembly with WASI Preview 1 and threads +[`wasm32-wasip2`](platform-support/wasm32-wasip2.md) | ✓ | WebAssembly with WASIp2 [`wasm32v1-none`](platform-support/wasm32v1-none.md) | * | WebAssembly limited to 1.0 features and no imports [`x86_64-apple-ios`](platform-support/apple-ios.md) | ✓ | 64-bit x86 iOS [`x86_64-apple-ios-macabi`](platform-support/apple-ios-macabi.md) | ✓ | Mac Catalyst on x86_64 [`x86_64-fortanix-unknown-sgx`](platform-support/x86_64-fortanix-unknown-sgx.md) | ✓ | [Fortanix ABI] for 64-bit Intel SGX -[`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia [`x86_64-linux-android`](platform-support/android.md) | ✓ | 64-bit x86 Android [`x86_64-pc-solaris`](platform-support/solaris.md) | ✓ | 64-bit x86 Solaris 11.4 [`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | 64-bit x86 MinGW (Windows 10+), LLVM ABI +[`x86_64-unknown-fuchsia`](platform-support/fuchsia.md) | ✓ | 64-bit x86 Fuchsia `x86_64-unknown-linux-gnux32` | ✓ | 64-bit Linux (x32 ABI) (kernel 4.15, glibc 2.27) [`x86_64-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ | x86_64 OpenHarmony [`x86_64-unknown-none`](platform-support/x86_64-unknown-none.md) | * | Freestanding/bare-metal x86_64, softfloat @@ -245,34 +245,34 @@ host tools. target | std | host | notes -------|:---:|:----:|------- -[`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md) | ✓ | ✓ | ARM64e Apple Darwin -[`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS -[`arm64e-apple-tvos`](platform-support/arm64e-apple-tvos.md) | ✓ | | ARM64e Apple tvOS [`aarch64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | ARM64 tvOS [`aarch64-apple-tvos-sim`](platform-support/apple-tvos.md) | ✓ | | ARM64 tvOS Simulator -[`aarch64-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS -[`aarch64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS Simulator [`aarch64-apple-visionos`](platform-support/apple-visionos.md) | ✓ | | ARM64 Apple visionOS [`aarch64-apple-visionos-sim`](platform-support/apple-visionos.md) | ✓ | | ARM64 Apple visionOS Simulator +[`aarch64-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS +[`aarch64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | ARM64 Apple WatchOS Simulator [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon -[`aarch64-unknown-teeos`](platform-support/aarch64-unknown-teeos.md) | ? | | ARM64 TEEOS | -[`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.0 RTOS | -[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS | [`aarch64-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | ARM64 FreeBSD [`aarch64-unknown-hermit`](platform-support/hermit.md) | ✓ | | ARM64 Hermit -`aarch64-unknown-illumos` | ✓ | ✓ | ARM64 illumos +[`aarch64-unknown-illumos`](platform-support/illumos.md) | ✓ | ✓ | ARM64 illumos `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) [`aarch64-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD +[`aarch64-unknown-nto-qnx700`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.0 RTOS | +[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ✓ | | ARM64 QNX Neutrino 7.1 RTOS | [`aarch64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | ARM64 OpenBSD [`aarch64-unknown-redox`](platform-support/redox.md) | ✓ | | ARM64 Redox OS +[`aarch64-unknown-teeos`](platform-support/aarch64-unknown-teeos.md) | ? | | ARM64 TEEOS | [`aarch64-unknown-trusty`](platform-support/trusty.md) | ? | | `aarch64-uwp-windows-msvc` | ✓ | | [`aarch64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | ARM64 VxWorks OS -`aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) `aarch64_be-unknown-linux-gnu` | ✓ | ✓ | ARM64 Linux (big-endian) +`aarch64_be-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (big-endian, ILP32 ABI) [`aarch64_be-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | ARM64 NetBSD (big-endian) [`arm64_32-apple-watchos`](platform-support/apple-watchos.md) | ✓ | | Arm Apple WatchOS 64-bit with 32-bit pointers +[`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md) | ✓ | ✓ | ARM64e Apple Darwin +[`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS +[`arm64e-apple-tvos`](platform-support/arm64e-apple-tvos.md) | ✓ | | ARM64e Apple tvOS [`armeb-unknown-linux-gnueabi`](platform-support/armeb-unknown-linux-gnueabi.md) | ✓ | ? | Arm BE8 the default Arm big-endian architecture since [Armv6](https://developer.arm.com/documentation/101754/0616/armlink-Reference/armlink-Command-line-Options/--be8?lang=en). [`armv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Bare Armv4T `armv4t-unknown-linux-gnueabi` | ? | | Armv4T Linux @@ -283,9 +283,9 @@ target | std | host | notes [`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? | | Armv6k Nintendo 3DS, Horizon (Requires devkitARM toolchain) [`armv7-rtems-eabihf`](platform-support/armv7-rtems-eabihf.md) | ? | | RTEMS OS for ARM BSPs [`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ✓ | | Armv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain) +[`armv7-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | Armv7-A FreeBSD [`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | Armv7-A Linux with uClibc, softfloat [`armv7-unknown-linux-uclibceabihf`](platform-support/armv7-unknown-linux-uclibceabihf.md) | ✓ | ? | Armv7-A Linux with uClibc, hardfloat -[`armv7-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | Armv7-A FreeBSD [`armv7-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | Armv7-A NetBSD w/hard-float [`armv7-unknown-trusty`](platform-support/trusty.md) | ? | | [`armv7-wrs-vxworks-eabihf`](platform-support/vxworks.md) | ✓ | | Armv7-A for VxWorks @@ -300,8 +300,8 @@ target | std | host | notes `bpfel-unknown-none` | * | | BPF (little endian) `csky-unknown-linux-gnuabiv2` | ✓ | | C-SKY abiv2 Linux (little endian) `csky-unknown-linux-gnuabiv2hf` | ✓ | | C-SKY abiv2 Linux, hardfloat (little endian) -[`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | | Bare Hexagon (v60+, HVX) [`hexagon-unknown-linux-musl`](platform-support/hexagon-unknown-linux-musl.md) | ✓ | | Hexagon Linux with musl 1.2.3 +[`hexagon-unknown-none-elf`](platform-support/hexagon-unknown-none-elf.md)| * | | Bare Hexagon (v60+, HVX) [`i386-apple-ios`](platform-support/apple-ios.md) | ✓ | | 32-bit x86 iOS [^x86_32-floats-return-ABI] [`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS [^x86_32-floats-return-ABI] [`i586-unknown-netbsd`](platform-support/netbsd.md) | ✓ | | 32-bit x86, restricted to Pentium @@ -325,48 +325,56 @@ target | std | host | notes `mips64-unknown-linux-muslabi64` | ✓ | | MIPS64 Linux, N64 ABI, musl 1.2.3 `mips64el-unknown-linux-gnuabi64` | ✓ | ✓ | MIPS64 (little endian) Linux, N64 ABI (kernel 4.4, glibc 2.23) `mips64el-unknown-linux-muslabi64` | ✓ | | MIPS64 (little endian) Linux, N64 ABI, musl 1.2.3 -`mipsel-unknown-linux-gnu` | ✓ | ✓ | MIPS (little endian) Linux (kernel 4.4, glibc 2.23) -`mipsel-unknown-linux-musl` | ✓ | | MIPS (little endian) Linux with musl 1.2.3 -[`mipsel-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | 32-bit MIPS (LE), requires mips32 cpu support `mipsel-sony-psp` | * | | MIPS (LE) Sony PlayStation Portable (PSP) [`mipsel-sony-psx`](platform-support/mipsel-sony-psx.md) | * | | MIPS (LE) Sony PlayStation 1 (PSX) +`mipsel-unknown-linux-gnu` | ✓ | ✓ | MIPS (little endian) Linux (kernel 4.4, glibc 2.23) +`mipsel-unknown-linux-musl` | ✓ | | MIPS (little endian) Linux with musl 1.2.3 `mipsel-unknown-linux-uclibc` | ✓ | | MIPS (LE) Linux with uClibc +[`mipsel-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | 32-bit MIPS (LE), requires mips32 cpu support `mipsel-unknown-none` | * | | Bare MIPS (LE) softfloat [`mipsisa32r6-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Big Endian [`mipsisa32r6el-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Little Endian [`mipsisa64r6-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ? | | 64-bit MIPS Release 6 Big Endian [`mipsisa64r6el-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ✓ | ✓ | 64-bit MIPS Release 6 Little Endian `msp430-none-elf` | * | | 16-bit MSP430 microcontrollers +[`powerpc-unknown-freebsd`](platform-support/freebsd.md) | ? | | PowerPC FreeBSD `powerpc-unknown-linux-gnuspe` | ✓ | | PowerPC SPE Linux `powerpc-unknown-linux-musl` | ? | | PowerPC Linux with musl 1.2.3 [`powerpc-unknown-linux-muslspe`](platform-support/powerpc-unknown-linux-muslspe.md) | ? | | PowerPC SPE Linux [`powerpc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD 32-bit powerpc systems [`powerpc-unknown-openbsd`](platform-support/powerpc-unknown-openbsd.md) | * | | -[`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ✓ | | [`powerpc-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | +[`powerpc-wrs-vxworks-spe`](platform-support/vxworks.md) | ✓ | | +[`powerpc64-ibm-aix`](platform-support/aix.md) | ? | | 64-bit AIX (7.2 and newer) [`powerpc64-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64 FreeBSD (ELFv2) -[`powerpc64le-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64LE FreeBSD -[`powerpc-unknown-freebsd`](platform-support/freebsd.md) | ? | | PowerPC FreeBSD `powerpc64-unknown-linux-musl` | ? | | 64-bit PowerPC Linux with musl 1.2.3 -[`powerpc64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [`powerpc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/powerpc64 -[`powerpc64-ibm-aix`](platform-support/aix.md) | ? | | 64-bit AIX (7.2 and newer) +[`powerpc64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | +[`powerpc64le-unknown-freebsd`](platform-support/freebsd.md) | ✓ | ✓ | PPC64LE FreeBSD +[`riscv32-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | +[`riscv32e-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32E ISA) +[`riscv32em-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EM ISA) +[`riscv32emc-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EMC ISA) `riscv32gc-unknown-linux-gnu` | ✓ | | RISC-V Linux (kernel 5.4, glibc 2.33) `riscv32gc-unknown-linux-musl` | ? | | RISC-V Linux (kernel 5.4, musl 1.2.3 + RISCV32 support patches) [`riscv32im-risc0-zkvm-elf`](platform-support/riscv32im-risc0-zkvm-elf.md) | ? | | RISC Zero's zero-knowledge Virtual Machine (RV32IM ISA) [`riscv32ima-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32IMA ISA) -[`riscv32imac-unknown-xous-elf`](platform-support/riscv32imac-unknown-xous-elf.md) | ? | | RISC-V Xous (RV32IMAC ISA) -[`riscv32imc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF [`riscv32imac-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF +[`riscv32imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX +[`riscv32imac-unknown-xous-elf`](platform-support/riscv32imac-unknown-xous-elf.md) | ? | | RISC-V Xous (RV32IMAC ISA) [`riscv32imafc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF -[`riscv32-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | -[`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit +[`riscv32imafc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX +[`riscv32imc-esp-espidf`](platform-support/esp-idf.md) | ✓ | | RISC-V ESP-IDF +[`riscv32imc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX +[`riscv64-linux-android`](platform-support/android.md) | ? | | RISC-V 64-bit Android +[`riscv64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | `riscv64gc-unknown-freebsd` | ? | | RISC-V FreeBSD `riscv64gc-unknown-fuchsia` | ? | | RISC-V Fuchsia +[`riscv64gc-unknown-hermit`](platform-support/hermit.md) | ✓ | | RISC-V Hermit [`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD +[`riscv64gc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64 -[`riscv64-linux-android`](platform-support/android.md) | ? | | RISC-V 64-bit Android -[`riscv64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | +[`riscv64imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX [`s390x-unknown-linux-musl`](platform-support/s390x-unknown-linux-musl.md) | ✓ | | S390x Linux (kernel 3.2, musl 1.2.3) `sparc-unknown-linux-gnu` | ✓ | | 32-bit SPARC Linux [`sparc-unknown-none-elf`](./platform-support/sparc-unknown-none-elf.md) | * | | Bare 32-bit SPARC V7+ @@ -374,9 +382,16 @@ target | std | host | notes [`sparc64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/sparc64 [`thumbv4t-none-eabi`](platform-support/armv4t-none-eabi.md) | * | | Thumb-mode Bare Armv4T [`thumbv5te-none-eabi`](platform-support/armv5te-none-eabi.md) | * | | Thumb-mode Bare Armv5TE +[`thumbv6m-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv6M with NuttX `thumbv7a-pc-windows-msvc` | ✓ | | `thumbv7a-uwp-windows-msvc` | ✓ | | +[`thumbv7em-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7EM with NuttX +[`thumbv7em-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv7EM with NuttX, hardfloat +[`thumbv7m-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7M with NuttX `thumbv7neon-unknown-linux-musleabihf` | ? | | Thumb2-mode Armv7-A Linux with NEON, musl 1.2.3 +[`thumbv8m.base-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv8M Baseline with NuttX +[`thumbv8m.main-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv8M Mainline with NuttX +[`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv8M Mainline with NuttX, hardfloat [`wasm64-unknown-unknown`](platform-support/wasm64-unknown-unknown.md) | ? | | WebAssembly [`x86_64-apple-tvos`](platform-support/apple-tvos.md) | ✓ | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator @@ -384,9 +399,10 @@ target | std | host | notes [`x86_64-unikraft-linux-musl`](platform-support/unikraft-linux-musl.md) | ✓ | | 64-bit Unikraft with musl 1.2.3 `x86_64-unknown-dragonfly` | ✓ | ✓ | 64-bit DragonFlyBSD `x86_64-unknown-haiku` | ✓ | ✓ | 64-bit Haiku -[`x86_64-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 64-bit GNU/Hurd [`x86_64-unknown-hermit`](platform-support/hermit.md) | ✓ | | x86_64 Hermit +[`x86_64-unknown-hurd-gnu`](platform-support/hurd.md) | ✓ | ✓ | 64-bit GNU/Hurd `x86_64-unknown-l4re-uclibc` | ? | | +[`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * | | 64-bit Linux with no libc [`x86_64-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | 64-bit OpenBSD [`x86_64-unknown-trusty`](platform-support/trusty.md) | ? | | `x86_64-uwp-windows-gnu` | ✓ | | @@ -394,27 +410,11 @@ target | std | host | notes [`x86_64-win7-windows-msvc`](platform-support/win7-windows-msvc.md) | ✓ | | 64-bit Windows 7 support [`x86_64-wrs-vxworks`](platform-support/vxworks.md) | ✓ | | [`x86_64h-apple-darwin`](platform-support/x86_64h-apple-darwin.md) | ✓ | ✓ | macOS with late-gen Intel (at least Haswell) -[`x86_64-unknown-linux-none`](platform-support/x86_64-unknown-linux-none.md) | * | | 64-bit Linux with no libc -[`xtensa-esp32-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32 [`xtensa-esp32-espidf`](platform-support/esp-idf.md) | ✓ | | Xtensa ESP32 -[`xtensa-esp32s2-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32-S2 +[`xtensa-esp32-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32 [`xtensa-esp32s2-espidf`](platform-support/esp-idf.md) | ✓ | | Xtensa ESP32-S2 -[`xtensa-esp32s3-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32-S3 +[`xtensa-esp32s2-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32-S2 [`xtensa-esp32s3-espidf`](platform-support/esp-idf.md) | ✓ | | Xtensa ESP32-S3 -[`thumbv6m-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv6M with NuttX -[`thumbv7m-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7M with NuttX -[`thumbv7em-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv7EM with NuttX -[`thumbv7em-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv7EM with NuttX, hardfloat -[`thumbv8m.base-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv8M Baseline with NuttX -[`thumbv8m.main-nuttx-eabi`](platform-support/nuttx.md) | * | | ARMv8M Mainline with NuttX -[`thumbv8m.main-nuttx-eabihf`](platform-support/nuttx.md) | * | | ARMv8M Mainline with NuttX, hardfloat -[`riscv32imc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX -[`riscv32imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX -[`riscv32imafc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX -[`riscv64imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX -[`riscv64gc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX -[`riscv32e-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32E ISA) -[`riscv32em-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EM ISA) -[`riscv32emc-unknown-none-elf`](platform-support/riscv32e-unknown-none-elf.md) | * | | Bare RISC-V (RV32EMC ISA) +[`xtensa-esp32s3-none-elf`](platform-support/xtensa.md) | * | | Xtensa ESP32-S3 [runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets diff --git a/src/doc/rustc/src/platform-support/android.md b/src/doc/rustc/src/platform-support/android.md index 96499b0d801..54e7ddca32a 100644 --- a/src/doc/rustc/src/platform-support/android.md +++ b/src/doc/rustc/src/platform-support/android.md @@ -65,4 +65,4 @@ Currently the `riscv64-linux-android` target requires the following architecture ### aarch64-linux-android on Nightly compilers As soon as `-Zfixed-x18` compiler flag is supplied, the [`ShadowCallStack` sanitizer](https://releases.llvm.org/7.0.1/tools/clang/docs/ShadowCallStack.html) -instrumentation is also made avaiable by supplying the second compiler flag `-Zsanitizer=shadow-call-stack`. +instrumentation is also made available by supplying the second compiler flag `-Zsanitizer=shadow-call-stack`. diff --git a/src/doc/rustc/src/platform-support/illumos.md b/src/doc/rustc/src/platform-support/illumos.md new file mode 100644 index 00000000000..dd2ae90f674 --- /dev/null +++ b/src/doc/rustc/src/platform-support/illumos.md @@ -0,0 +1,42 @@ +# `aarch64-unknown-illumos` and `x86_64-unknown-illumos` + +**Tier: 2/3** + +[illumos](https://www.illumos.org/), is a Unix operating system which provides next-generation features for downstream distributions, +including advanced system debugging, next generation filesystem, networking, and virtualization options. + +## Target maintainers + +- Joshua M. Clulow ([@jclulow](https://github.com/jclulow)) +- Patrick Mooney ([@pfmooney](https://github.com/pfmooney)) + +## Requirements + +The target supports host tools. + +The illumos target supports `std` and uses the standard ELF file format. + +`x86_64-unknown-illumos` is a tier 2 target with host tools. +`aarch64-unknown-illumos` is a tier 3 target. + +## Building the target + +These targets can be built by adding `aarch64-unknown-illumos` and +`x86_64-unknown-illumos` as targets in the rustc list. + +## Building Rust programs + +Rust ships pre-compiled artifacts for the `x86_64-unknown-illumos` target. +Rust does not ship pre-compiled artifacts for `aarch64-unknown-illumos`, +it requires building the target either as shown above or using `-Zbuild-std`. + +## Testing + +Tests can be run in the same way as a regular binary. + +## Cross-compilation toolchains and C code + +The target supports C code. + +The illumos project makes available [prebuilt sysroot artefacts](https://github.com/illumos/sysroot) which can be used for cross compilation. +The official Rust binaries are cross-compiled using these artefacts. diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md index 1acc0584be9..b57083980d2 100644 --- a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md +++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md @@ -122,7 +122,7 @@ limactl shell riscv Using [Docker (with BuildKit)](https://docs.docker.com/build/buildkit/) the [`riscv64/ubuntu`](https://hub.docker.com/r/riscv64/ubuntu) image can be used -to buiild or run `riscv64gc-unknown-linux-gnu` binaries. +to build or run `riscv64gc-unknown-linux-gnu` binaries. ```bash docker run --platform linux/riscv64 -ti --rm --mount "type=bind,src=$(pwd),dst=/checkout" riscv64/ubuntu bash diff --git a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md index 5608b5cb778..965d6aea931 100644 --- a/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md +++ b/src/doc/rustc/src/platform-support/x86_64-unknown-linux-none.md @@ -14,6 +14,11 @@ This target is cross compiled and can be built from any host. This target has no support for host tools, std, or alloc. +One of the primary motivations of the target is to write a dynamic linker and libc in Rust. +For that, the target defaults to position-independent code and position-independent executables (PIE) by default. +PIE binaries need relocation at runtime. This is usually done by the dynamic linker or libc. +You can use `-Crelocation-model=static` to create a position-dependent binary that does not need relocation at runtime. + ## Building the target The target can be built by enabling it for a `rustc` build: diff --git a/src/doc/rustc/src/targets/custom.md b/src/doc/rustc/src/targets/custom.md index a332d24c9f1..6c1494186a4 100644 --- a/src/doc/rustc/src/targets/custom.md +++ b/src/doc/rustc/src/targets/custom.md @@ -21,10 +21,10 @@ To use a custom target, see the (unstable) [`build-std` feature](../../cargo/ref When `rustc` is given an option `--target=TARGET` (where `TARGET` is any string), it uses the following logic: 1. if `TARGET` is the name of a built-in target, use that 2. if `TARGET` is a path to a file, read that file as a json target -3. otherwise, search the colon-seperated list of directories found +3. otherwise, search the colon-separated list of directories found in the `RUST_TARGET_PATH` environment variable from left to right for a file named `TARGET.json`. -These steps are tried in order, so if there are multple potentially valid +These steps are tried in order, so if there are multiple potentially valid interpretations for a target, whichever is found first will take priority. If none of these methods find a target, an error is thrown. diff --git a/src/doc/rustdoc/src/write-documentation/documentation-tests.md b/src/doc/rustdoc/src/write-documentation/documentation-tests.md index e02c26bd42b..b921f677857 100644 --- a/src/doc/rustdoc/src/write-documentation/documentation-tests.md +++ b/src/doc/rustdoc/src/write-documentation/documentation-tests.md @@ -412,7 +412,7 @@ In some cases, doctests cannot be merged. For example, if you have: ``` The problem with this code is that, if you change any other doctests, it'll likely break when -runing `rustdoc --test`, making it tricky to maintain. +running `rustdoc --test`, making it tricky to maintain. This is where the `standalone_crate` attribute comes in: it tells `rustdoc` that a doctest should not be merged with the others. So the previous code should use it: diff --git a/src/doc/unstable-book/src/language-features/rustc-private.md b/src/doc/unstable-book/src/language-features/rustc-private.md index 97fce5980e4..3b83a3cf4df 100644 --- a/src/doc/unstable-book/src/language-features/rustc-private.md +++ b/src/doc/unstable-book/src/language-features/rustc-private.md @@ -6,6 +6,9 @@ The tracking issue for this feature is: [#27812] ------------------------ -This feature allows access to unstable internal compiler crates. +This feature allows access to unstable internal compiler crates such as `rustc_driver`. -Additionally it changes the linking behavior of crates which have this feature enabled. It will prevent linking to a dylib if there's a static variant of it already statically linked into another dylib dependency. This is required to successfully link to `rustc_driver`. +The presence of this feature changes the way the linkage format for dylibs is calculated in a way +that is necessary for linking against dylibs that statically link `std` (such as `rustc_driver`). +This makes this feature "viral" in linkage; its use in a given crate makes its use required in +dependent crates which link to it (including integration tests, which are built as separate crates). diff --git a/src/etc/completions/x.fish b/src/etc/completions/x.fish index f0927183c07..49fe10a4ea2 100644 --- a/src/etc/completions/x.fish +++ b/src/etc/completions/x.fish @@ -319,6 +319,7 @@ complete -c x -n "__fish_x_using_subcommand test" -l bless -d 'whether to automa complete -c x -n "__fish_x_using_subcommand test" -l force-rerun -d 'rerun tests even if the inputs are unchanged' complete -c x -n "__fish_x_using_subcommand test" -l only-modified -d 'only run tests that result has been changed' complete -c x -n "__fish_x_using_subcommand test" -l rustfix-coverage -d 'enable this to generate a Rustfix coverage file, which is saved in `/<build_base>/rustfix_missing_coverage.txt`' +complete -c x -n "__fish_x_using_subcommand test" -l no-capture -d 'don\'t capture stdout/stderr of tests' complete -c x -n "__fish_x_using_subcommand test" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x -n "__fish_x_using_subcommand test" -s i -l incremental -d 'use incremental compilation' complete -c x -n "__fish_x_using_subcommand test" -l include-default-paths -d 'include default paths in addition to the provided ones' diff --git a/src/etc/completions/x.ps1 b/src/etc/completions/x.ps1 index 7cbf0f0d13c..fa833b6876a 100644 --- a/src/etc/completions/x.ps1 +++ b/src/etc/completions/x.ps1 @@ -366,6 +366,7 @@ Register-ArgumentCompleter -Native -CommandName 'x' -ScriptBlock { [CompletionResult]::new('--force-rerun', '--force-rerun', [CompletionResultType]::ParameterName, 'rerun tests even if the inputs are unchanged') [CompletionResult]::new('--only-modified', '--only-modified', [CompletionResultType]::ParameterName, 'only run tests that result has been changed') [CompletionResult]::new('--rustfix-coverage', '--rustfix-coverage', [CompletionResultType]::ParameterName, 'enable this to generate a Rustfix coverage file, which is saved in `/<build_base>/rustfix_missing_coverage.txt`') + [CompletionResult]::new('--no-capture', '--no-capture', [CompletionResultType]::ParameterName, 'don''t capture stdout/stderr of tests') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish index df31b0d644e..07144ad22d1 100644 --- a/src/etc/completions/x.py.fish +++ b/src/etc/completions/x.py.fish @@ -319,6 +319,7 @@ complete -c x.py -n "__fish_x.py_using_subcommand test" -l bless -d 'whether to complete -c x.py -n "__fish_x.py_using_subcommand test" -l force-rerun -d 'rerun tests even if the inputs are unchanged' complete -c x.py -n "__fish_x.py_using_subcommand test" -l only-modified -d 'only run tests that result has been changed' complete -c x.py -n "__fish_x.py_using_subcommand test" -l rustfix-coverage -d 'enable this to generate a Rustfix coverage file, which is saved in `/<build_base>/rustfix_missing_coverage.txt`' +complete -c x.py -n "__fish_x.py_using_subcommand test" -l no-capture -d 'don\'t capture stdout/stderr of tests' complete -c x.py -n "__fish_x.py_using_subcommand test" -s v -l verbose -d 'use verbose output (-vv for very verbose)' complete -c x.py -n "__fish_x.py_using_subcommand test" -s i -l incremental -d 'use incremental compilation' complete -c x.py -n "__fish_x.py_using_subcommand test" -l include-default-paths -d 'include default paths in addition to the provided ones' diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1 index afbfb055abd..7d5bd3c9632 100644 --- a/src/etc/completions/x.py.ps1 +++ b/src/etc/completions/x.py.ps1 @@ -366,6 +366,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock { [CompletionResult]::new('--force-rerun', '--force-rerun', [CompletionResultType]::ParameterName, 'rerun tests even if the inputs are unchanged') [CompletionResult]::new('--only-modified', '--only-modified', [CompletionResultType]::ParameterName, 'only run tests that result has been changed') [CompletionResult]::new('--rustfix-coverage', '--rustfix-coverage', [CompletionResultType]::ParameterName, 'enable this to generate a Rustfix coverage file, which is saved in `/<build_base>/rustfix_missing_coverage.txt`') + [CompletionResult]::new('--no-capture', '--no-capture', [CompletionResultType]::ParameterName, 'don''t capture stdout/stderr of tests') [CompletionResult]::new('-v', '-v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('--verbose', '--verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)') [CompletionResult]::new('-i', '-i', [CompletionResultType]::ParameterName, 'use incremental compilation') diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh index ba7f2c9fb5d..5c5e4ef0c15 100644 --- a/src/etc/completions/x.py.sh +++ b/src/etc/completions/x.py.sh @@ -3119,7 +3119,7 @@ _x.py() { return 0 ;; x.py__test) - opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh index 415fe09718c..dd71ec00edf 100644 --- a/src/etc/completions/x.py.zsh +++ b/src/etc/completions/x.py.zsh @@ -365,6 +365,7 @@ _arguments "${_arguments_options[@]}" : \ '--force-rerun[rerun tests even if the inputs are unchanged]' \ '--only-modified[only run tests that result has been changed]' \ '--rustfix-coverage[enable this to generate a Rustfix coverage file, which is saved in \`/<build_base>/rustfix_missing_coverage.txt\`]' \ +'--no-capture[don'\''t capture stdout/stderr of tests]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ diff --git a/src/etc/completions/x.sh b/src/etc/completions/x.sh index a4cf80acc30..057af1ffc6d 100644 --- a/src/etc/completions/x.sh +++ b/src/etc/completions/x.sh @@ -3119,7 +3119,7 @@ _x() { return 0 ;; x__test) - opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..." + opts="-v -i -j -h --no-fail-fast --test-args --compiletest-rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --no-capture --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..." if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") ) return 0 diff --git a/src/etc/completions/x.zsh b/src/etc/completions/x.zsh index ee6f504f93e..6215f9af833 100644 --- a/src/etc/completions/x.zsh +++ b/src/etc/completions/x.zsh @@ -365,6 +365,7 @@ _arguments "${_arguments_options[@]}" : \ '--force-rerun[rerun tests even if the inputs are unchanged]' \ '--only-modified[only run tests that result has been changed]' \ '--rustfix-coverage[enable this to generate a Rustfix coverage file, which is saved in \`/<build_base>/rustfix_missing_coverage.txt\`]' \ +'--no-capture[don'\''t capture stdout/stderr of tests]' \ '*-v[use verbose output (-vv for very verbose)]' \ '*--verbose[use verbose output (-vv for very verbose)]' \ '-i[use incremental compilation]' \ diff --git a/src/etc/test-float-parse/README.md b/src/etc/test-float-parse/README.md index 21b20d0a072..5e2c43d1cad 100644 --- a/src/etc/test-float-parse/README.md +++ b/src/etc/test-float-parse/README.md @@ -3,7 +3,7 @@ These are tests designed to test decimal to float conversions (`dec2flt`) used by the standard library. -It consistes of a collection of test generators that each generate a set of +It consists of a collection of test generators that each generate a set of patterns intended to test a specific property. In addition, there are exhaustive tests (for <= `f32`) and fuzzers (for anything that can't be run exhaustively). diff --git a/src/etc/test-float-parse/src/lib.rs b/src/etc/test-float-parse/src/lib.rs index 71b1aa06671..3c71b0dc32e 100644 --- a/src/etc/test-float-parse/src/lib.rs +++ b/src/etc/test-float-parse/src/lib.rs @@ -35,7 +35,7 @@ const DEFAULT_MAX_FAILURES: u64 = 20; /// Register exhaustive tests only for <= 32 bits. No more because it would take years. const MAX_BITS_FOR_EXHAUUSTIVE: u32 = 32; -/// If there are more tests than this threashold, the test will be defered until after all +/// If there are more tests than this threshold, the test will be deferred until after all /// others run (so as to avoid thread pool starvation). They also can be excluded with /// `--skip-huge`. const HUGE_TEST_CUTOFF: u64 = 5_000_000; @@ -109,7 +109,7 @@ pub fn run(cfg: Config, include: &[String], exclude: &[String]) -> ExitCode { ui::finish(&tests, elapsed, &cfg) } -/// Enumerate tests to run but don't actaully run them. +/// Enumerate tests to run but don't actually run them. pub fn register_tests(cfg: &Config) -> Vec<TestInfo> { let mut tests = Vec::new(); @@ -120,7 +120,7 @@ pub fn register_tests(cfg: &Config) -> Vec<TestInfo> { tests.sort_unstable_by_key(|t| (t.float_name, t.gen_name)); for i in 0..(tests.len() - 1) { if tests[i].gen_name == tests[i + 1].gen_name { - panic!("dupliate test name {}", tests[i].gen_name); + panic!("duplicate test name {}", tests[i].gen_name); } } @@ -295,7 +295,7 @@ enum Update { fail: CheckFailure, /// String for which parsing was attempted. input: Box<str>, - /// The parsed & decomposed `FloatRes`, aleady stringified so we don't need generics here. + /// The parsed & decomposed `FloatRes`, already stringified so we don't need generics here. float_res: Box<str>, }, /// Exited with an unexpected condition. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 4d46f0e75c8..3c9e0914b59 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -268,7 +268,7 @@ fn clean_poly_trait_ref_with_constraints<'tcx>( ) } -fn clean_lifetime(lifetime: &hir::Lifetime, cx: &mut DocContext<'_>) -> Lifetime { +fn clean_lifetime(lifetime: &hir::Lifetime, cx: &DocContext<'_>) -> Lifetime { if let Some( rbv::ResolvedArg::EarlyBound(did) | rbv::ResolvedArg::LateBound(_, _, did) @@ -362,9 +362,9 @@ pub(crate) fn clean_predicate<'tcx>( let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { ty::ClauseKind::Trait(pred) => clean_poly_trait_predicate(bound_predicate.rebind(pred), cx), - ty::ClauseKind::RegionOutlives(pred) => clean_region_outlives_predicate(pred), + ty::ClauseKind::RegionOutlives(pred) => Some(clean_region_outlives_predicate(pred)), ty::ClauseKind::TypeOutlives(pred) => { - clean_type_outlives_predicate(bound_predicate.rebind(pred), cx) + Some(clean_type_outlives_predicate(bound_predicate.rebind(pred), cx)) } ty::ClauseKind::Projection(pred) => { Some(clean_projection_predicate(bound_predicate.rebind(pred), cx)) @@ -396,32 +396,30 @@ fn clean_poly_trait_predicate<'tcx>( }) } -fn clean_region_outlives_predicate( - pred: ty::RegionOutlivesPredicate<'_>, -) -> Option<WherePredicate> { +fn clean_region_outlives_predicate(pred: ty::RegionOutlivesPredicate<'_>) -> WherePredicate { let ty::OutlivesPredicate(a, b) = pred; - Some(WherePredicate::RegionPredicate { + WherePredicate::RegionPredicate { lifetime: clean_middle_region(a).expect("failed to clean lifetime"), bounds: vec![GenericBound::Outlives( clean_middle_region(b).expect("failed to clean bounds"), )], - }) + } } fn clean_type_outlives_predicate<'tcx>( pred: ty::Binder<'tcx, ty::TypeOutlivesPredicate<'tcx>>, cx: &mut DocContext<'tcx>, -) -> Option<WherePredicate> { +) -> WherePredicate { let ty::OutlivesPredicate(ty, lt) = pred.skip_binder(); - Some(WherePredicate::BoundPredicate { + WherePredicate::BoundPredicate { ty: clean_middle_ty(pred.rebind(ty), cx, None, None), bounds: vec![GenericBound::Outlives( clean_middle_region(lt).expect("failed to clean lifetimes"), )], bound_params: Vec::new(), - }) + } } fn clean_middle_term<'tcx>( @@ -894,7 +892,7 @@ fn clean_ty_generics<'tcx>( // Add back a `Sized` bound if there are no *trait* bounds remaining (incl. `?Sized`). // Since all potential trait bounds are at the front we can just check the first bound. - if bounds.first().map_or(true, |b| !b.is_trait_bound()) { + if bounds.first().is_none_or(|b| !b.is_trait_bound()) { bounds.insert(0, GenericBound::sized(cx)); } @@ -1811,7 +1809,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T } TyKind::Slice(ty) => Slice(Box::new(clean_ty(ty, cx))), TyKind::Pat(ty, pat) => Type::Pat(Box::new(clean_ty(ty, cx)), format!("{pat:?}").into()), - TyKind::Array(ty, ref const_arg) => { + TyKind::Array(ty, const_arg) => { // NOTE(min_const_generics): We can't use `const_eval_poly` for constants // as we currently do not supply the parent generics to anonymous constants // but do allow `ConstKind::Param`. @@ -1860,7 +1858,7 @@ pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> T /// Returns `None` if the type could not be normalized fn normalize<'tcx>( - cx: &mut DocContext<'tcx>, + cx: &DocContext<'tcx>, ty: ty::Binder<'tcx, Ty<'tcx>>, ) -> Option<ty::Binder<'tcx, Ty<'tcx>>> { // HACK: low-churn fix for #79459 while we wait for a trait normalization fix @@ -2337,7 +2335,7 @@ fn clean_middle_opaque_bounds<'tcx>( // Add back a `Sized` bound if there are no *trait* bounds remaining (incl. `?Sized`). // Since all potential trait bounds are at the front we can just check the first bound. - if bounds.first().map_or(true, |b| !b.is_trait_bound()) { + if bounds.first().is_none_or(|b| !b.is_trait_bound()) { bounds.insert(0, GenericBound::sized(cx)); } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index e6e5123d0bb..009e9662933 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -220,7 +220,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions } = interface::run_compiler(config, |compiler| { let krate = rustc_interface::passes::parse(&compiler.sess); - let collector = rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { + let collector = rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { let crate_name = tcx.crate_name(LOCAL_CRATE).to_string(); let crate_attrs = tcx.hir().attrs(CRATE_HIR_ID); let opts = scrape_test_config(crate_name, crate_attrs, args_path); diff --git a/src/librustdoc/doctest/make.rs b/src/librustdoc/doctest/make.rs index a188bc8ebd9..7bcb9465948 100644 --- a/src/librustdoc/doctest/make.rs +++ b/src/librustdoc/doctest/make.rs @@ -538,7 +538,7 @@ fn handle_attr(mod_attr_pending: &mut String, source_info: &mut SourceInfo, edit // If it's complete, then we can clear the pending content. mod_attr_pending.clear(); } else { - mod_attr_pending.push_str("\n"); + mod_attr_pending.push('\n'); } } diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index b63122565c4..e64baca974d 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -305,6 +305,7 @@ impl DocFolder for CacheBuilder<'_, '_> { | clean::MacroItem(..) | clean::ProcMacroItem(..) | clean::VariantItem(..) => { + use rustc_data_structures::fx::IndexEntry as Entry; if !self.cache.stripped_mod { // Re-exported items mean that the same id can show up twice // in the rustdoc ast that we're looking at. We know, @@ -313,15 +314,15 @@ impl DocFolder for CacheBuilder<'_, '_> { // paths map if there was already an entry present and we're // not a public item. let item_def_id = item.item_id.expect_def_id(); - if !self.cache.paths.contains_key(&item_def_id) - || self - .cache - .effective_visibilities - .is_directly_public(self.tcx, item_def_id) - { - self.cache - .paths - .insert(item_def_id, (self.cache.stack.clone(), item.type_())); + match self.cache.paths.entry(item_def_id) { + Entry::Vacant(entry) => { + entry.insert((self.cache.stack.clone(), item.type_())); + } + Entry::Occupied(mut entry) => { + if entry.get().0.len() > self.cache.stack.len() { + entry.insert((self.cache.stack.clone(), item.type_())); + } + } } } } @@ -413,7 +414,7 @@ impl DocFolder for CacheBuilder<'_, '_> { let impl_item = Impl { impl_item: item }; let impl_did = impl_item.def_id(); let trait_did = impl_item.trait_did(); - if trait_did.map_or(true, |d| self.cache.traits.contains_key(&d)) { + if trait_did.is_none_or(|d| self.cache.traits.contains_key(&d)) { for did in dids { if self.impl_ids.entry(did).or_default().insert(impl_did) { self.cache.impls.entry(did).or_default().push(impl_item.clone()); diff --git a/src/librustdoc/html/escape.rs b/src/librustdoc/html/escape.rs index 48771571f8f..88654ed32da 100644 --- a/src/librustdoc/html/escape.rs +++ b/src/librustdoc/html/escape.rs @@ -104,10 +104,9 @@ impl fmt::Display for EscapeBodyTextWithWbr<'_> { continue; } let is_uppercase = || s.chars().any(|c| c.is_uppercase()); - let next_is_uppercase = - || pk.map_or(true, |(_, t)| t.chars().any(|c| c.is_uppercase())); - let next_is_underscore = || pk.map_or(true, |(_, t)| t.contains('_')); - let next_is_colon = || pk.map_or(true, |(_, t)| t.contains(':')); + let next_is_uppercase = || pk.is_none_or(|(_, t)| t.chars().any(|c| c.is_uppercase())); + let next_is_underscore = || pk.is_none_or(|(_, t)| t.contains('_')); + let next_is_colon = || pk.is_none_or(|(_, t)| t.contains(':')); // Check for CamelCase. // // `i - last > 3` avoids turning FmRadio into Fm<wbr>Radio, which is technically diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index aa8fdaaee4c..7e835585b73 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -480,7 +480,7 @@ impl<'a, I: Iterator<Item = SpannedEvent<'a>>> Iterator for SpannedLinkReplacer< type Item = SpannedEvent<'a>; fn next(&mut self) -> Option<Self::Item> { - let Some((mut event, range)) = self.iter.next() else { return None }; + let (mut event, range) = self.iter.next()?; self.inner.handle_event(&mut event); // Yield the modified event Some((event, range)) @@ -2039,7 +2039,7 @@ impl IdMap { let candidate = candidate.to_string(); if is_default_id(&candidate) { let id = format!("{}-{}", candidate, 1); - self.map.insert(candidate.into(), 2); + self.map.insert(candidate, 2); id } else { candidate @@ -2052,7 +2052,7 @@ impl IdMap { } }; - self.map.insert(id.clone().into(), 1); + self.map.insert(id.clone(), 1); id } diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 2d5df75e7dc..5d96dbc0ee6 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -748,7 +748,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> { &shared.layout, &page, "", - scrape_examples_help(&shared), + scrape_examples_help(shared), &shared.style_files, ); shared.fs.write(scrape_examples_help_file, v)?; diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index dfdf2cd6ec3..9a9ce31caaa 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1974,7 +1974,7 @@ fn render_impl( .opt_doc_value() .map(|dox| { Markdown { - content: &*dox, + content: &dox, links: &i.impl_item.links(cx), ids: &mut cx.id_map.borrow_mut(), error_codes: cx.shared.codes, diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 0fb77d38f16..e8230e63c0f 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1420,7 +1420,7 @@ fn item_union(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Uni ty: &'a clean::Type, ) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> { display_fn(move |f| { - let v = ty.print(&self.cx); + let v = ty.print(self.cx); write!(f, "{v}") }) } diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index 583d0214a46..7f072aa7e2f 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -312,15 +312,15 @@ fn from_clean_item(item: clean::Item, renderer: &JsonRenderer<'_>) -> ItemEnum { StructFieldItem(f) => ItemEnum::StructField(f.into_json(renderer)), EnumItem(e) => ItemEnum::Enum(e.into_json(renderer)), VariantItem(v) => ItemEnum::Variant(v.into_json(renderer)), - FunctionItem(f) => ItemEnum::Function(from_function(f, true, header.unwrap(), renderer)), + FunctionItem(f) => ItemEnum::Function(from_function(*f, true, header.unwrap(), renderer)), ForeignFunctionItem(f, _) => { - ItemEnum::Function(from_function(f, false, header.unwrap(), renderer)) + ItemEnum::Function(from_function(*f, false, header.unwrap(), renderer)) } TraitItem(t) => ItemEnum::Trait((*t).into_json(renderer)), TraitAliasItem(t) => ItemEnum::TraitAlias(t.into_json(renderer)), - MethodItem(m, _) => ItemEnum::Function(from_function(m, true, header.unwrap(), renderer)), + MethodItem(m, _) => ItemEnum::Function(from_function(*m, true, header.unwrap(), renderer)), RequiredMethodItem(m) => { - ItemEnum::Function(from_function(m, false, header.unwrap(), renderer)) + ItemEnum::Function(from_function(*m, false, header.unwrap(), renderer)) } ImplItem(i) => ItemEnum::Impl((*i).into_json(renderer)), StaticItem(s) => ItemEnum::Static(convert_static(s, rustc_hir::Safety::Safe, renderer)), @@ -730,12 +730,11 @@ impl FromClean<clean::Impl> for Impl { } pub(crate) fn from_function( - function: Box<clean::Function>, + clean::Function { decl, generics }: clean::Function, has_body: bool, header: rustc_hir::FnHeader, renderer: &JsonRenderer<'_>, ) -> Function { - let clean::Function { decl, generics } = *function; Function { sig: decl.into_json(renderer), generics: generics.into_json(renderer), diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index ff1c9c61720..d74dcc98cb0 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -869,7 +869,7 @@ fn main_args( sess.dcx().fatal("Compilation failed, aborting rustdoc"); } - rustc_interface::create_and_enter_global_ctxt(&compiler, krate, |tcx| { + rustc_interface::create_and_enter_global_ctxt(compiler, krate, |tcx| { let (krate, render_opts, mut cache) = sess.time("run_global_ctxt", || { core::run_global_ctxt(tcx, show_coverage, render_options, output_format) }); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 3c1d0c35bef..a777b45b807 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1977,7 +1977,7 @@ fn resolution_failure( } if !path_str.contains("::") { - if disambiguator.map_or(true, |d| d.ns() == MacroNS) + if disambiguator.is_none_or(|d| d.ns() == MacroNS) && collector .cx .tcx diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs index 5638d471890..01068af3e8c 100644 --- a/src/tools/compiletest/src/directive-list.rs +++ b/src/tools/compiletest/src/directive-list.rs @@ -160,10 +160,10 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[ "needs-xray", "no-auto-check-cfg", "no-prefer-dynamic", + "normalize-stderr", "normalize-stderr-32bit", "normalize-stderr-64bit", - "normalize-stderr-test", - "normalize-stdout-test", + "normalize-stdout", "only-16bit", "only-32bit", "only-64bit", diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 91558d0c898..48149e3b897 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -12,7 +12,6 @@ use tracing::*; use crate::common::{Config, Debugger, FailMode, Mode, PassMode}; use crate::debuggers::{extract_cdb_version, extract_gdb_version}; use crate::header::auxiliary::{AuxProps, parse_and_update_aux}; -use crate::header::cfg::{MatchOutcome, parse_cfg_name_directive}; use crate::header::needs::CachedNeedsConditions; use crate::util::static_regex; @@ -472,11 +471,24 @@ impl TestProps { config.set_name_directive(ln, IGNORE_PASS, &mut self.ignore_pass); - if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stdout") { - self.normalize_stdout.push(rule); - } - if let Some(rule) = config.parse_custom_normalization(ln, "normalize-stderr") { - self.normalize_stderr.push(rule); + if let Some(NormalizeRule { kind, regex, replacement }) = + config.parse_custom_normalization(ln) + { + let rule_tuple = (regex, replacement); + match kind { + NormalizeKind::Stdout => self.normalize_stdout.push(rule_tuple), + NormalizeKind::Stderr => self.normalize_stderr.push(rule_tuple), + NormalizeKind::Stderr32bit => { + if config.target_cfg().pointer_width == 32 { + self.normalize_stderr.push(rule_tuple); + } + } + NormalizeKind::Stderr64bit => { + if config.target_cfg().pointer_width == 64 { + self.normalize_stderr.push(rule_tuple); + } + } + } } if let Some(code) = config @@ -966,20 +978,26 @@ impl Config { } } - fn parse_custom_normalization(&self, line: &str, prefix: &str) -> Option<(String, String)> { - let parsed = parse_cfg_name_directive(self, line, prefix); - if parsed.outcome != MatchOutcome::Match { - return None; - } - let name = parsed.name.expect("successful match always has a name"); + fn parse_custom_normalization(&self, raw_directive: &str) -> Option<NormalizeRule> { + // FIXME(Zalathar): Integrate name/value splitting into `DirectiveLine` + // instead of doing it here. + let (directive_name, raw_value) = raw_directive.split_once(':')?; + + let kind = match directive_name { + "normalize-stdout" => NormalizeKind::Stdout, + "normalize-stderr" => NormalizeKind::Stderr, + "normalize-stderr-32bit" => NormalizeKind::Stderr32bit, + "normalize-stderr-64bit" => NormalizeKind::Stderr64bit, + _ => return None, + }; - let Some((regex, replacement)) = parse_normalize_rule(line) else { + let Some((regex, replacement)) = parse_normalize_rule(raw_value) else { panic!( - "couldn't parse custom normalization rule: `{line}`\n\ - help: expected syntax is: `{prefix}-{name}: \"REGEX\" -> \"REPLACEMENT\"`" + "couldn't parse custom normalization rule: `{raw_directive}`\n\ + help: expected syntax is: `{directive_name}: \"REGEX\" -> \"REPLACEMENT\"`" ); }; - Some((regex, replacement)) + Some(NormalizeRule { kind, regex, replacement }) } fn parse_name_directive(&self, line: &str, directive: &str) -> bool { @@ -1105,27 +1123,42 @@ fn expand_variables(mut value: String, config: &Config) -> String { value } +struct NormalizeRule { + kind: NormalizeKind, + regex: String, + replacement: String, +} + +enum NormalizeKind { + Stdout, + Stderr, + Stderr32bit, + Stderr64bit, +} + /// Parses the regex and replacement values of a `//@ normalize-*` header, /// in the format: /// ```text -/// normalize-*: "REGEX" -> "REPLACEMENT" +/// "REGEX" -> "REPLACEMENT" /// ``` -fn parse_normalize_rule(header: &str) -> Option<(String, String)> { +fn parse_normalize_rule(raw_value: &str) -> Option<(String, String)> { // FIXME: Support escaped double-quotes in strings. let captures = static_regex!( r#"(?x) # (verbose mode regex) ^ - [^:\s]+:\s* # (header name followed by colon) + \s* # (leading whitespace) "(?<regex>[^"]*)" # "REGEX" \s+->\s+ # -> "(?<replacement>[^"]*)" # "REPLACEMENT" $ "# ) - .captures(header)?; + .captures(raw_value)?; let regex = captures["regex"].to_owned(); let replacement = captures["replacement"].to_owned(); - // FIXME: Support escaped new-line in strings. + // A `\n` sequence in the replacement becomes an actual newline. + // FIXME: Do unescaping in a less ad-hoc way, and perhaps support escaped + // backslashes and double-quotes. let replacement = replacement.replace("\\n", "\n"); Some((regex, replacement)) } diff --git a/src/tools/compiletest/src/header/cfg.rs b/src/tools/compiletest/src/header/cfg.rs index 3ab552903dc..3f7225195ce 100644 --- a/src/tools/compiletest/src/header/cfg.rs +++ b/src/tools/compiletest/src/header/cfg.rs @@ -40,8 +40,8 @@ pub(super) fn handle_only(config: &Config, line: &str) -> IgnoreDecision { } /// Parses a name-value directive which contains config-specific information, e.g., `ignore-x86` -/// or `normalize-stderr-32bit`. -pub(super) fn parse_cfg_name_directive<'a>( +/// or `only-windows`. +fn parse_cfg_name_directive<'a>( config: &Config, line: &'a str, prefix: &str, diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index cd7c6f8361e..618b66dfd4c 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -35,11 +35,14 @@ fn make_test_description<R: Read>( #[test] fn test_parse_normalize_rule() { - let good_data = &[( - r#"normalize-stderr-32bit: "something (32 bits)" -> "something ($WORD bits)""#, - "something (32 bits)", - "something ($WORD bits)", - )]; + let good_data = &[ + ( + r#""something (32 bits)" -> "something ($WORD bits)""#, + "something (32 bits)", + "something ($WORD bits)", + ), + (r#" " with whitespace" -> " replacement""#, " with whitespace", " replacement"), + ]; for &(input, expected_regex, expected_replacement) in good_data { let parsed = parse_normalize_rule(input); @@ -49,15 +52,15 @@ fn test_parse_normalize_rule() { } let bad_data = &[ - r#"normalize-stderr-32bit "something (32 bits)" -> "something ($WORD bits)""#, - r#"normalize-stderr-16bit: something (16 bits) -> something ($WORD bits)"#, - r#"normalize-stderr-32bit: something (32 bits) -> something ($WORD bits)"#, - r#"normalize-stderr-32bit: "something (32 bits) -> something ($WORD bits)"#, - r#"normalize-stderr-32bit: "something (32 bits)" -> "something ($WORD bits)"#, - r#"normalize-stderr-32bit: "something (32 bits)" -> "something ($WORD bits)"."#, + r#"something (11 bits) -> something ($WORD bits)"#, + r#"something (12 bits) -> something ($WORD bits)"#, + r#""something (13 bits) -> something ($WORD bits)"#, + r#""something (14 bits)" -> "something ($WORD bits)"#, + r#""something (15 bits)" -> "something ($WORD bits)"."#, ]; for &input in bad_data { + println!("- {input:?}"); let parsed = parse_normalize_rule(input); assert_eq!(parsed, None); } diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs index 250ef0794ad..74d1f5637a8 100644 --- a/src/tools/compiletest/src/lib.rs +++ b/src/tools/compiletest/src/lib.rs @@ -159,7 +159,9 @@ pub fn parse_config(args: Vec<String>) -> Config { ) .optflag("", "force-rerun", "rerun tests even if the inputs are unchanged") .optflag("", "only-modified", "only run tests that result been modified") + // FIXME: Temporarily retained so we can point users to `--no-capture` .optflag("", "nocapture", "") + .optflag("", "no-capture", "don't capture stdout/stderr of tests") .optflag("", "profiler-runtime", "is the profiler runtime enabled for this target") .optflag("h", "help", "show this message") .reqopt("", "channel", "current Rust channel", "CHANNEL") @@ -288,6 +290,10 @@ pub fn parse_config(args: Vec<String>) -> Config { ); }) }); + if matches.opt_present("nocapture") { + panic!("`--nocapture` is deprecated; please use `--no-capture`"); + } + Config { bless: matches.opt_present("bless"), compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")), @@ -385,7 +391,7 @@ pub fn parse_config(args: Vec<String>) -> Config { target_cfgs: OnceLock::new(), builtin_cfg_names: OnceLock::new(), - nocapture: matches.opt_present("nocapture"), + nocapture: matches.opt_present("no-capture"), git_repository: matches.opt_str("git-repository").unwrap(), nightly_branch: matches.opt_str("nightly-branch").unwrap(), diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 108fde1c899..7084c407a64 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -213,7 +213,7 @@ fn remove_and_create_dir_all(path: &Path) { fs::create_dir_all(path).unwrap(); } -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] struct TestCx<'test> { config: &'test Config, props: &'test TestProps, @@ -2318,32 +2318,47 @@ impl<'test> TestCx<'test> { match output_kind { TestOutput::Compile => { if !self.props.dont_check_compiler_stdout { - errors += self.compare_output( + if self + .compare_output( + stdout_kind, + &normalized_stdout, + &proc_res.stdout, + &expected_stdout, + ) + .should_error() + { + errors += 1; + } + } + if !self.props.dont_check_compiler_stderr { + if self + .compare_output(stderr_kind, &normalized_stderr, &stderr, &expected_stderr) + .should_error() + { + errors += 1; + } + } + } + TestOutput::Run => { + if self + .compare_output( stdout_kind, &normalized_stdout, &proc_res.stdout, &expected_stdout, - ); + ) + .should_error() + { + errors += 1; } - if !self.props.dont_check_compiler_stderr { - errors += self.compare_output( - stderr_kind, - &normalized_stderr, - &stderr, - &expected_stderr, - ); + + if self + .compare_output(stderr_kind, &normalized_stderr, &stderr, &expected_stderr) + .should_error() + { + errors += 1; } } - TestOutput::Run => { - errors += self.compare_output( - stdout_kind, - &normalized_stdout, - &proc_res.stdout, - &expected_stdout, - ); - errors += - self.compare_output(stderr_kind, &normalized_stderr, &stderr, &expected_stderr); - } } errors } @@ -2576,7 +2591,14 @@ impl<'test> TestCx<'test> { actual: &str, actual_unnormalized: &str, expected: &str, - ) -> usize { + ) -> CompareOutcome { + let expected_path = + expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream); + + if self.config.bless && actual.is_empty() && expected_path.exists() { + self.delete_file(&expected_path); + } + let are_different = match (self.force_color_svg(), expected.find('\n'), actual.find('\n')) { // FIXME: We ignore the first line of SVG files // because the width parameter is non-deterministic. @@ -2584,7 +2606,7 @@ impl<'test> TestCx<'test> { _ => expected != actual, }; if !are_different { - return 0; + return CompareOutcome::Same; } // Wrapper tools set by `runner` might provide extra output on failure, @@ -2600,7 +2622,7 @@ impl<'test> TestCx<'test> { used.retain(|line| actual_lines.contains(line)); // check if `expected` contains a subset of the lines of `actual` if used.len() == expected_lines.len() && (expected.is_empty() == actual.is_empty()) { - return 0; + return CompareOutcome::Same; } if expected_lines.is_empty() { // if we have no lines to check, force a full overwite @@ -2626,9 +2648,6 @@ impl<'test> TestCx<'test> { } println!("Saved the actual {stream} to {actual_path:?}"); - let expected_path = - expected_output_path(self.testpaths, self.revision, &self.config.compare_mode, stream); - if !self.config.bless { if expected.is_empty() { println!("normalized {}:\n{}\n", stream, actual); @@ -2651,15 +2670,17 @@ impl<'test> TestCx<'test> { self.delete_file(&old); } - if let Err(err) = fs::write(&expected_path, &actual) { - self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}")); + if !actual.is_empty() { + if let Err(err) = fs::write(&expected_path, &actual) { + self.fatal(&format!("failed to write {stream} to `{expected_path:?}`: {err}")); + } + println!("Blessing the {stream} of {test_name} in {expected_path:?}"); } - println!("Blessing the {stream} of {test_name} in {expected_path:?}"); } println!("\nThe actual {0} differed from the expected {0}.", stream); - if self.config.bless { 0 } else { 1 } + if self.config.bless { CompareOutcome::Blessed } else { CompareOutcome::Differed } } /// Returns whether to show the full stderr/stdout. @@ -2885,3 +2906,21 @@ enum AuxType { Dylib, ProcMacro, } + +/// Outcome of comparing a stream to a blessed file, +/// e.g. `.stderr` and `.fixed`. +#[derive(Copy, Clone, Debug, PartialEq, Eq)] +enum CompareOutcome { + /// Expected and actual outputs are the same + Same, + /// Outputs differed but were blessed + Blessed, + /// Outputs differed and an error should be emitted + Differed, +} + +impl CompareOutcome { + fn should_error(&self) -> bool { + matches!(self, CompareOutcome::Differed) + } +} diff --git a/src/tools/compiletest/src/runtest/coverage.rs b/src/tools/compiletest/src/runtest/coverage.rs index 030ca5ebb24..56fc5baf5f2 100644 --- a/src/tools/compiletest/src/runtest/coverage.rs +++ b/src/tools/compiletest/src/runtest/coverage.rs @@ -39,16 +39,16 @@ impl<'test> TestCx<'test> { let expected_coverage_dump = self.load_expected_output(kind); let actual_coverage_dump = self.normalize_output(&proc_res.stdout, &[]); - let coverage_dump_errors = self.compare_output( + let coverage_dump_compare_outcome = self.compare_output( kind, &actual_coverage_dump, &proc_res.stdout, &expected_coverage_dump, ); - if coverage_dump_errors > 0 { + if coverage_dump_compare_outcome.should_error() { self.fatal_proc_rec( - &format!("{coverage_dump_errors} errors occurred comparing coverage output."), + &format!("an error occurred comparing coverage output."), &proc_res, ); } @@ -139,16 +139,16 @@ impl<'test> TestCx<'test> { self.fatal_proc_rec(&err, &proc_res); }); - let coverage_errors = self.compare_output( + let coverage_dump_compare_outcome = self.compare_output( kind, &normalized_actual_coverage, &proc_res.stdout, &expected_coverage, ); - if coverage_errors > 0 { + if coverage_dump_compare_outcome.should_error() { self.fatal_proc_rec( - &format!("{} errors occurred comparing coverage output.", coverage_errors), + &format!("an error occurred comparing coverage output."), &proc_res, ); } diff --git a/src/tools/compiletest/src/runtest/debugger.rs b/src/tools/compiletest/src/runtest/debugger.rs index c15422fb6f6..d9e5c3fa0d8 100644 --- a/src/tools/compiletest/src/runtest/debugger.rs +++ b/src/tools/compiletest/src/runtest/debugger.rs @@ -19,15 +19,9 @@ pub(super) struct DebuggerCommands { } impl DebuggerCommands { - pub fn parse_from( - file: &Path, - config: &Config, - debugger_prefixes: &[&str], - ) -> Result<Self, String> { - let directives = debugger_prefixes - .iter() - .map(|prefix| (format!("{prefix}-command"), format!("{prefix}-check"))) - .collect::<Vec<_>>(); + pub fn parse_from(file: &Path, config: &Config, debugger_prefix: &str) -> Result<Self, String> { + let command_directive = format!("{debugger_prefix}-command"); + let check_directive = format!("{debugger_prefix}-check"); let mut breakpoint_lines = vec![]; let mut commands = vec![]; @@ -48,14 +42,11 @@ impl DebuggerCommands { continue; }; - for &(ref command_directive, ref check_directive) in &directives { - config - .parse_name_value_directive(&line, command_directive) - .map(|cmd| commands.push(cmd)); - - config - .parse_name_value_directive(&line, check_directive) - .map(|cmd| check_lines.push((line_no, cmd))); + if let Some(command) = config.parse_name_value_directive(&line, &command_directive) { + commands.push(command); + } + if let Some(pattern) = config.parse_name_value_directive(&line, &check_directive) { + check_lines.push((line_no, pattern)); } } diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs index c621c22ac99..b236b067569 100644 --- a/src/tools/compiletest/src/runtest/debuginfo.rs +++ b/src/tools/compiletest/src/runtest/debuginfo.rs @@ -59,14 +59,8 @@ impl TestCx<'_> { return; } - let prefixes = { - static PREFIXES: &[&str] = &["cdb", "cdbg"]; - // No "native rust support" variation for CDB yet. - PREFIXES - }; - // Parse debugger commands etc from test files - let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, prefixes) + let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, "cdb") .unwrap_or_else(|e| self.fatal(&e)); // https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-commands @@ -137,7 +131,7 @@ impl TestCx<'_> { } fn run_debuginfo_gdb_test_no_opt(&self) { - let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, &["gdb"]) + let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, "gdb") .unwrap_or_else(|e| self.fatal(&e)); let mut cmds = dbg_cmds.commands.join("\n"); @@ -403,7 +397,7 @@ impl TestCx<'_> { } // Parse debugger commands etc from test files - let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, &["lldb"]) + let dbg_cmds = DebuggerCommands::parse_from(&self.testpaths.file, self.config, "lldb") .unwrap_or_else(|e| self.fatal(&e)); // Write debugger script: diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs index 10528de427d..0c6d46188e6 100644 --- a/src/tools/compiletest/src/runtest/ui.rs +++ b/src/tools/compiletest/src/runtest/ui.rs @@ -100,7 +100,12 @@ impl TestCx<'_> { ) }); - errors += self.compare_output("fixed", &fixed_code, &fixed_code, &expected_fixed); + if self + .compare_output("fixed", &fixed_code, &fixed_code, &expected_fixed) + .should_error() + { + errors += 1; + } } else if !expected_fixed.is_empty() { panic!( "the `//@ run-rustfix` directive wasn't found but a `*.fixed` \ diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 833e41df537..570b2c374c0 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -8,7 +8,7 @@ //! //! Currently uses a combination of HTML parsing to //! extract the `href` and `id` attributes, -//! and regex search on the orignal markdown to handle intra-doc links. +//! and regex search on the original markdown to handle intra-doc links. //! //! These values are then translated to file URLs if possible and then the //! destination is asserted to exist. diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs index 89fdd2a01eb..de154d771a0 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.rs @@ -1,7 +1,7 @@ #![feature(core_intrinsics)] #![feature(rustc_attrs)] -use std::intrinsics::typed_swap; +use std::intrinsics::typed_swap_nonoverlapping; use std::ptr::addr_of_mut; fn invalid_array() { @@ -10,7 +10,7 @@ fn invalid_array() { unsafe { let a = addr_of_mut!(a).cast::<[bool; 100]>(); let b = addr_of_mut!(b).cast::<[bool; 100]>(); - typed_swap(a, b); //~ERROR: constructing invalid value + typed_swap_nonoverlapping(a, b); //~ERROR: constructing invalid value } } diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr index 20b20412e75..5884d13a2ad 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-array.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: constructing invalid value at [0]: encountered 0x02, but expected a boolean --> tests/fail/intrinsics/typed-swap-invalid-array.rs:LL:CC | -LL | typed_swap(a, b); - | ^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered 0x02, but expected a boolean +LL | typed_swap_nonoverlapping(a, b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at [0]: encountered 0x02, but expected a boolean | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr index 6062465f36a..9804233c7fa 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.stderr +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.left.stderr @@ -1,8 +1,8 @@ error: Undefined Behavior: constructing invalid value: encountered 0x02, but expected a boolean --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC | -LL | typed_swap(a, b); - | ^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x02, but expected a boolean +LL | typed_swap_nonoverlapping(a, b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x02, but expected a boolean | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr new file mode 100644 index 00000000000..54b21f155ca --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.right.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: constructing invalid value: encountered 0x03, but expected a boolean + --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC + | +LL | typed_swap_nonoverlapping(a, b); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered 0x03, but expected a boolean + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `invalid_scalar` at tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC +note: inside `main` + --> tests/fail/intrinsics/typed-swap-invalid-scalar.rs:LL:CC + | +LL | invalid_scalar(); + | ^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs index 9d014a523f8..f5f9c7efbe4 100644 --- a/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-invalid-scalar.rs @@ -1,16 +1,18 @@ +//@revisions: left right #![feature(core_intrinsics)] #![feature(rustc_attrs)] -use std::intrinsics::typed_swap; +use std::intrinsics::typed_swap_nonoverlapping; use std::ptr::addr_of_mut; fn invalid_scalar() { - let mut a = 1_u8; - let mut b = 2_u8; + // We run the test twice, with either the left or the right side being invalid. + let mut a = if cfg!(left) { 2_u8 } else { 1_u8 }; + let mut b = if cfg!(right) { 3_u8 } else { 1_u8 }; unsafe { let a = addr_of_mut!(a).cast::<bool>(); let b = addr_of_mut!(b).cast::<bool>(); - typed_swap(a, b); //~ERROR: constructing invalid value + typed_swap_nonoverlapping(a, b); //~ERROR: constructing invalid value } } diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs new file mode 100644 index 00000000000..e643091a02a --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.rs @@ -0,0 +1,13 @@ +#![feature(core_intrinsics)] +#![feature(rustc_attrs)] + +use std::intrinsics::typed_swap_nonoverlapping; +use std::ptr::addr_of_mut; + +fn main() { + let mut a = 0_u8; + unsafe { + let a = addr_of_mut!(a); + typed_swap_nonoverlapping(a, a); //~ERROR: called on overlapping ranges + } +} diff --git a/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr new file mode 100644 index 00000000000..6d578841fe5 --- /dev/null +++ b/src/tools/miri/tests/fail/intrinsics/typed-swap-overlap.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: `copy_nonoverlapping` called on overlapping ranges + --> tests/fail/intrinsics/typed-swap-overlap.rs:LL:CC + | +LL | typed_swap_nonoverlapping(a, a); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `copy_nonoverlapping` called on overlapping ranges + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at tests/fail/intrinsics/typed-swap-overlap.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + diff --git a/src/tools/nix-dev-shell/envrc-flake b/src/tools/nix-dev-shell/envrc-flake index 849ed1f4fc5..f3e5442b86b 100644 --- a/src/tools/nix-dev-shell/envrc-flake +++ b/src/tools/nix-dev-shell/envrc-flake @@ -1,4 +1,4 @@ -# If you want to use this as an .envrc file to create a shell with necessery components +# If you want to use this as an .envrc file to create a shell with necessary components # to develop rustc, use the following command in the root of the rusr checkout: # # ln -s ./src/tools/nix-dev-shell/envrc-flake ./.envrc && nix flake update --flake ./src/tools/nix-dev-shell diff --git a/src/tools/nix-dev-shell/envrc-shell b/src/tools/nix-dev-shell/envrc-shell index d8f900fe86a..4080d7d5384 100644 --- a/src/tools/nix-dev-shell/envrc-shell +++ b/src/tools/nix-dev-shell/envrc-shell @@ -1,4 +1,4 @@ -# If you want to use this as an .envrc file to create a shell with necessery components +# If you want to use this as an .envrc file to create a shell with necessary components # to develop rustc, use the following command in the root of the rusr checkout: # # ln -s ./src/tools/nix-dev-shell/envrc-shell ./.envrc diff --git a/src/tools/rustbook/Cargo.lock b/src/tools/rustbook/Cargo.lock index 68fb9895ecd..1f98e820840 100644 --- a/src/tools/rustbook/Cargo.lock +++ b/src/tools/rustbook/Cargo.lock @@ -96,9 +96,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fd03a028ef38ba2276dce7e33fcd6369c158a1bca17946c4b1b701891c1ff7" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] name = "autocfg" @@ -161,9 +161,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.2.5" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e" +checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" dependencies = [ "shlex", ] @@ -1209,9 +1209,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.37" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -1338,18 +1338,18 @@ checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" [[package]] name = "serde" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", @@ -1446,9 +1446,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.90" +version = "2.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" dependencies = [ "proc-macro2", "quote", @@ -1639,9 +1639,9 @@ checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "unicase" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e51b68083f157f853b6379db119d1c1be0e6e4dec98101079dec41f6f5cf6df" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" diff --git a/src/tools/rustc-perf-wrapper/src/main.rs b/src/tools/rustc-perf-wrapper/src/main.rs index 0b4c894e29d..e6c885e23de 100644 --- a/src/tools/rustc-perf-wrapper/src/main.rs +++ b/src/tools/rustc-perf-wrapper/src/main.rs @@ -1,5 +1,5 @@ use std::fs::create_dir_all; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; use std::process::Command; use clap::Parser; @@ -169,7 +169,7 @@ fn execute_benchmark(cmd: &mut Command, compiler: &Path) { const MANIFEST_DIR: &str = env!("CARGO_MANIFEST_DIR"); - let rustc_perf_dir = PathBuf::from(MANIFEST_DIR).join("../rustc-perf"); + let rustc_perf_dir = Path::new(MANIFEST_DIR).join("../rustc-perf"); // We need to set the working directory to `src/tools/perf`, so that it can find the directory // with compile-time benchmarks. diff --git a/src/tools/suggest-tests/src/static_suggestions.rs b/src/tools/suggest-tests/src/static_suggestions.rs index b216138cf9a..d363d583b54 100644 --- a/src/tools/suggest-tests/src/static_suggestions.rs +++ b/src/tools/suggest-tests/src/static_suggestions.rs @@ -2,7 +2,7 @@ use std::sync::OnceLock; use crate::{Suggestion, sug}; -// FIXME: perhaps this could use `std::lazy` when it is stablizied +// FIXME: perhaps this could use `std::lazy` when it is stabilized macro_rules! static_suggestions { ($( [ $( $glob:expr ),* $(,)? ] => [ $( $suggestion:expr ),* $(,)? ] ),* $(,)? ) => { pub(crate) fn static_suggestions() -> &'static [(Vec<&'static str>, Vec<Suggestion>)] diff --git a/src/tools/tidy/Cargo.toml b/src/tools/tidy/Cargo.toml index bc75787fb1a..2f424a482b5 100644 --- a/src/tools/tidy/Cargo.toml +++ b/src/tools/tidy/Cargo.toml @@ -6,7 +6,7 @@ autobins = false [dependencies] build_helper = { path = "../../build_helper" } -cargo_metadata = "0.18" +cargo_metadata = "0.19" regex = "1" miropt-test-tools = { path = "../miropt-test-tools" } walkdir = "2" diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt index 0e156b9d1ac..b20d8678d0e 100644 --- a/src/tools/tidy/src/allowed_run_make_makefiles.txt +++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt @@ -1,9 +1,6 @@ -run-make/branch-protection-check-IBT/Makefile run-make/cat-and-grep-sanity-check/Makefile run-make/extern-fn-reachable/Makefile -run-make/incr-add-rust-src-component/Makefile run-make/jobserver-error/Makefile -run-make/libs-through-symlinks/Makefile run-make/split-debuginfo/Makefile run-make/symbol-mangling-hashed/Makefile run-make/translation/Makefile diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index beeb33b46ff..1794d0fbca7 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -1,12 +1,16 @@ //! Checks the licenses of third-party dependencies. use std::collections::HashSet; -use std::fs::read_dir; +use std::fs::{File, read_dir}; +use std::io::Write; use std::path::Path; use build_helper::ci::CiEnv; use cargo_metadata::{Metadata, Package, PackageId}; +#[path = "../../../bootstrap/src/utils/proc_macro_deps.rs"] +mod proc_macro_deps; + /// These are licenses that are allowed for all crates, including the runtime, /// rustc, tools, etc. #[rustfmt::skip] @@ -564,9 +568,11 @@ const PERMITTED_CRANELIFT_DEPENDENCIES: &[&str] = &[ /// /// `root` is path to the directory with the root `Cargo.toml` (for the workspace). `cargo` is path /// to the cargo executable. -pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { +pub fn check(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) { let mut checked_runtime_licenses = false; + check_proc_macro_dep_list(root, cargo, bless, bad); + for &(workspace, exceptions, permitted_deps, submodules) in WORKSPACES { if has_missing_submodule(root, submodules) { continue; @@ -600,6 +606,71 @@ pub fn check(root: &Path, cargo: &Path, bad: &mut bool) { assert!(checked_runtime_licenses); } +/// Ensure the list of proc-macro crate transitive dependencies is up to date +fn check_proc_macro_dep_list(root: &Path, cargo: &Path, bless: bool, bad: &mut bool) { + let mut cmd = cargo_metadata::MetadataCommand::new(); + cmd.cargo_path(cargo) + .manifest_path(root.join("Cargo.toml")) + .features(cargo_metadata::CargoOpt::AllFeatures) + .other_options(vec!["--locked".to_owned()]); + let metadata = t!(cmd.exec()); + let is_proc_macro_pkg = |pkg: &Package| pkg.targets.iter().any(|target| target.is_proc_macro()); + + let mut proc_macro_deps = HashSet::new(); + for pkg in metadata.packages.iter().filter(|pkg| is_proc_macro_pkg(*pkg)) { + deps_of(&metadata, &pkg.id, &mut proc_macro_deps); + } + // Remove the proc-macro crates themselves + proc_macro_deps.retain(|pkg| !is_proc_macro_pkg(&metadata[pkg])); + let proc_macro_deps_iter = proc_macro_deps.into_iter().map(|dep| metadata[dep].name.clone()); + + if bless { + let mut proc_macro_deps: Vec<_> = proc_macro_deps_iter.collect(); + proc_macro_deps.sort(); + proc_macro_deps.dedup(); + let mut file = File::create(root.join("src/bootstrap/src/utils/proc_macro_deps.rs")) + .expect("`proc_macro_deps` should exist"); + writeln!( + &mut file, + "/// Do not update manually - use `./x.py test tidy --bless` +/// Holds all direct and indirect dependencies of proc-macro crates in tree. +/// See <https://github.com/rust-lang/rust/issues/134863> +pub static CRATES: &[&str] = &[ + // tidy-alphabetical-start" + ) + .unwrap(); + for dep in proc_macro_deps { + writeln!(&mut file, " {dep:?},").unwrap(); + } + writeln!( + &mut file, + " // tidy-alphabetical-end +];" + ) + .unwrap(); + } else { + let proc_macro_deps: HashSet<_> = proc_macro_deps_iter.collect(); + let expected = + proc_macro_deps::CRATES.iter().map(|s| s.to_string()).collect::<HashSet<_>>(); + let old_bad = *bad; + for missing in proc_macro_deps.difference(&expected) { + tidy_error!( + bad, + "proc-macro crate dependency `{missing}` is not registered in `src/bootstrap/src/utils/proc_macro_deps.rs`", + ); + } + for extra in expected.difference(&proc_macro_deps) { + tidy_error!( + bad, + "`{extra}` is not registered in `src/bootstrap/src/utils/proc_macro_deps.rs`, but is not a proc-macro crate dependency", + ); + } + if *bad != old_bad { + eprintln!("Run `./x.py test tidy --bless` to regenerate the list"); + } + } +} + /// Used to skip a check if a submodule is not checked out, and not in a CI environment. /// /// This helps prevent enforcing developers to fetch submodules for tidy. diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index 40608952c0b..13a558fea48 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -95,7 +95,7 @@ fn main() { check!(target_specific_tests, &tests_path); // Checks that are done on the cargo workspace. - check!(deps, &root_path, &cargo); + check!(deps, &root_path, &cargo, bless); check!(extdeps, &root_path); // Checks over tests. diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index 35cda17e168..aefcd2bb0cc 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -69,8 +69,7 @@ const ANNOTATIONS_TO_IGNORE: &[&str] = &[ "// gdb", "// lldb", "// cdb", - "// normalize-stderr-test", - "//@ normalize-stderr-test", + "//@ normalize-stderr", ]; fn generate_problems<'a>( @@ -198,8 +197,8 @@ fn should_ignore(line: &str) -> bool { // For `ui_test`-style UI test directives, also ignore // - `//@[rev] compile-flags` - // - `//@[rev] normalize-stderr-test` - || static_regex!("\\s*//@(\\[.*\\]) (compile-flags|normalize-stderr-test|error-pattern).*") + // - `//@[rev] normalize-stderr` + || static_regex!("\\s*//@(\\[.*\\]) (compile-flags|normalize-stderr|error-pattern).*") .is_match(line) // Matching for rustdoc tests commands. // It allows to prevent them emitting warnings like `line longer than 100 chars`. |
