diff --git a/src/bootstrap/bolt.rs b/src/bootstrap/bolt.rs index ea37cd47049bf..c48df5cddd818 100644 --- a/src/bootstrap/bolt.rs +++ b/src/bootstrap/bolt.rs @@ -19,7 +19,12 @@ pub fn instrument_with_bolt_inplace(path: &Path) { .expect("Could not instrument artifact using BOLT"); if !status.success() { - panic!("Could not instrument {} with BOLT, exit code {:?}", path.display(), status.code()); + eprintln!( + "Could not instrument {} with BOLT, exit code {:?}", + path.display(), + status.code() + ); + crate::detail_exit(1); } std::fs::copy(&instrumented_path, path).expect("Cannot copy instrumented artifact"); @@ -63,9 +68,9 @@ pub fn optimize_library_with_bolt_inplace(path: &Path, profile_path: &Path) { .expect("Could not optimize artifact using BOLT"); if !status.success() { - panic!("Could not optimize {} with BOLT, exit code {:?}", path.display(), status.code()); + eprintln!("Could not optimize {} with BOLT, exit code {:?}", path.display(), status.code()); + crate::detail_exit(1); } - std::fs::copy(&optimized_path, path).expect("Cannot copy optimized artifact"); std::fs::remove_file(optimized_path).expect("Cannot delete optimized artifact"); } diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index b4fc1d4f28da7..d8e6796775b75 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -152,10 +152,14 @@ impl TaskPath { if let Some(str) = os_str.to_str() { if let Some((found_kind, found_prefix)) = str.split_once("::") { if found_kind.is_empty() { - panic!("empty kind in task path {}", path.display()); + eprintln!("empty kind in task path {}", path.display()); + crate::detail_exit(1); } kind = Kind::parse(found_kind); - assert!(kind.is_some()); + if !kind.is_some() { + eprintln!("empty kind in task path {}", path.display()); + crate::detail_exit(1); + } path = Path::new(found_prefix).join(components.as_path()); } } @@ -321,11 +325,10 @@ impl StepDescription { // sanity checks on rules for (desc, should_run) in v.iter().zip(&should_runs) { - assert!( - !should_run.paths.is_empty(), - "{:?} should have at least one pathset", - desc.name - ); + if should_run.paths.is_empty() { + eprintln!("{:?} should have at least one pathset", desc.name); + crate::detail_exit(1); + } } if paths.is_empty() || builder.config.include_default_paths { @@ -466,11 +469,12 @@ impl<'a> ShouldRun<'a> { // exceptional case for `Kind::Setup` because its `library` // and `compiler` options would otherwise naively match with // `compiler` and `library` folders respectively. - assert!( - self.kind == Kind::Setup || !self.builder.src.join(alias).exists(), - "use `builder.path()` for real paths: {}", - alias - ); + match self.kind == Kind::Setup || !self.builder.src.join(alias).exists() { + true => {} + false => { + eprintln!("use `builder.path()` for real paths: {:?}", alias) + } + }; self.paths.insert(PathSet::Set( std::iter::once(TaskPath { path: alias.into(), kind: Some(self.kind) }).collect(), )); @@ -1197,7 +1201,10 @@ impl<'a> Builder<'a> { out_dir.join(target.triple).join("doc") } } - _ => panic!("doc mode {:?} not expected", mode), + _ => { + eprintln!("doc mode {:?} not expected", mode); + crate::detail_exit(1); + } }; let rustdoc = self.rustdoc(compiler); self.clear_if_dirty(&my_out, &rustdoc); @@ -1945,7 +1952,8 @@ impl<'a> Builder<'a> { for el in stack.iter().rev() { out += &format!("\t{:?}\n", el); } - panic!("{}", out); + eprintln!("{}", out); + crate::detail_exit(1); } if let Some(out) = self.cache.get(&step) { self.verbose_than(1, &format!("{}c {:?}", " ".repeat(stack.len()), step)); diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs index eae81b9fc69c8..8ac2fab4570ed 100644 --- a/src/bootstrap/channel.rs +++ b/src/bootstrap/channel.rs @@ -139,7 +139,10 @@ pub fn read_commit_info_file(root: &Path) -> Option { sha: sha.to_owned(), short_sha: short_sha.to_owned(), }, - _ => panic!("the `git-comit-info` file is malformed"), + _ => { + eprintln!("the `git-comit-info` file is malformed"); + crate::detail_exit(1); + } }; Some(info) } else { diff --git a/src/bootstrap/clean.rs b/src/bootstrap/clean.rs index 468efc1114c43..5aec4934eb612 100644 --- a/src/bootstrap/clean.rs +++ b/src/bootstrap/clean.rs @@ -118,7 +118,8 @@ fn rm_rf(path: &Path) { if e.kind() == ErrorKind::NotFound { return; } - panic!("failed to get metadata for file {}: {}", path.display(), e); + eprintln!("failed to get metadata for file {}: {}", path.display(), e); + crate::detail_exit(1); } Ok(metadata) => { if metadata.file_type().is_file() || metadata.file_type().is_symlink() { @@ -180,11 +181,13 @@ where if m.file_type().is_symlink() && path.is_dir() && fs::remove_dir(path).is_ok() { return; } - panic!("failed to {} {}: {}", desc, path.display(), e); + eprintln!("failed to {} {}: {}", desc, path.display(), e); + crate::detail_exit(1); }); } Err(e) => { - panic!("failed to {} {}: {}", desc, path.display(), e); + eprintln!("failed to {} {}: {}", desc, path.display(), e); + crate::detail_exit(1); } } } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 07c0d2233caeb..5565bf3056e61 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -236,7 +236,8 @@ fn copy_self_contained_objects( // and link with them manually in the self-contained mode. if target.contains("musl") { let srcdir = builder.musl_libdir(target).unwrap_or_else(|| { - panic!("Target {:?} does not have a \"musl-libdir\" key", target.triple) + eprintln!("Target {:?} does not have a \"musl-libdir\" key", target.triple); + crate::detail_exit(1); }); for &obj in &["libc.a", "crt1.o", "Scrt1.o", "rcrt1.o", "crti.o", "crtn.o"] { copy_and_stamp( @@ -264,7 +265,8 @@ fn copy_self_contained_objects( let srcdir = builder .wasi_root(target) .unwrap_or_else(|| { - panic!("Target {:?} does not have a \"wasi-root\" key", target.triple) + eprintln!("Target {:?} does not have a \"wasi-root\" key", target.triple); + crate::detail_exit(1); }) .join("lib/wasm32-wasi"); for &obj in &["libc.a", "crt1-command.o", "crt1-reactor.o"] { @@ -488,7 +490,10 @@ fn apple_darwin_update_library_name(library_path: &Path, new_name: &str) { .arg(library_path) .status() .expect("failed to execute `install_name_tool`"); - assert!(status.success()); + if !status.success() { + eprintln!("failed to execute `install_name_tool`"); + crate::detail_exit(1); + }; } fn apple_darwin_sign_file(file_path: &Path) { @@ -499,7 +504,10 @@ fn apple_darwin_sign_file(file_path: &Path) { .arg(file_path) .status() .expect("failed to execute `codesign`"); - assert!(status.success()); + if !status.success() { + eprintln!("failed to execute `codesign`"); + crate::detail_exit(1); + } } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -662,7 +670,8 @@ impl Step for Rustc { if builder.config.rust_profile_use.is_some() && builder.config.rust_profile_generate.is_some() { - panic!("Cannot use and generate PGO profiles at the same time"); + eprintln!("Cannot use and generate PGO profiles at the same time"); + crate::detail_exit(1); } // With LLD, we can use ICF (identical code folding) to reduce the executable size @@ -1020,14 +1029,18 @@ impl Step for CodegenBackend { }); let codegen_backend = match files.next() { Some(f) => f, - None => panic!("no dylibs built for codegen backend?"), + None => { + eprintln!("no dylibs built for codegen backend?"); + crate::detail_exit(1); + } }; if let Some(f) = files.next() { - panic!( + eprintln!( "codegen backend built two dylibs:\n{}\n{}", codegen_backend.display(), f.display() ); + crate::detail_exit(1); } let stamp = codegen_backend_stamp(builder, compiler, target, backend); let codegen_backend = codegen_backend.to_str().unwrap(); @@ -1567,7 +1580,10 @@ pub fn run_cargo( }); let path_to_add = match max { Some(triple) => triple.0.to_str().unwrap(), - None => panic!("no output generated for {:?} {:?}", prefix, extension), + None => { + eprintln!("no output generated for {:?} {:?}", prefix, extension); + crate::detail_exit(1); + } }; if is_dylib(path_to_add) { let candidate = format!("{}.lib", path_to_add); @@ -1625,7 +1641,10 @@ pub fn stream_cargo( builder.verbose(&format!("running: {:?}", cargo)); let mut child = match cargo.spawn() { Ok(child) => child, - Err(e) => panic!("failed to execute command: {:?}\nerror: {}", cargo, e), + Err(e) => { + eprintln!("failed to execute command: {:?}\nerror: {}", cargo, e); + crate::detail_exit(1); + } }; // Spawn Cargo slurping up its JSON output. We'll start building up the diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index e5fad53896971..ccc03813b9985 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -28,11 +28,10 @@ use serde::{Deserialize, Deserializer}; macro_rules! check_ci_llvm { ($name:expr) => { - assert!( - $name.is_none(), - "setting {} is incompatible with download-ci-llvm.", - stringify!($name) - ); + if !$name.is_none() { + eprintln!("setting {} is incompatible with download-ci-llvm.", stringify!($name)); + $crate::detail_exit(1); + } }; } @@ -504,7 +503,10 @@ impl Merge for TomlConfig { do_merge(&mut self.llvm, llvm); do_merge(&mut self.rust, rust); do_merge(&mut self.dist, dist); - assert!(target.is_none(), "merging target-specific config is not currently supported"); + if !target.is_none() { + eprintln!("merging target-specific config is not currently supported"); + crate::detail_exit(1); + } } } @@ -1189,7 +1191,13 @@ impl Config { let asserts = llvm_assertions.unwrap_or(false); config.llvm_from_ci = match llvm.download_ci_llvm { Some(StringOrBool::String(s)) => { - assert!(s == "if-available", "unknown option `{}` for download-ci-llvm", s); + match s == "if-available" { + false => { + eprintln!("unknown option `{}` for download-ci-llvm", s); + crate::detail_exit(1); + } + true => {} + }; crate::native::is_ci_llvm_available(&config, asserts) } Some(StringOrBool::Bool(b)) => b, @@ -1458,7 +1466,7 @@ impl Config { if let Err(version) = version { eprintln!("reading {}/src/version failed: {:?}", src, version); } - panic!(); + crate::detail_exit(1); } } }; @@ -1498,7 +1506,9 @@ impl Config { /// The absolute path to the downloaded LLVM artifacts. pub(crate) fn ci_llvm_root(&self) -> PathBuf { - assert!(self.llvm_from_ci); + if !self.llvm_from_ci { + crate::detail_exit(1); + } self.out.join(&*self.build.triple).join("ci-llvm") } @@ -1628,7 +1638,8 @@ impl Config { Some(StringOrBool::Bool(true)) => false, Some(StringOrBool::String(s)) if s == "if-unchanged" => true, Some(StringOrBool::String(other)) => { - panic!("unrecognized option for download-rustc: {}", other) + eprintln!("unrecognized option for download-rustc: {}", other); + crate::detail_exit(1); } }; diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index 02e35d2436e2f..3b8a1f4000922 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -158,7 +158,8 @@ fn find_files(files: &[&str], path: &[PathBuf]) -> Vec { if let Some(file_path) = file_path { found.push(file_path); } else { - panic!("Could not find '{}' in {:?}", file, path); + eprintln!("Could not find '{}' in {:?}", file, path); + crate::detail_exit(1); } } @@ -597,7 +598,8 @@ fn verify_uefi_rlib_format(builder: &Builder<'_>, target: TargetSelection, stamp if !is_coff { let member_name = String::from_utf8_lossy(member.name()); - panic!("member {} in {} is not COFF", member_name, path.display()); + eprintln!("member {} in {} is not COFF", member_name, path.display()); + crate::detail_exit(1); } } } diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 7f8aa2573ddb3..368ebf7ddd14f 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -566,10 +566,11 @@ fn doc_std( format.as_str() )); if builder.no_std(target) == Some(true) { - panic!( + eprintln!( "building std documentation for no_std target {target} is not supported\n\ Set `docs = false` in the config to disable documentation." ); + crate::detail_exit(1); } let compiler = builder.compiler(stage, builder.config.build); diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index bd67978a7662e..9d12c92018749 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -37,7 +37,10 @@ impl Config { if self.dry_run() { return; } - fs::remove_file(f).unwrap_or_else(|_| panic!("failed to remove {:?}", f)); + fs::remove_file(f).unwrap_or_else(|_| { + eprintln!("failed to remove {:?}", f); + crate::detail_exit(1); + }); } /// Create a temporary directory in `out` and return its path. @@ -200,8 +203,14 @@ impl Config { Some("http") | Some("https") => { self.download_http_with_retries(&tempfile, url, help_on_error) } - Some(other) => panic!("unsupported protocol {other} in {url}"), - None => panic!("no protocol in {url}"), + Some(other) => { + eprintln!("unsupported protocol {} in {}", other, url); + crate::detail_exit(1); + } + None => { + eprintln!("no protocol in {}", url); + crate::detail_exit(1); + } } t!(std::fs::rename(&tempfile, dest_path)); } @@ -282,7 +291,8 @@ impl Config { let dst_path = dst.join(short_path); self.verbose(&format!("extracting {} to {}", original_path.display(), dst.display())); if !t!(member.unpack_in(dst)) { - panic!("path traversal attack ??"); + eprintln!("path traversal attack ??"); + crate::detail_exit(1); } let src_path = dst.join(original_path); if src_path.is_dir() && dst_path.exists() { @@ -471,7 +481,8 @@ impl Config { self.download_file(&format!("{base_url}/{url}"), &tarball, ""); if let Some(sha256) = checksum { if !self.verify(&tarball, sha256) { - panic!("failed to verify {}", tarball.display()); + eprintln!("failed to verify {}", tarball.display()); + crate::detail_exit(1); } } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 52c3dc0bf7591..4480688b9dcdc 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -371,7 +371,8 @@ To learn more about a subcommand, run `./x.py -h`", if let Some(s) = paths { println!("{}", s); } else { - panic!("No paths available for subcommand `{}`", subcommand.as_str()); + eprintln!("No paths available for subcommand `{}`", subcommand.as_str()); + crate::detail_exit(1); } } else { println!( diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index bfc57a85cdb42..152e67750b208 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -200,7 +200,10 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { eprintln!("./x.py fmt is not supported on this channel"); crate::detail_exit(1); }); - assert!(rustfmt_path.exists(), "{}", rustfmt_path.display()); + if !rustfmt_path.exists() { + eprintln!("{}", rustfmt_path.display()); + crate::detail_exit(1); + } let src = build.src.clone(); let (tx, rx): (SyncSender, _) = std::sync::mpsc::sync_channel(128); let walker = match paths.get(0) { diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 1815a0973072b..b3fd862a4ee60 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -107,7 +107,10 @@ fn prepare_dir(mut path: PathBuf) -> String { // paths. std::fs::canonicalize is not used as that requires the path to actually be present. if path.is_relative() { path = std::env::current_dir().expect("failed to get the current directory").join(path); - assert!(path.is_absolute(), "could not make the path relative"); + if !path.is_absolute() { + eprintln!("could not make the path relative"); + crate::detail_exit(1); + } } sanitize_sh(&path) diff --git a/src/bootstrap/job.rs b/src/bootstrap/job.rs index 5c0322e18a4ab..187a4f303e6ff 100644 --- a/src/bootstrap/job.rs +++ b/src/bootstrap/job.rs @@ -54,6 +54,9 @@ pub unsafe fn setup(build: &mut Build) { // Create a new job object for us to use let job = CreateJobObjectW(ptr::null_mut(), ptr::null()); + if job.is_null() { + eprintln!("{}", io::Error::last_os_error()); + } assert!(!job.is_null(), "{}", io::Error::last_os_error()); // Indicate that when all handles to the job object are gone that all diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 267aa3278d8ff..82cae3a00052d 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -489,10 +489,11 @@ impl Build { .to_path_buf(); if !bootstrap_out.join(exe("rustc", config.build)).exists() && !cfg!(test) { // this restriction can be lifted whenever https://github.com/rust-lang/rfcs/pull/3028 is implemented - panic!( + eprintln!( "`rustc` not found in {}, run `cargo build --bins` before `cargo run`", bootstrap_out.display() - ) + ); + crate::detail_exit(1); } if rust_info.is_from_tarball() && config.description.is_none() { @@ -590,12 +591,13 @@ impl Build { let host = build.out.join("host"); if let Err(e) = symlink_dir(&build.config, &build_triple, &host) { if e.kind() != ErrorKind::AlreadyExists { - panic!( + eprintln!( "symlink_dir({} => {}) failed with {}", host.display(), build_triple.display(), e ); + crate::detail_exit(1); } } @@ -635,10 +637,10 @@ impl Build { .arg(relative_path) .current_dir(&self.config.src), ); - let actual_hash = recorded - .split_whitespace() - .nth(2) - .unwrap_or_else(|| panic!("unexpected output `{}`", recorded)); + let actual_hash = recorded.split_whitespace().nth(2).unwrap_or_else(|| { + eprintln!("unexpected output `{}`", recorded); + crate::detail_exit(1); + }); // update_submodule if actual_hash == checked_out_hash.trim_end() { @@ -1390,8 +1392,8 @@ impl Build { return stripped.to_owned(); } } - - panic!("failed to find version in {}'s Cargo.toml", package) + eprintln!("failed to find version in {}'s Cargo.toml", package); + crate::detail_exit(1); } /// Returns `true` if unstable features should be enabled for the compiler @@ -1411,10 +1413,10 @@ impl Build { let mut list = vec![INTERNER.intern_str(root)]; let mut visited = HashSet::new(); while let Some(krate) = list.pop() { - let krate = self - .crates - .get(&krate) - .unwrap_or_else(|| panic!("metadata missing for {krate}: {:?}", self.crates)); + let krate = self.crates.get(&krate).unwrap_or_else(|| { + eprintln!("metadata missing for {krate}: {:?}", self.crates); + crate::detail_exit(1); + }); ret.push(krate); for dep in &krate.deps { if !self.crates.contains_key(dep) { @@ -1504,7 +1506,8 @@ impl Build { // just fall back to a slow `copy` operation. } else { if let Err(e) = fs::copy(&src, dst) { - panic!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e) + eprintln!("failed to copy `{}` to `{}`: {}", src.display(), dst.display(), e); + crate::detail_exit(1); } t!(fs::set_permissions(dst, metadata.permissions())); let atime = FileTime::from_last_access_time(&metadata); @@ -1576,7 +1579,8 @@ impl Build { self.verbose_than(1, &format!("Install {:?} to {:?}", src, dst)); t!(fs::create_dir_all(dstdir)); if !src.exists() { - panic!("Error: File \"{}\" not found!", src.display()); + eprintln!("Error: File \"{}\" not found!", src.display()); + crate::detail_exit(1); } self.copy_internal(src, &dst, true); chmod(&dst, perms); @@ -1607,7 +1611,10 @@ impl Build { let iter = match fs::read_dir(dir) { Ok(v) => v, Err(_) if self.config.dry_run() => return vec![].into_iter(), - Err(err) => panic!("could not read dir {:?}: {:?}", dir, err), + Err(err) => { + eprintln!("could not read dir {:?}: {:?}", dir, err); + crate::detail_exit(1); + } }; iter.map(|e| t!(e)).collect::>().into_iter() } @@ -1673,10 +1680,11 @@ fn chmod(_path: &Path, _perms: u32) {} /// If code is not 0 (successful exit status), exit status is 101 (rust's default error code.) /// If the test is running and code is an error code, it will cause a panic. -fn detail_exit(code: i32) -> ! { +pub fn detail_exit(code: i32) -> ! { // if in test and code is an error code, panic with status code provided if cfg!(test) { - panic!("status code: {}", code); + eprintln!("status code: {}", code); + std::process::exit(code); } else { // otherwise,exit with provided status code std::process::exit(code); diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs index e193e70a0c417..e9c887b35da14 100644 --- a/src/bootstrap/metadata.rs +++ b/src/bootstrap/metadata.rs @@ -53,7 +53,10 @@ pub fn build(build: &mut Build) { let relative_path = krate.local_path(build); build.crates.insert(name, krate); let existing_path = build.crate_paths.insert(relative_path, name); - assert!(existing_path.is_none(), "multiple crates with the same path"); + if !existing_path.is_none() { + eprintln!("multiple crates with the same path"); + crate::detail_exit(1); + } } } } diff --git a/src/bootstrap/metrics.rs b/src/bootstrap/metrics.rs index c823dc7968465..9aab87c02e5e7 100644 --- a/src/bootstrap/metrics.rs +++ b/src/bootstrap/metrics.rs @@ -107,7 +107,8 @@ impl BuildMetrics { Ok(contents) => t!(serde_json::from_slice::(&contents)).invocations, Err(err) => { if err.kind() != std::io::ErrorKind::NotFound { - panic!("failed to open existing metrics file at {}: {err}", dest.display()); + eprintln!("failed to open existing metrics file at {}: {err}", dest.display()); + crate::detail_exit(1); } Vec::new() } diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 3acc2d4b5c4b1..a9264c6919d6a 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -163,7 +163,7 @@ pub(crate) fn detect_llvm_sha(config: &Config, is_git: bool) -> String { eprintln!("help: maybe your repository history is too shallow?"); eprintln!("help: consider disabling `download-ci-llvm`"); eprintln!("help: or fetch enough history to include one upstream commit"); - panic!(); + crate::detail_exit(1); } llvm_sha @@ -275,7 +275,8 @@ impl Step for Llvm { builder.update_submodule(&Path::new("src").join("llvm-project")); if builder.llvm_link_shared() && target.contains("windows") { - panic!("shared linking to LLVM is not currently supported on {}", target.triple); + eprintln!("shared linking to LLVM is not currently supported on {}", target.triple); + crate::detail_exit(1); } builder.info(&format!("Building LLVM for {}", target)); @@ -462,7 +463,8 @@ impl Step for Llvm { let build_bin = builder.llvm_out(builder.config.build).join("build").join("bin"); let clang_tblgen = build_bin.join("clang-tblgen").with_extension(EXE_EXTENSION); if !builder.config.dry_run() && !clang_tblgen.exists() { - panic!("unable to find {}", clang_tblgen.display()); + eprintln!("unable to find {}", clang_tblgen.display()); + crate::detail_exit(1); } cfg.define("CLANG_TABLEGEN", clang_tblgen); } @@ -565,7 +567,8 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) { return; } } - panic!("\n\nbad LLVM version: {}, need >=13.0\n\n", version) + eprintln!("\n\nbad LLVM version: {}, need >=13.0\n\n", version); + crate::detail_exit(1); } fn configure_cmake( @@ -1127,7 +1130,8 @@ impl HashStamp { Ok(h) => self.hash.as_deref().unwrap_or(b"") == h.as_slice(), Err(e) if e.kind() == io::ErrorKind::NotFound => false, Err(e) => { - panic!("failed to read stamp file `{}`: {}", self.path.display(), e); + eprintln!("failed to read stamp file `{}`: {}", self.path.display(), e); + crate::detail_exit(1); } } } diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index e0280854541a0..35f66f02a2499 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -69,10 +69,12 @@ impl Step for BuildManifest { // (https://github.com/rust-lang/promote-release). let mut cmd = builder.tool_cmd(Tool::BuildManifest); let sign = builder.config.dist_sign_folder.as_ref().unwrap_or_else(|| { - panic!("\n\nfailed to specify `dist.sign-folder` in `config.toml`\n\n") + eprintln!("\n\nfailed to specify `dist.sign-folder` in `config.toml`\n\n"); + crate::detail_exit(1); }); let addr = builder.config.dist_upload_addr.as_ref().unwrap_or_else(|| { - panic!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n") + eprintln!("\n\nfailed to specify `dist.upload-addr` in `config.toml`\n\n"); + crate::detail_exit(1); }); let today = output(Command::new("date").arg("+%Y-%m-%d")); @@ -209,7 +211,8 @@ impl Step for CollectLicenseMetadata { fn run(self, builder: &Builder<'_>) -> Self::Output { let Some(reuse) = &builder.config.reuse else { - panic!("REUSE is required to collect the license metadata"); + eprintln!("REUSE is required to collect the license metadata"); + crate::detail_exit(1); }; // Temporary location, it will be moved to src/etc once it's accurate. diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 8a40b0f64f4b6..42c783a850215 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -56,7 +56,8 @@ impl Finder { pub fn must_have>(&mut self, cmd: S) -> PathBuf { self.maybe_have(&cmd).unwrap_or_else(|| { - panic!("\n\ncouldn't find required command: {:?}\n\n", cmd.as_ref()); + eprintln!("\n\ncouldn't find required command: {:?}\n\n", cmd.as_ref()); + crate::detail_exit(1); }) } } @@ -68,7 +69,8 @@ pub fn check(build: &mut Build) { // being unable to identify the files properly. See // https://github.com/rust-lang/rust/issues/34959 for more details. if cfg!(windows) && path.to_string_lossy().contains('\"') { - panic!("PATH contains invalid character '\"'"); + eprintln!("PATH contains invalid character '\"'"); + crate::detail_exit(1); } let mut cmd_finder = Finder::new(); @@ -188,7 +190,8 @@ than building it. // Externally configured LLVM requires FileCheck to exist let filecheck = build.llvm_filecheck(build.build); if !filecheck.starts_with(&build.out) && !filecheck.exists() && build.config.codegen_tests { - panic!("FileCheck executable {:?} does not exist", filecheck); + eprintln!("FileCheck executable {:?} does not exist", filecheck); + crate::detail_exit(1); } } @@ -201,7 +204,8 @@ than building it. if target.contains("-none-") || target.contains("nvptx") { if build.no_std(*target) == Some(false) { - panic!("All the *-none-* and nvptx* targets are no-std targets") + eprintln!("All the *-none-* and nvptx* targets are no-std targets"); + crate::detail_exit(1); } } @@ -216,14 +220,18 @@ than building it. match build.musl_libdir(*target) { Some(libdir) => { if fs::metadata(libdir.join("libc.a")).is_err() { - panic!("couldn't find libc.a in musl libdir: {}", libdir.display()); + eprintln!("couldn't find libc.a in musl libdir: {}", libdir.display()); + crate::detail_exit(1); } } - None => panic!( - "when targeting MUSL either the rust.musl-root \ - option or the target.$TARGET.musl-root option must \ - be specified in config.toml" - ), + None => { + eprintln!( + "when targeting MUSL either the rust.musl-root \ + option or the target.$TARGET.musl-root option must \ + be specified in config.toml" + ); + crate::detail_exit(1); + } } } @@ -241,7 +249,7 @@ than building it. // Studio, so detect that here and error. let out = output(Command::new("cmake").arg("--help")); if !out.contains("Visual Studio") { - panic!( + eprintln!( " cmake does not support Visual Studio generators. @@ -255,6 +263,7 @@ package instead of cmake: $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake " ); + crate::detail_exit(1); } } } diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index 004601cb68b10..c1d5117d2641e 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -354,7 +354,10 @@ pub fn interactive_path() -> io::Result { // install a git hook to automatically run tidy, if they want fn install_git_hook_maybe(config: &Config) -> io::Result<()> { let git = t!(config.git().args(&["rev-parse", "--git-common-dir"]).output().map(|output| { - assert!(output.status.success(), "failed to run `git`"); + if !output.status.success() { + eprintln!("Failed to run `git`"); + crate::detail_exit(1); + } PathBuf::from(t!(String::from_utf8(output.stdout)).trim()) })); let dst = git.join("hooks").join("pre-push"); diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index fc850a22b2f6f..6e39df81de46c 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -315,7 +315,10 @@ impl<'a> Tarball<'a> { build_cli(&self, &mut cmd); cmd.arg("--work-dir").arg(&self.temp_dir); if let Some(formats) = &self.builder.config.dist_compression_formats { - assert!(!formats.is_empty(), "dist.compression-formats can't be empty"); + if formats.is_empty() { + eprintln!("dist.compression-formats can't be empty"); + crate::detail_exit(1); + } cmd.arg("--compression-formats").arg(formats.join(",")); } self.builder.run(&mut cmd); @@ -327,7 +330,8 @@ impl<'a> Tarball<'a> { for entry in walkdir::WalkDir::new(&decompressed_output) { let entry = t!(entry); if entry.path_is_symlink() { - panic!("generated a symlink in a tarball: {}", entry.path().display()); + eprintln!("generated a symlink in a tarball: {}", entry.path().display()); + crate::detail_exit(1); } } } diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 6078e39ac9d3b..229366e36ea9a 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -41,7 +41,10 @@ impl From for TestKind { match kind { Kind::Test => TestKind::Test, Kind::Bench => TestKind::Bench, - _ => panic!("unexpected kind in crate: {:?}", kind), + _ => { + eprintln!("unexpected kind in crate: {:?}", kind); + crate::detail_exit(1); + } } } } @@ -151,10 +154,11 @@ impl Step for Linkcheck { // documentation built for each will contain broken links to // docs built for the other platform (e.g. rustc linking to cargo) if (hosts != targets) && !hosts.is_empty() && !targets.is_empty() { - panic!( + eprintln!( "Linkcheck currently does not support builds with different hosts and targets. You can skip linkcheck with --exclude src/tools/linkchecker" ); + crate::detail_exit(1); } builder.info(&format!("Linkcheck ({})", host)); @@ -229,7 +233,8 @@ impl Step for HtmlCheck { eprintln!( "Note that `tidy` is not the in-tree `src/tools/tidy` but needs to be installed" ); - panic!("Cannot run html-check tests"); + eprintln!("Cannot run html-check tests"); + crate::detail_exit(1); } // Ensure that a few different kinds of documentation are available. builder.default_doc(&[]); @@ -552,7 +557,10 @@ impl Miri { builder.verbose(&format!("running: {:?}", cargo)); let out = cargo.output().expect("We already ran `cargo miri setup` before and that worked"); - assert!(out.status.success(), "`cargo miri setup` returned with non-0 exit code"); + if !out.status.success() { + eprintln!("`cargo miri setup` returned with non-0 exit code"); + crate::detail_exit(1); + } // Output is "\n". let stdout = String::from_utf8(out.stdout) .expect("`cargo miri setup` stdout is not valid UTF-8"); @@ -869,7 +877,8 @@ impl Step for RustdocJSStd { { if !p.ends_with(".js") { eprintln!("A non-js file was given: `{}`", path.display()); - panic!("Cannot run rustdoc-js-std tests"); + eprintln!("Cannot run rustdoc-js-std tests"); + crate::detail_exit(1); } command.arg("--test-file").arg(path); } @@ -1018,7 +1027,8 @@ impl Step for RustdocGUI { "If you want to install the `{0}` dependency, run `npm install {0}`", "browser-ui-test", ); - panic!("Cannot run rustdoc-gui tests"); + eprintln!("Cannot run rustdoc-gui tests"); + crate::detail_exit(1); } } @@ -1071,7 +1081,8 @@ impl Step for RustdocGUI { if let Some(p) = util::is_valid_test_suite_arg(path, "tests/rustdoc-gui", builder) { if !p.ends_with(".goml") { eprintln!("A non-goml file was given: `{}`", path.display()); - panic!("Cannot run rustdoc-gui tests"); + eprintln!("Cannot run rustdoc-gui tests"); + crate::detail_exit(1); } if let Some(name) = path.file_name().and_then(|f| f.to_str()) { command.arg("--file").arg(name); @@ -1541,7 +1552,10 @@ note: if you're sure you want to do this, please open an issue as to why. In the String::from_utf8_lossy(&output.stdout) .lines() .next() - .unwrap_or_else(|| panic!("{:?} failed {:?}", cmd, output)) + .unwrap_or_else(|| { + eprintln!("{:?} failed {:?}", cmd, output); + crate::detail_exit(1); + }) .to_string() }) }; @@ -1637,7 +1651,9 @@ note: if you're sure you want to do this, please open an issue as to why. In the let llvm_bin_path = llvm_config .parent() .expect("Expected llvm-config to be contained in directory"); - assert!(llvm_bin_path.is_dir()); + if !llvm_bin_path.is_dir() { + crate::detail_exit(1); + } cmd.arg("--llvm-bin-dir").arg(llvm_bin_path); // If LLD is available, add it to the PATH @@ -2124,7 +2140,10 @@ impl Step for Crate { Mode::Rustc => { compile::rustc_cargo(builder, &mut cargo, target); } - _ => panic!("can only test libraries"), + _ => { + eprintln!("can only test libraries"); + crate::detail_exit(1); + } }; // Build up the base `cargo test` command. diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index ca5f500f93bc4..062ca1919470f 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -58,7 +58,10 @@ impl Step for ToolBuild { } Mode::ToolStd => builder.ensure(compile::Std::new(compiler, target)), Mode::ToolBootstrap => {} // uses downloaded stage0 compiler libs - _ => panic!("unexpected Mode for tool build"), + _ => { + eprintln!("unexpected Mode for tool build"); + crate::detail_exit(1); + } } let mut cargo = prepare_tool_cargo( @@ -203,7 +206,8 @@ impl Step for ToolBuild { that will update the dependency graph to ensure that \ these crates all share the same feature set" ); - panic!("tools should not compile multiple copies of the same crate"); + eprintln!("tools should not compile multiple copies of the same crate"); + crate::detail_exit(1); } builder.save_toolstate( @@ -515,7 +519,8 @@ impl Step for Rustdoc { let target_compiler = self.compiler; if target_compiler.stage == 0 { if !target_compiler.is_snapshot(builder) { - panic!("rustdoc in stage 0 must be snapshot rustdoc"); + eprintln!("rustdoc in stage 0 must be snapshot rustdoc"); + crate::detail_exit(1); } return builder.initial_rustc.with_file_name(exe("rustdoc", target_compiler.host)); } diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs index 1969e0b6f8722..21713c6daf815 100644 --- a/src/bootstrap/toolstate.rs +++ b/src/bootstrap/toolstate.rs @@ -320,7 +320,8 @@ fn checkout_toolstate_repo() { Err(_) => false, }; if !success { - panic!("git clone unsuccessful (status: {:?})", status); + eprintln!("git clone unsuccessful (status: {:?})", status); + crate::detail_exit(1); } } @@ -333,7 +334,8 @@ fn prepare_toolstate_config(token: &str) { Err(_) => false, }; if !success { - panic!("git config key={} value={} failed (status: {:?})", key, value, status); + eprintln!("git config key={} value={} failed (status: {:?})", key, value, status); + crate::detail_exit(1); } } @@ -422,18 +424,23 @@ fn commit_toolstate_change(current_toolstate: &ToolstateData) { .arg("origin") .arg("master") .status()); - assert!(status.success()); + if !status.success() { + crate::detail_exit(1); + } let status = t!(Command::new("git") .current_dir(TOOLSTATE_DIR) .arg("reset") .arg("--hard") .arg("origin/master") .status()); - assert!(status.success()); + if !status.success() { + crate::detail_exit(1); + } } if !success { - panic!("Failed to update toolstate repository with new data"); + eprintln!("Failed to update toolstate repository with new data"); + crate::detail_exit(1); } } diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index 93e53d383cd39..f906d819dbb3c 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -28,14 +28,20 @@ macro_rules! t { ($e:expr) => { match $e { Ok(e) => e, - Err(e) => panic!("{} failed with {}", stringify!($e), e), + Err(e) => { + eprintln!("{} failed with {}", stringify!($e), e); + $crate::detail_exit(1); + } } }; // it can show extra info in the second parameter ($e:expr, $extra:expr) => { match $e { Ok(e) => e, - Err(e) => panic!("{} failed with {} ({:?})", stringify!($e), e, $extra), + Err(e) => { + eprintln!("{} failed with {} ({:?})", stringify!($e), e, $extra); + $crate::detail_exit(1); + } } }; } @@ -262,11 +268,12 @@ pub fn forcing_clang_based_tests() -> bool { "0" | "no" | "off" => false, other => { // Let's make sure typos don't go unnoticed - panic!( + eprintln!( "Unrecognized option '{}' set in \ RUSTBUILD_FORCE_CLANG_BASED_TESTS", other - ) + ); + crate::detail_exit(1); } } } else { @@ -302,10 +309,11 @@ pub fn is_valid_test_suite_arg<'a, P: AsRef>( let abs_path = builder.src.join(path); let exists = abs_path.is_dir() || abs_path.is_file(); if !exists { - panic!( + eprintln!( "Invalid test suite filter \"{}\": file or directory does not exist", abs_path.display() ); + crate::detail_exit(1); } // Since test suite paths are themselves directories, if we don't // specify a directory or file, we'll get an empty string here @@ -403,11 +411,12 @@ pub fn output(cmd: &mut Command) -> String { Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", cmd, e)), }; if !output.status.success() { - panic!( + eprintln!( "command did not execute successfully: {:?}\n\ expected success, got: {}", cmd, output.status ); + crate::detail_exit(1); } String::from_utf8(output.stdout).unwrap() } @@ -445,7 +454,10 @@ pub fn up_to_date(src: &Path, dst: &Path) -> bool { let threshold = mtime(dst); let meta = match fs::metadata(src) { Ok(meta) => meta, - Err(e) => panic!("source {:?} failed to get metadata: {}", src, e), + Err(e) => { + eprintln!("source {:?} failed to get metadata: {}", src, e); + crate::detail_exit(1); + } }; if meta.is_dir() { dir_up_to_date(src, threshold) @@ -475,7 +487,8 @@ fn fail(s: &str) -> ! { /// FIXME: this shouldn't exist. pub(crate) fn absolute(path: &Path) -> PathBuf { if path.as_os_str().is_empty() { - panic!("can't make empty path absolute"); + eprintln!("can't make empty path absolute"); + crate::detail_exit(1); } #[cfg(unix)] { @@ -592,11 +605,10 @@ pub fn get_clang_cl_resource_dir(clang_cl_path: &str) -> PathBuf { let clang_rt_builtins = output(&mut builtins_locator); let clang_rt_builtins = Path::new(clang_rt_builtins.trim()); - assert!( - clang_rt_builtins.exists(), - "`clang-cl` must correctly locate the library runtime directory" - ); - + if !clang_rt_builtins.exists() { + eprintln!("`clang-cl` must correctly locate the library runtime directory"); + crate::detail_exit(1); + } // - the profiler runtime will be located in the same directory as the builtins lib, like // `$LLVM_DISTRO_ROOT/lib/clang/$LLVM_VERSION/lib/windows`. let clang_rt_dir = clang_rt_builtins.parent().expect("The clang lib folder should exist");