diff options
| author | bors <bors@rust-lang.org> | 2022-12-18 18:44:37 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-12-18 18:44:37 +0000 |
| commit | d0dc9efff14ac0a1eeceffd1e605e37eeb8362a0 (patch) | |
| tree | a8a822106633ae58a80f28af77cc817111af9d36 /src | |
| parent | 37efc8107293edb5970551920ba1128240b87c68 (diff) | |
| parent | 22379779b5842c4347b966e783a09e238f32369e (diff) | |
Auto merge of #105876 - matthiaskrgr:rollup-a9dgzjt, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #96584 (Fix `x setup -h -v` should work) - #105420 (Remove dead code after destination propagation) - #105844 (Make the x tool use the x and x.ps1 scripts) - #105854 (remove redundant clone) - #105858 (Another `as_chunks` example) - #105870 (avoid .into() conversion to identical types) - #105875 (don't destuct references just to reborrow) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'src')
| -rw-r--r-- | src/bootstrap/builder.rs | 15 | ||||
| -rw-r--r-- | src/bootstrap/flags.rs | 6 | ||||
| -rw-r--r-- | src/bootstrap/lib.rs | 4 | ||||
| -rw-r--r-- | src/bootstrap/setup.rs | 70 | ||||
| -rw-r--r-- | src/test/mir-opt/dest-prop/unreachable.f.DestinationPropagation.diff | 86 | ||||
| -rw-r--r-- | src/test/mir-opt/dest-prop/unreachable.rs | 18 | ||||
| -rw-r--r-- | src/tools/x/src/main.rs | 72 |
7 files changed, 210 insertions, 61 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 3f551dc119b..1d37d68c1d4 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -19,6 +19,7 @@ use crate::flags::{Color, Subcommand}; use crate::install; use crate::native; use crate::run; +use crate::setup; use crate::test; use crate::tool::{self, SourceType}; use crate::util::{self, add_dylib_path, add_link_lib_path, exe, libdir, output, t}; @@ -433,8 +434,11 @@ impl<'a> ShouldRun<'a> { // single alias, which does not correspond to any on-disk path pub fn alias(mut self, alias: &str) -> Self { + // exceptional case for `Kind::Setup` because its `library` + // and `compiler` options would otherwise naively match with + // `compiler` and `library` folders respectively. assert!( - !self.builder.src.join(alias).exists(), + self.kind == Kind::Setup || !self.builder.src.join(alias).exists(), "use `builder.path()` for real paths: {}", alias ); @@ -758,8 +762,9 @@ impl<'a> Builder<'a> { run::CollectLicenseMetadata, run::GenerateCopyright, ), + Kind::Setup => describe!(setup::Profile), // These commands either don't use paths, or they're special-cased in Build::build() - Kind::Clean | Kind::Format | Kind::Setup => vec![], + Kind::Clean | Kind::Format => vec![], } } @@ -822,7 +827,11 @@ impl<'a> Builder<'a> { Subcommand::Install { ref paths } => (Kind::Install, &paths[..]), Subcommand::Run { ref paths, .. } => (Kind::Run, &paths[..]), Subcommand::Format { .. } => (Kind::Format, &[][..]), - Subcommand::Clean { .. } | Subcommand::Setup { .. } => { + Subcommand::Setup { profile: ref path } => ( + Kind::Setup, + path.as_ref().map_or([].as_slice(), |path| std::slice::from_ref(path)), + ), + Subcommand::Clean { .. } => { panic!() } }; diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 37a8eb884ef..851cb5ecf4c 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -143,7 +143,7 @@ pub enum Subcommand { args: Vec<String>, }, Setup { - profile: Option<Profile>, + profile: Option<PathBuf>, }, } @@ -351,7 +351,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`", // fn usage() let usage = |exit_code: i32, opts: &Options, verbose: bool, subcommand_help: &str| -> ! { - let config = Config::parse(&["build".to_string()]); + let config = Config::parse(&["setup".to_string()]); let build = Build::new(config); let paths = Builder::get_help(&build, subcommand); @@ -621,7 +621,7 @@ Arguments: } Kind::Setup => { let profile = if paths.len() > 1 { - println!("\nat most one profile can be passed to setup\n"); + eprintln!("\nerror: At most one profile can be passed to setup\n"); usage(1, &opts, verbose, &subcommand_help) } else if let Some(path) = paths.pop() { let profile_string = t!(path.into_os_string().into_string().map_err( diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index f0c9a948727..47fb4a38d05 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -730,10 +730,6 @@ impl Build { return clean::clean(self, all); } - if let Subcommand::Setup { profile } = &self.config.cmd { - return setup::setup(&self.config, *profile); - } - // Download rustfmt early so that it can be used in rust-analyzer configs. let _ = &builder::Builder::new(&self).initial_rustfmt(); diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index c7f98a7d0d1..57426ce3d51 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -1,3 +1,4 @@ +use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::Config; use crate::{t, VERSION}; use std::env::consts::EXE_SUFFIX; @@ -9,7 +10,7 @@ use std::process::Command; use std::str::FromStr; use std::{fmt, fs, io}; -#[derive(Clone, Copy, Debug, Eq, PartialEq)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)] pub enum Profile { Compiler, Codegen, @@ -48,6 +49,16 @@ impl Profile { } out } + + pub fn as_str(&self) -> &'static str { + match self { + Profile::Compiler => "compiler", + Profile::Codegen => "codegen", + Profile::Library => "library", + Profile::Tools => "tools", + Profile::User => "user", + } + } } impl FromStr for Profile { @@ -69,24 +80,58 @@ impl FromStr for Profile { impl fmt::Display for Profile { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Profile::Compiler => write!(f, "compiler"), - Profile::Codegen => write!(f, "codegen"), - Profile::Library => write!(f, "library"), - Profile::User => write!(f, "user"), - Profile::Tools => write!(f, "tools"), + f.write_str(self.as_str()) + } +} + +impl Step for Profile { + type Output = (); + const DEFAULT: bool = true; + + fn should_run(mut run: ShouldRun<'_>) -> ShouldRun<'_> { + for choice in Profile::all() { + run = run.alias(choice.as_str()); } + run + } + + fn make_run(run: RunConfig<'_>) { + // for Profile, `run.paths` will have 1 and only 1 element + // this is because we only accept at most 1 path from user input. + // If user calls `x.py setup` without arguments, the interactive TUI + // will guide user to provide one. + let profile = if run.paths.len() > 1 { + // HACK: `builder` runs this step with all paths if no path was passed. + t!(interactive_path()) + } else { + run.paths + .first() + .unwrap() + .assert_single_path() + .path + .as_path() + .as_os_str() + .to_str() + .unwrap() + .parse() + .unwrap() + }; + + run.builder.ensure(profile); + } + + fn run(self, builder: &Builder<'_>) { + setup(&builder.build.config, self) } } -pub fn setup(config: &Config, profile: Option<Profile>) { - let profile = profile.unwrap_or_else(|| t!(interactive_path())); +pub fn setup(config: &Config, profile: Profile) { let stage_path = ["build", config.build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string()); if !rustup_installed() && profile != Profile::User { eprintln!("`rustup` is not installed; cannot link `stage1` toolchain"); - } else if stage_dir_exists(&stage_path[..]) { + } else if stage_dir_exists(&stage_path[..]) && !config.dry_run() { attempt_toolchain_link(&stage_path[..]); } @@ -104,7 +149,9 @@ pub fn setup(config: &Config, profile: Option<Profile>) { Profile::User => &["dist", "build"], }; - t!(install_git_hook_maybe(&config)); + if !config.dry_run() { + t!(install_git_hook_maybe(&config)); + } println!(); @@ -144,6 +191,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) { changelog-seen = {}\n", profile, VERSION ); + t!(fs::write(path, settings)); let include_path = profile.include_path(&config.src); diff --git a/src/test/mir-opt/dest-prop/unreachable.f.DestinationPropagation.diff b/src/test/mir-opt/dest-prop/unreachable.f.DestinationPropagation.diff new file mode 100644 index 00000000000..9ea756c2712 --- /dev/null +++ b/src/test/mir-opt/dest-prop/unreachable.f.DestinationPropagation.diff @@ -0,0 +1,86 @@ +- // MIR for `f` before DestinationPropagation ++ // MIR for `f` after DestinationPropagation + + fn f(_1: T) -> () { + debug a => _1; // in scope 0 at $DIR/unreachable.rs:+0:19: +0:20 + let mut _0: (); // return place in scope 0 at $DIR/unreachable.rs:+0:25: +0:25 + let _2: T; // in scope 0 at $DIR/unreachable.rs:+1:9: +1:10 + let mut _3: bool; // in scope 0 at $DIR/unreachable.rs:+2:8: +2:13 + let _4: (); // in scope 0 at $DIR/unreachable.rs:+3:9: +3:16 + let mut _5: T; // in scope 0 at $DIR/unreachable.rs:+3:11: +3:12 + let mut _6: T; // in scope 0 at $DIR/unreachable.rs:+3:14: +3:15 + let _7: (); // in scope 0 at $DIR/unreachable.rs:+5:9: +5:16 + let mut _8: T; // in scope 0 at $DIR/unreachable.rs:+5:11: +5:12 + let mut _9: T; // in scope 0 at $DIR/unreachable.rs:+5:14: +5:15 + scope 1 { +- debug b => _2; // in scope 1 at $DIR/unreachable.rs:+1:9: +1:10 ++ debug b => _1; // in scope 1 at $DIR/unreachable.rs:+1:9: +1:10 + } + + bb0: { +- StorageLive(_2); // scope 0 at $DIR/unreachable.rs:+1:9: +1:10 +- _2 = _1; // scope 0 at $DIR/unreachable.rs:+1:13: +1:14 ++ nop; // scope 0 at $DIR/unreachable.rs:+1:9: +1:10 ++ nop; // scope 0 at $DIR/unreachable.rs:+1:13: +1:14 + StorageLive(_3); // scope 1 at $DIR/unreachable.rs:+2:8: +2:13 + _3 = const false; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13 +- goto -> bb3; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13 ++ goto -> bb1; // scope 1 at $DIR/unreachable.rs:+2:8: +2:13 + } + + bb1: { +- StorageLive(_4); // scope 1 at $DIR/unreachable.rs:+3:9: +3:16 +- StorageLive(_5); // scope 1 at $DIR/unreachable.rs:+3:11: +3:12 +- _5 = _1; // scope 1 at $DIR/unreachable.rs:+3:11: +3:12 +- StorageLive(_6); // scope 1 at $DIR/unreachable.rs:+3:14: +3:15 +- _6 = _2; // scope 1 at $DIR/unreachable.rs:+3:14: +3:15 +- _4 = g::<T>(move _5, move _6) -> bb2; // scope 1 at $DIR/unreachable.rs:+3:9: +3:16 +- // mir::Constant +- // + span: $DIR/unreachable.rs:11:9: 11:10 +- // + literal: Const { ty: fn(T, T) {g::<T>}, val: Value(<ZST>) } +- } +- +- bb2: { +- StorageDead(_6); // scope 1 at $DIR/unreachable.rs:+3:15: +3:16 +- StorageDead(_5); // scope 1 at $DIR/unreachable.rs:+3:15: +3:16 +- StorageDead(_4); // scope 1 at $DIR/unreachable.rs:+3:16: +3:17 +- _0 = const (); // scope 1 at $DIR/unreachable.rs:+2:14: +4:6 +- goto -> bb5; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6 +- } +- +- bb3: { + StorageLive(_7); // scope 1 at $DIR/unreachable.rs:+5:9: +5:16 +- StorageLive(_8); // scope 1 at $DIR/unreachable.rs:+5:11: +5:12 +- _8 = _2; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12 ++ nop; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12 ++ nop; // scope 1 at $DIR/unreachable.rs:+5:11: +5:12 + StorageLive(_9); // scope 1 at $DIR/unreachable.rs:+5:14: +5:15 +- _9 = _2; // scope 1 at $DIR/unreachable.rs:+5:14: +5:15 +- _7 = g::<T>(move _8, move _9) -> bb4; // scope 1 at $DIR/unreachable.rs:+5:9: +5:16 ++ _9 = _1; // scope 1 at $DIR/unreachable.rs:+5:14: +5:15 ++ _7 = g::<T>(move _1, move _9) -> bb2; // scope 1 at $DIR/unreachable.rs:+5:9: +5:16 + // mir::Constant + // + span: $DIR/unreachable.rs:13:9: 13:10 + // + literal: Const { ty: fn(T, T) {g::<T>}, val: Value(<ZST>) } + } + +- bb4: { ++ bb2: { + StorageDead(_9); // scope 1 at $DIR/unreachable.rs:+5:15: +5:16 +- StorageDead(_8); // scope 1 at $DIR/unreachable.rs:+5:15: +5:16 ++ nop; // scope 1 at $DIR/unreachable.rs:+5:15: +5:16 + StorageDead(_7); // scope 1 at $DIR/unreachable.rs:+5:16: +5:17 + _0 = const (); // scope 1 at $DIR/unreachable.rs:+4:12: +6:6 +- goto -> bb5; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6 ++ goto -> bb3; // scope 1 at $DIR/unreachable.rs:+2:5: +6:6 + } + +- bb5: { ++ bb3: { + StorageDead(_3); // scope 1 at $DIR/unreachable.rs:+6:5: +6:6 +- StorageDead(_2); // scope 0 at $DIR/unreachable.rs:+7:1: +7:2 ++ nop; // scope 0 at $DIR/unreachable.rs:+7:1: +7:2 + return; // scope 0 at $DIR/unreachable.rs:+7:2: +7:2 + } + } + diff --git a/src/test/mir-opt/dest-prop/unreachable.rs b/src/test/mir-opt/dest-prop/unreachable.rs new file mode 100644 index 00000000000..32b5def984a --- /dev/null +++ b/src/test/mir-opt/dest-prop/unreachable.rs @@ -0,0 +1,18 @@ +// Check that unreachable code is removed after the destination propagation. +// Regression test for issue #105428. +// +// compile-flags: --crate-type=lib -Zmir-opt-level=0 +// compile-flags: -Zmir-enable-passes=+ConstProp,+SimplifyConstCondition-after-const-prop,+DestinationPropagation + +// EMIT_MIR unreachable.f.DestinationPropagation.diff +pub fn f<T: Copy>(a: T) { + let b = a; + if false { + g(a, b); + } else { + g(b, b); + } +} + +#[inline(never)] +pub fn g<T: Copy>(_: T, _: T) {} diff --git a/src/tools/x/src/main.rs b/src/tools/x/src/main.rs index 02c364dabf9..f07ff43efe9 100644 --- a/src/tools/x/src/main.rs +++ b/src/tools/x/src/main.rs @@ -1,51 +1,43 @@ -//! Run `x.py` from any subdirectory of a rust compiler checkout. +//! Run bootstrap from any subdirectory of a rust compiler checkout. //! //! We prefer `exec`, to avoid adding an extra process in the process tree. //! However, since `exec` isn't available on Windows, we indirect through //! `exec_or_status`, which will call `exec` on unix and `status` on Windows. //! -//! We use `python`, `python3`, or `python2` as the python interpreter to run -//! `x.py`, in that order of preference. +//! We use `powershell.exe x.ps1` on Windows, and `sh -c x` on Unix, those are +//! the ones that call `x.py`. We use `sh -c` on Unix, because it is a standard. +//! We also don't use `pwsh` on Windows, because it is not installed by default; use std::{ - env::{self, consts::EXE_EXTENSION}, - io, + env, io, + path::Path, process::{self, Command, ExitStatus}, }; -const PYTHON: &str = "python"; -const PYTHON2: &str = "python2"; -const PYTHON3: &str = "python3"; - -fn python() -> &'static str { - let val = match env::var_os("PATH") { - Some(val) => val, - None => return PYTHON, - }; - - let mut python2 = false; - let mut python3 = false; - - for dir in env::split_paths(&val) { - // `python` should always take precedence over python2 / python3 if it exists - if dir.join(PYTHON).with_extension(EXE_EXTENSION).exists() { - return PYTHON; - } +#[cfg(windows)] +fn x_command(dir: &Path) -> Command { + let mut cmd = Command::new("powershell.exe"); + cmd.args([ + "-NoLogo", + "-NoProfile", + "-NonInteractive", + "-ExecutionPolicy", + "RemoteSigned", + "-Command", + "./x.ps1", + ]) + .current_dir(dir); + cmd +} - python2 |= dir.join(PYTHON2).with_extension(EXE_EXTENSION).exists(); - python3 |= dir.join(PYTHON3).with_extension(EXE_EXTENSION).exists(); - } +#[cfg(unix)] +fn x_command(dir: &Path) -> Command { + Command::new(dir.join("x")) +} - // try 3 before 2 - if python3 { - PYTHON3 - } else if python2 { - PYTHON2 - } else { - // Python was not found on path, so exit - eprintln!("Unable to find python in your PATH. Please check it is installed."); - process::exit(1); - } +#[cfg(not(any(windows, unix)))] +fn x_command(_dir: &Path) -> Command { + compile_error!("Unsupported platform"); } #[cfg(unix)] @@ -72,15 +64,15 @@ fn main() { let candidate = dir.join("x.py"); if candidate.exists() { - let mut python = Command::new(python()); + let mut cmd = x_command(dir); - python.arg(&candidate).args(env::args().skip(1)).current_dir(dir); + cmd.args(env::args().skip(1)).current_dir(dir); - let result = exec_or_status(&mut python); + let result = exec_or_status(&mut cmd); match result { Err(error) => { - eprintln!("Failed to invoke `{}`: {}", candidate.display(), error); + eprintln!("Failed to invoke `{:?}`: {}", cmd, error); } Ok(status) => { process::exit(status.code().unwrap_or(1)); |
