Skip to content

Make normalization in a test case resilient to dist compilation#158318

Open
steffahn wants to merge 1 commit into
rust-lang:mainfrom
steffahn:fix-ice-confusion
Open

Make normalization in a test case resilient to dist compilation#158318
steffahn wants to merge 1 commit into
rust-lang:mainfrom
steffahn:fix-ice-confusion

Conversation

@steffahn

@steffahn steffahn commented Jun 23, 2026

Copy link
Copy Markdown
Member

This fixes #158219 by adapting the tests/rustdoc-ui/ice-bug-report-url test case such that it will no longer fail with the remapping prefixes from #150110

This was previously sometimes the first test failure if someone tried x.py test on a compiler checkout configured with dist setup, prominently featuring the new (mismatching) test stdout containing the scary ICE error message.


The new normalization regex is taken from many existing test cases,
see: ↝ this code search ⮺

which includes files such as tests/ui/treat-err-as-bug/span_delayed_bug.rs or tests/ui/treat-err-as-bug/err.rs.

The new normalization regex is taken from many existing test cases,
see: https://github.com/search?q=repo%3Arust-lang%2Frust+%2Fthread+%27rustc%27%5C.%5C*panicked%2F&type=code

which includes files such as `tests/ui/treat-err-as-bug/span_delayed_bug.rs`
or `tests/ui/treat-err-as-bug/err.rs`
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Jun 23, 2026
@rustbot

rustbot commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

r? @camelid

rustbot has assigned @camelid.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: rustdoc
  • rustdoc expanded to 8 candidates
  • Random selection from GuillaumeGomez, camelid, notriddle

@steffahn

steffahn commented Jun 23, 2026

Copy link
Copy Markdown
Member Author

To clarify: This doesn't make it so that x.py test will actually succeed in the reported context; it just makes it so the first error that appears isn't related to UI tests around ICE outputs anymore.

In before this, the test run on my machine - in a setup reproducing #158219 - did end in output like

$ ./x.py test (expand/collapse)
[…lots of output omitted…]
[…lots of output omitted…]

Testing stage2 with compiletest suite=rustdoc-ui mode=ui (x86_64-unknown-linux-gnu)

running 398 tests
iii.............................................................i.......................  88/398
.i.......................................................
[ui] tests/rustdoc-ui/ice-bug-report-url.rs ... F
.............................. 176/398
........................................................................................ 264/398
........................................................................................ 352/398
..............................................

failures:

---- [ui] tests/rustdoc-ui/ice-bug-report-url.rs stdout ----
Saved the actual stderr to `/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/test/rustdoc-ui/ice-bug-report-url/ice-bug-report-url.stderr`
diff of stderr:

5          |          ^ expected one of `->`, `where`, or `{`
6
7
-
+       thread 'rustc' ($TID) panicked at /rustc-dev/4429659e4745016bd3f26a4a421843edc7fbc422/compiler/rustc_errors/src/lib.rs:1528:17:
9       aborting due to `-Z treat-err-as-bug=1`
10      stack backtrace:
11

Note: some mismatched output was normalized before being compared
-       thread 'rustc' (687526) panicked at /rustc-dev/4429659e4745016bd3f26a4a421843edc7fbc422/compiler/rustc_errors/src/lib.rs:1528:17:
+       thread 'rustc' ($TID) panicked at /rustc-dev/4429659e4745016bd3f26a4a421843edc7fbc422/compiler/rustc_errors/src/lib.rs:1528:17:


The actual stderr differed from the expected stderr
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args ice-bug-report-url.rs`

error: 1 errors occurred comparing output.
status: exit status: 101
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" "/home/frank/repos/rust_main_dist/tests/rustdoc-ui/ice-bug-report-url.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/home/frank/.cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/home/frank/repos/rust_main_dist/vendor" "--sysroot" "/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-o" "/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/test/rustdoc-ui/ice-bug-report-url" "-A" "internal_features" "-A" "incomplete_features" "-A" "unused_parens" "-A" "unused_braces" "-Cdebuginfo=0" "-Ztreat-err-as-bug"
stdout: none
--- stderr -------------------------------
error: internal compiler error: expected one of `->`, `where`, or `{`, found `<eof>`
  --> /home/frank/repos/rust_main_dist/tests/rustdoc-ui/ice-bug-report-url.rs:12:10
   |
LL | fn wrong()
   |          ^ expected one of `->`, `where`, or `{`


thread 'rustc' (687526) panicked at /rustc-dev/4429659e4745016bd3f26a4a421843edc7fbc422/compiler/rustc_errors/src/lib.rs:1528:17:
aborting due to `-Z treat-err-as-bug=1`
stack backtrace:
   0: __rustc::rust_begin_unwind
   1: core::panicking::panic_fmt
   2: <rustc_errors::DiagCtxtInner>::emit_diagnostic::{closure#3}
   3: rustc_interface::callbacks::track_diagnostic::<core::option::Option<rustc_span::ErrorGuaranteed>>
   4: <rustc_errors::DiagCtxtInner>::emit_diagnostic
   5: <rustc_errors::DiagCtxtHandle>::emit_diagnostic
   6: <rustc_span::ErrorGuaranteed as rustc_errors::diagnostic::EmissionGuarantee>::emit_producing_guarantee
   7: rustc_interface::passes::parse
   8: rustc_interface::interface::run_compiler::<(), rustdoc::main_args::{closure#2}>::{closure#1}
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

error: the compiler unexpectedly panicked. This is a bug

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md

note: please make sure that you have updated to the latest nightly

note: rustc 1.98.0-nightly (4429659e4 2026-06-22) running on x86_64-unknown-linux-gnu

note: compiler flags: -Z threads=1 -Z simulate-remapped-rust-src-base=/rustc/FAKE_PREFIX -Z translate-remapped-path-to-local-path=no -Z ignore-directory-in-diagnostics-source-blocks=/home/frank/.cargo -Z ignore-directory-in-diagnostics-source-blocks=/home/frank/repos/rust_main_dist/vendor -C codegen-units=1 -Z ui-testing -Z deduplicate-diagnostics=no -Z write-long-types-to-disk=no -C strip=debuginfo -C debuginfo=0 -Z treat-err-as-bug

query stack during panic:
end of query stack
------------------------------------------

---- [ui] tests/rustdoc-ui/ice-bug-report-url.rs stdout end ----

failures:
    [ui] tests/rustdoc-ui/ice-bug-report-url.rs

test result: FAILED. 392 passed; 1 failed; 5 ignored; 0 measured; 0 filtered out; finished in 13.17s

Some tests failed in compiletest suite=rustdoc-ui mode=ui host=x86_64-unknown-linux-gnu target=x86_64-unknown-linux-gnu
Build completed unsuccessfully in 0:32:14

and after this change it fails for me with

$ ./x.py test (expand/collapse)
[…lots of output omitted…]
[…lots of output omitted…]

Testing stage2 with compiletest suite=run-make mode=run-make (x86_64-unknown-linux-gnu)

running 483 tests
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii..................i...i..............iii........  88/483
.......i.....i.................
[run-make] tests/run-make/embed-source-dwarf ... F
............................i..i......................i. 176/483
.............i..ii.......i............iii.......i........iiii.........................i. 264/483
.............iiiiii.iiii...............iiii....iiiii.............
[run-make] tests/run-make/remap-path-prefix-std ... F
..............i....... 352/483
.............................iii..................ii......................i.......i....i 440/483
iiiiiiiiiiii..iiiii........................

failures:

---- [run-make] tests/run-make/embed-source-dwarf stdout ----

error: rmake recipe failed to complete
status: exit status: 101
command: cd "/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/test/run-make/embed-source-dwarf/rmake_out" && env -u RUSTFLAGS -u __RUSTC_DEBUG_ASSERTIONS_ENABLED -u __STD_DEBUG_ASSERTIONS_ENABLED AR="ar" BUILD_ROOT="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu" CC="cc" CC_DEFAULT_FLAGS="-ffunction-sections -fdata-sections -fPIC -m64" CXX="c++" CXX_DEFAULT_FLAGS="-ffunction-sections -fdata-sections -fPIC -m64" HOST_RUSTC_DYLIB_PATH="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage2/lib" LD_LIBRARY_PATH="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/bootstrap-tools/x86_64-unknown-linux-gnu/release/build/run_make_support/878a16a0b6f5304f/out:/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib" LD_LIB_PATH_ENVVAR="LD_LIBRARY_PATH" LLVM_BIN_DIR="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/llvm/bin" LLVM_COMPONENTS="aarch64 aarch64asmparser aarch64codegen aarch64desc aarch64disassembler aarch64info aarch64utils abi aggressiveinstcombine all all-targets amdgpu amdgpuasmparser amdgpucodegen amdgpudesc amdgpudisassembler amdgpuinfo amdgputargetmca amdgpuutils analysis arm armasmparser armcodegen armdesc armdisassembler arminfo armutils asmparser asmprinter avr avrasmparser avrcodegen avrdesc avrdisassembler avrinfo binaryformat bitreader bitstreamreader bitwriter bpf bpfasmparser bpfcodegen bpfdesc bpfdisassembler bpfinfo cas cfguard cgdata codegen codegentypes core coroutines coverage csky cskyasmparser cskycodegen cskydesc cskydisassembler cskyinfo debuginfobtf debuginfocodeview debuginfodwarf debuginfodwarflowlevel debuginfogsym debuginfologicalview debuginfomsf debuginfopdb demangle dlltooldriver dtlto dwarfcfichecker dwarflinker dwarflinkerclassic dwarflinkerparallel dwp engine executionengine extensions filecheck frontendatomic frontenddirective frontenddriver frontendhlsl frontendoffloading frontendopenacc frontendopenmp fuzzercli fuzzmutate globalisel hexagon hexagonasmparser hexagoncodegen hexagondesc hexagondisassembler hexagoninfo hipstdpar instcombine instrumentation interfacestub interpreter ipo irprinter irreader jitlink libdriver lineeditor linker loongarch loongarchasmparser loongarchcodegen loongarchdesc loongarchdisassembler loongarchinfo lto m68k m68kasmparser m68kcodegen m68kdesc m68kdisassembler m68kinfo mc mca mcdisassembler mcjit mcparser mips mipsasmparser mipscodegen mipsdesc mipsdisassembler mipsinfo mirparser msp430 msp430asmparser msp430codegen msp430desc msp430disassembler msp430info native nativecodegen nvptx nvptxcodegen nvptxdesc nvptxinfo objcarcopts objcopy object objectyaml option orcdebugging orcjit orcshared orctargetprocess passes plugins powerpc powerpcasmparser powerpccodegen powerpcdesc powerpcdisassembler powerpcinfo profiledata remarks riscv riscvasmparser riscvcodegen riscvdesc riscvdisassembler riscvinfo riscvtargetmca runtimedyld sandboxir scalaropts selectiondag sparc sparcasmparser sparccodegen sparcdesc sparcdisassembler sparcinfo support supportlsp symbolize systemz systemzasmparser systemzcodegen systemzdesc systemzdisassembler systemzinfo tablegen target targetparser telemetry textapi textapibinaryreader transformutils vectorize webassembly webassemblyasmparser webassemblycodegen webassemblydesc webassemblydisassembler webassemblyinfo webassemblyutils windowsdriver windowsmanifest x86 x86asmparser x86codegen x86desc x86disassembler x86info x86targetmca xray xtensa xtensaasmparser xtensacodegen xtensadesc xtensadisassembler xtensainfo" LLVM_FILECHECK="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/llvm/build/bin/FileCheck" NODE="/home/frank/.nvm/versions/node/v22.12.0/bin/node" PYTHON="/usr/bin/python3" RUSTC="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" RUSTDOC="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" SOURCE_ROOT="/home/frank/repos/rust_main_dist" TARGET="x86_64-unknown-linux-gnu" TARGET_EXE_DYLIB_PATH="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" __BOOTSTRAP_JOBS="24" __RMAKE_VERBOSE_SUBPROCESS_OUTPUT="1" __STD_REMAP_DEBUGINFO_ENABLED="1" "/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/test/run-make/embed-source-dwarf/rmake"
stdout: none
--- stderr -------------------------------
LD_LIBRARY_PATH="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/test/run-make/embed-source-dwarf/rmake_out:/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage2/lib:/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/bootstrap-tools/x86_64-unknown-linux-gnu/release/build/run_make_support/878a16a0b6f5304f/out:/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "-L" "/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/test/run-make/embed-source-dwarf/rmake_out" "main.rs" "-o" "embed-source-main" "-g" "-Zembed-source=yes" "-Cdwarf-version=5" "--target=x86_64-unknown-linux-gnu"
output status: `exit status: 0`
=== STDOUT ===



=== STDERR ===



[/home/frank/repos/rust_main_dist/tests/run-make/embed-source-dwarf/rmake.rs:65:5] &sources = {
    "main.rs": "// hello\nfn main() {}\n",
    "backtrace.rs": "//! Common code for printing backtraces.\n#![forbid(unsafe_op_in_unsafe_fn)]\n\nuse crate::backtrace_rs::{self, BacktraceFmt, BytesOrWideString, PrintFmt};\nuse crate::borrow::Cow;\nuse crate::io::prelude::*;\nuse crate::path::{self, Path, PathBuf};\nuse crate::sync::{Mutex, MutexGuard, PoisonError};\nuse crate::{env, fmt, io};\n\n/// Max number of frames to print.\nconst MAX_NB_FRAMES: usize = 100;\n\npub(crate) const FULL_BACKTRACE_DEFAULT: bool = cfg_select! {\n    // Fuchsia components default to full backtrace.\n    target_os = \"fuchsia\" => true,\n    _ => false,\n};\n\npub(crate) struct BacktraceLock<'a>(#[allow(dead_code)] MutexGuard<'a, ()>);\n\npub(crate) fn lock<'a>() -> BacktraceLock<'a> {\n    static LOCK: Mutex<()> = Mutex::new(());\n    BacktraceLock(LOCK.lock().unwrap_or_else(PoisonError::into_inner))\n}\n\nimpl BacktraceLock<'_> {\n    /// Prints the current backtrace.\n    pub(crate) fn print(&mut self, w: &mut dyn Write, format: PrintFmt) -> io::Result<()> {\n        // There are issues currently linking libbacktrace into tests, and in\n        // general during std's own unit tests we're not testing this path. In\n        // test mode immediately return here to optimize away any references to the\n        // libbacktrace symbols\n        if cfg!(test) {\n            return Ok(());\n        }\n\n        struct DisplayBacktrace {\n            format: PrintFmt,\n        }\n        impl fmt::Display for DisplayBacktrace {\n            fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {\n                // SAFETY: the backtrace lock is held\n                unsafe { _print_fmt(fmt, self.format) }\n            }\n        }\n        write!(w, \"{}\", DisplayBacktrace { format })\n    }\n}\n\n/// # Safety\n///\n/// This function is not Sync. The caller must hold a mutex lock, or there must be only one thread in the program.\nunsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt::Result {\n    // Always 'fail' to get the cwd when running under Miri -\n    // this allows Miri to display backtraces in isolation mode\n    let cwd = if !cfg!(miri) { env::current_dir().ok() } else { None };\n\n    let mut print_path = move |fmt: &mut fmt::Formatter<'_>, bows: BytesOrWideString<'_>| {\n        output_filename(fmt, bows, print_fmt, cwd.as_ref())\n    };\n    writeln!(fmt, \"stack backtrace:\")?;\n    let mut bt_fmt = BacktraceFmt::new(fmt, print_fmt, &mut print_path);\n    bt_fmt.add_context()?;\n    let mut idx = 0;\n    let mut res = Ok(());\n    let mut omitted_count: usize = 0;\n    let mut first_omit = true;\n    // If we're using a short backtrace, ignore all frames until we're told to start printing.\n    let mut print = print_fmt != PrintFmt::Short;\n    set_image_base();\n    // SAFETY: we roll our own locking in this town\n    unsafe {\n        backtrace_rs::trace_unsynchronized(|frame| {\n            if print_fmt == PrintFmt::Short && idx > MAX_NB_FRAMES {\n                return false;\n            }\n\n            if cfg!(feature = \"backtrace-trace-only\") {\n                const HEX_WIDTH: usize = 2 + 2 * size_of::<usize>();\n                let frame_ip = frame.ip();\n                res = writeln!(bt_fmt.formatter(), \"{idx:4}: {frame_ip:HEX_WIDTH$?}\");\n            } else {\n                let mut hit = false;\n                backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| {\n                    hit = true;\n\n                    // `__rust_end_short_backtrace` means we are done hiding symbols\n                    // for now. Print until we see `__rust_begin_short_backtrace`.\n                    if print_fmt == PrintFmt::Short {\n                        if let Some(sym) = symbol.name().and_then(|s| s.as_str()) {\n                            if sym.contains(\"__rust_end_short_backtrace\") {\n                                print = true;\n                                return;\n                            }\n                            if print && sym.contains(\"__rust_begin_short_backtrace\") {\n                                print = false;\n                                return;\n                            }\n                            if !print {\n                                omitted_count += 1;\n                            }\n                        }\n                    }\n\n                    if print {\n                        if omitted_count > 0 {\n                            debug_assert!(print_fmt == PrintFmt::Short);\n                            // only print the message between the middle of frames\n                            if !first_omit {\n                                let _ = writeln!(\n                                    bt_fmt.formatter(),\n                                    \"      [... omitted {} frame{} ...]\",\n                                    omitted_count,\n                                    if omitted_count > 1 { \"s\" } else { \"\" }\n                                );\n                            }\n                            first_omit = false;\n                            omitted_count = 0;\n                        }\n                        res = bt_fmt.frame().symbol(frame, symbol);\n                    }\n                });\n                #[cfg(all(target_os = \"nto\", any(target_env = \"nto70\", target_env = \"nto71\")))]\n                if libc::__my_thread_exit as *mut libc::c_void == frame.ip() {\n                    if !hit && print {\n                        use crate::backtrace_rs::SymbolName;\n                        res = bt_fmt.frame().print_raw(\n                            frame.ip(),\n                            Some(SymbolName::new(\"__my_thread_exit\".as_bytes())),\n                            None,\n                            None,\n                        );\n                    }\n                    return false;\n                }\n                if !hit && print {\n                    res = bt_fmt.frame().print_raw(frame.ip(), None, None, None);\n                }\n            }\n\n            idx += 1;\n            res.is_ok()\n        })\n    };\n    res?;\n    bt_fmt.finish()?;\n    if print_fmt == PrintFmt::Short {\n        writeln!(\n            fmt,\n            \"note: Some details are omitted, \\\n             run with `RUST_BACKTRACE=full` for a verbose backtrace.\"\n        )?;\n    }\n    Ok(())\n}\n\n/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. Note that\n/// this is only inline(never) when backtraces in std are enabled, otherwise\n/// it's fine to optimize away.\n#[cfg_attr(feature = \"backtrace\", inline(never))]\npub fn __rust_begin_short_backtrace<F, T>(f: F) -> T\nwhere\n    F: FnOnce() -> T,\n{\n    let result = f();\n\n    // prevent this frame from being tail-call optimised away\n    crate::hint::black_box(());\n\n    result\n}\n\n/// Fixed frame used to clean the backtrace with `RUST_BACKTRACE=1`. Note that\n/// this is only inline(never) when backtraces in std are enabled, otherwise\n/// it's fine to optimize away.\n#[cfg_attr(feature = \"backtrace\", inline(never))]\npub fn __rust_end_short_backtrace<F, T>(f: F) -> T\nwhere\n    F: FnOnce() -> T,\n{\n    let result = f();\n\n    // prevent this frame from being tail-call optimised away\n    crate::hint::black_box(());\n\n    result\n}\n\n/// Prints the filename of the backtrace frame.\n///\n/// See also `output`.\npub fn output_filename(\n    fmt: &mut fmt::Formatter<'_>,\n    bows: BytesOrWideString<'_>,\n    print_fmt: PrintFmt,\n    cwd: Option<&PathBuf>,\n) -> fmt::Result {\n    let file: Cow<'_, Path> = match bows {\n        #[cfg(unix)]\n        BytesOrWideString::Bytes(bytes) => {\n            use crate::os::unix::prelude::*;\n            Path::new(crate::ffi::OsStr::from_bytes(bytes)).into()\n        }\n        #[cfg(not(unix))]\n        BytesOrWideString::Bytes(bytes) => {\n            Path::new(crate::str::from_utf8(bytes).unwrap_or(\"<unknown>\")).into()\n        }\n        #[cfg(windows)]\n        BytesOrWideString::Wide(wide) => {\n            use crate::os::windows::prelude::*;\n            Cow::Owned(crate::ffi::OsString::from_wide(wide).into())\n        }\n        #[cfg(not(windows))]\n        BytesOrWideString::Wide(_wide) => Path::new(\"<unknown>\").into(),\n    };\n    if print_fmt == PrintFmt::Short && file.is_absolute() {\n        if let Some(cwd) = cwd {\n            if let Ok(stripped) = file.strip_prefix(&cwd) {\n                if let Some(s) = stripped.to_str() {\n                    return write!(fmt, \".{}{s}\", path::MAIN_SEPARATOR);\n                }\n            }\n        }\n    }\n    fmt::Display::fmt(&file.display(), fmt)\n}\n\n#[cfg(all(target_vendor = \"fortanix\", target_env = \"sgx\"))]\npub fn set_image_base() {\n    let image_base = crate::os::fortanix_sgx::mem::image_base();\n    backtrace_rs::set_image_base(crate::ptr::without_provenance_mut(image_base as _));\n}\n\n#[cfg(not(all(target_vendor = \"fortanix\", target_env = \"sgx\")))]\npub fn set_image_base() {\n    // nothing to do for platforms other than SGX\n}\n",
    "hint.rs": "#![stable(feature = \"core_hint\", since = \"1.27.0\")]\n\n//! Hints to compiler that affects how code should be emitted or optimized.\n//!\n//! Hints may be compile time or runtime.\n\nuse crate::marker::Destruct;\nuse crate::mem::MaybeUninit;\nuse crate::{intrinsics, ub_checks};\n\n/// Informs the compiler that the site which is calling this function is not\n/// reachable, possibly enabling further optimizations.\n///\n/// # Safety\n///\n/// Reaching this function is *Undefined Behavior*.\n///\n/// As the compiler assumes that all forms of Undefined Behavior can never\n/// happen, it will eliminate all branches in the surrounding code that it can\n/// determine will invariably lead to a call to `unreachable_unchecked()`.\n///\n/// If the assumptions embedded in using this function turn out to be wrong -\n/// that is, if the site which is calling `unreachable_unchecked()` is actually\n/// reachable at runtime - the compiler may have generated nonsensical machine\n/// instructions for this situation, including in seemingly unrelated code,\n/// causing difficult-to-debug problems.\n///\n/// Use this function sparingly. Consider using the [`unreachable!`] macro,\n/// which may prevent some optimizations but will safely panic in case it is\n/// actually reached at runtime. Benchmark your code to find out if using\n/// `unreachable_unchecked()` comes with a performance benefit.\n///\n/// # Examples\n///\n/// `unreachable_unchecked()` can be used in situations where the compiler\n/// can't prove invariants that were previously established. Such situations\n/// have a higher chance of occurring if those invariants are upheld by\n/// external code that the compiler can't analyze.\n/// ```\n/// fn prepare_inputs(divisors: &mut Vec<u32>) {\n///     // Note to future-self when making changes: The invariant established\n///     // here is NOT checked in `do_computation()`; if this changes, you HAVE\n///     // to change `do_computation()`.\n///     divisors.retain(|divisor| *divisor != 0)\n/// }\n///\n/// /// # Safety\n/// /// All elements of `divisor` must be non-zero.\n/// unsafe fn do_computation(i: u32, divisors: &[u32]) -> u32 {\n///     divisors.iter().fold(i, |acc, divisor| {\n///         // Convince the compiler that a division by zero can't happen here\n///         // and a check is not needed below.\n///         if *divisor == 0 {\n///             // Safety: `divisor` can't be zero because of `prepare_inputs`,\n///             // but the compiler does not know about this. We *promise*\n///             // that we always call `prepare_inputs`.\n///             unsafe { std::hint::unreachable_unchecked() }\n///         }\n///         // The compiler would normally introduce a check here that prevents\n///         // a division by zero. However, if `divisor` was zero, the branch\n///         // above would reach what we explicitly marked as unreachable.\n///         // The compiler concludes that `divisor` can't be zero at this point\n///         // and removes the - now proven useless - check.\n///         acc / divisor\n///     })\n/// }\n///\n/// let mut divisors = vec![2, 0, 4];\n/// prepare_inputs(&mut divisors);\n/// let result = unsafe {\n///     // Safety: prepare_inputs() guarantees that divisors is non-zero\n///     do_computation(100, &divisors)\n/// };\n/// assert_eq!(result, 12);\n///\n/// ```\n///\n/// While using `unreachable_unchecked()` is perfectly sound in the following\n/// example, as the compiler is able to prove that a division by zero is not\n/// possible, benchmarking reveals that `unreachable_unchecked()` provides\n/// no benefit over using [`unreachable!`], while the latter does not introduce\n/// the possibility of Undefined Behavior.\n///\n/// ```\n/// fn div_1(a: u32, b: u32) -> u32 {\n///     use std::hint::unreachable_unchecked;\n///\n///     // `b.saturating_add(1)` is always positive (not zero),\n///     // hence `checked_div` will never return `None`.\n///     // Therefore, the else branch is unreachable.\n///     a.checked_div(b.saturating_add(1))\n///         .unwrap_or_else(|| unsafe { unreachable_unchecked() })\n/// }\n///\n/// assert_eq!(div_1(7, 0), 7);\n/// assert_eq!(div_1(9, 1), 4);\n/// assert_eq!(div_1(11, u32::MAX), 0);\n/// ```\n#[inline]\n#[stable(feature = \"unreachable\", since = \"1.27.0\")]\n#[rustc_const_stable(feature = \"const_unreachable_unchecked\", since = \"1.57.0\")]\n#[track_caller]\npub const unsafe fn unreachable_unchecked() -> ! {\n    ub_checks::assert_unsafe_precondition!(\n        check_language_ub,\n        \"hint::unreachable_unchecked must never be reached\",\n        () => false\n    );\n    // SAFETY: the safety contract for `intrinsics::unreachable` must\n    // be upheld by the caller.\n    unsafe { intrinsics::unreachable() }\n}\n\n/// Makes a *soundness* promise to the compiler that `cond` holds.\n///\n/// This may allow the optimizer to simplify things, but it might also make the generated code\n/// slower. Either way, calling it will most likely make compilation take longer.\n///\n/// You may know this from other places as\n/// [`llvm.assume`](https://llvm.org/docs/LangRef.html#llvm-assume-intrinsic) or, in C,\n/// [`__builtin_assume`](https://clang.llvm.org/docs/LanguageExtensions.html#builtin-assume).\n///\n/// This promotes a correctness requirement to a soundness requirement. Don't do that without\n/// very good reason.\n///\n/// # Usage\n///\n/// This is a situational tool for micro-optimization, and is allowed to do nothing. Any use\n/// should come with a repeatable benchmark to show the value, with the expectation to drop it\n/// later should the optimizer get smarter and no longer need it.\n///\n/// The more complicated the condition, the less likely this is to be useful. For example,\n/// `assert_unchecked(foo.is_sorted())` is a complex enough value that the compiler is unlikely\n/// to be able to take advantage of it.\n///\n/// There's also no need to `assert_unchecked` basic properties of things.  For example, the\n/// compiler already knows the range of `count_ones`, so there is no benefit to\n/// `let n = u32::count_ones(x); assert_unchecked(n <= u32::BITS);`.\n///\n/// `assert_unchecked` is logically equivalent to `if !cond { unreachable_unchecked(); }`. If\n/// ever you are tempted to write `assert_unchecked(false)`, you should instead use\n/// [`unreachable_unchecked()`] directly.\n///\n/// # Safety\n///\n/// `cond` must be `true`. It is immediate UB to call this with `false`.\n///\n/// # Example\n///\n/// ```\n/// use core::hint;\n///\n/// /// # Safety\n/// ///\n/// /// `p` must be nonnull and valid\n/// pub unsafe fn next_value(p: *const i32) -> i32 {\n///     // SAFETY: caller invariants guarantee that `p` is not null\n///     unsafe { hint::assert_unchecked(!p.is_null()) }\n///\n///     if p.is_null() {\n///         return -1;\n///     } else {\n///         // SAFETY: caller invariants guarantee that `p` is valid\n///         unsafe { *p + 1 }\n///     }\n/// }\n/// ```\n///\n/// Without the `assert_unchecked`, the above function produces the following with optimizations\n/// enabled:\n///\n/// ```asm\n/// next_value:\n///         test    rdi, rdi\n///         je      .LBB0_1\n///         mov     eax, dword ptr [rdi]\n///         inc     eax\n///         ret\n/// .LBB0_1:\n///         mov     eax, -1\n///         ret\n/// ```\n///\n/// Adding the assertion allows the optimizer to remove the extra check:\n///\n/// ```asm\n/// next_value:\n///         mov     eax, dword ptr [rdi]\n///         inc     eax\n///         ret\n/// ```\n///\n/// This example is quite unlike anything that would be used in the real world: it is redundant\n/// to put an assertion right next to code that checks the same thing, and dereferencing a\n/// pointer already has the builtin assumption that it is nonnull. However, it illustrates the\n/// kind of changes the optimizer can make even when the behavior is less obviously related.\n#[track_caller]\n#[inline(always)]\n#[doc(alias = \"assume\")]\n#[stable(feature = \"hint_assert_unchecked\", since = \"1.81.0\")]\n#[rustc_const_stable(feature = \"hint_assert_unchecked\", since = \"1.81.0\")]\npub const unsafe fn assert_unchecked(cond: bool) {\n    // SAFETY: The caller promised `cond` is true.\n    unsafe {\n        ub_checks::assert_unsafe_precondition!(\n            check_language_ub,\n            \"hint::assert_unchecked must never be called when the condition is false\",\n            (cond: bool = cond) => cond,\n        );\n        crate::intrinsics::assume(cond);\n    }\n}\n\n/// Emits a machine instruction to signal the processor that it is running in\n/// a busy-wait spin-loop (\"spin lock\").\n///\n/// Upon receiving the spin-loop signal the processor can optimize its behavior by,\n/// for example, saving power or switching hyper-threads.\n///\n/// This function is different from [`thread::yield_now`] which directly\n/// yields to the system's scheduler, whereas `spin_loop` does not interact\n/// with the operating system.\n///\n/// A common use case for `spin_loop` is implementing bounded optimistic\n/// spinning in a CAS loop in synchronization primitives. To avoid problems\n/// like priority inversion, it is strongly recommended that the spin loop is\n/// terminated after a finite amount of iterations and an appropriate blocking\n/// syscall is made.\n///\n/// **Note**: On platforms that do not support receiving spin-loop hints this\n/// function does not do anything at all.\n///\n/// # Examples\n///\n/// ```ignore-wasm\n/// use std::sync::atomic::{AtomicBool, Ordering};\n/// use std::sync::Arc;\n/// use std::{hint, thread};\n///\n/// // A shared atomic value that threads will use to coordinate\n/// let live = Arc::new(AtomicBool::new(false));\n///\n/// // In a background thread we'll eventually set the value\n/// let bg_work = {\n///     let live = live.clone();\n///     thread::spawn(move || {\n///         // Do some work, then make the value live\n///         do_some_work();\n///         live.store(true, Ordering::Release);\n///     })\n/// };\n///\n/// // Back on our current thread, we wait for the value to be set\n/// while !live.load(Ordering::Acquire) {\n///     // The spin loop is a hint to the CPU that we're waiting, but probably\n///     // not for very long\n///     hint::spin_loop();\n/// }\n///\n/// // The value is now set\n/// # fn do_some_work() {}\n/// do_some_work();\n/// bg_work.join()?;\n/// # Ok::<(), Box<dyn core::any::Any + Send + 'static>>(())\n/// ```\n///\n/// [`thread::yield_now`]: ../../std/thread/fn.yield_now.html\n#[inline(always)]\n#[stable(feature = \"renamed_spin_loop\", since = \"1.49.0\")]\npub fn spin_loop() {\n    crate::cfg_select! {\n        miri => {\n            unsafe extern \"Rust\" {\n                safe fn miri_spin_loop();\n            }\n\n            // Miri does support some of the intrinsics that are called below, but to guarantee\n            // consistent behavior across targets, this custom function is used.\n            miri_spin_loop();\n        }\n        target_arch = \"x86\" => {\n            // SAFETY: the `cfg` attr ensures that we only execute this on x86 targets.\n            crate::arch::x86::_mm_pause()\n        }\n        target_arch = \"x86_64\" => {\n            // SAFETY: the `cfg` attr ensures that we only execute this on x86_64 targets.\n            crate::arch::x86_64::_mm_pause()\n        }\n        target_arch = \"riscv32\" => crate::arch::riscv32::pause(),\n        target_arch = \"riscv64\" => crate::arch::riscv64::pause(),\n        any(target_arch = \"aarch64\", target_arch = \"arm64ec\") => {\n            // SAFETY: the `cfg` attr ensures that we only execute this on aarch64 targets.\n            unsafe { crate::arch::aarch64::__isb(crate::arch::aarch64::SY) }\n        }\n        all(\n            target_arch = \"arm\",\n            any(\n                all(target_feature = \"v6k\", not(target_feature = \"thumb-mode\")),\n                target_feature = \"v6t2\",\n                all(target_feature = \"v6\", target_feature = \"mclass\"),\n            )\n        ) => {\n            // SAFETY: the `cfg` attr ensures that we only execute this on arm\n            // targets with support for the this feature. On ARMv6 in Thumb\n            // mode, T2 is required (see Arm DDI0406C Section A8.8.427),\n            // otherwise ARMv6-M or ARMv6K is enough\n            unsafe { crate::arch::arm::__yield() }\n        }\n        target_arch = \"loongarch32\" => crate::arch::loongarch32::ibar::<0>(),\n        target_arch = \"loongarch64\" => crate::arch::loongarch64::ibar::<0>(),\n        _ => { /* do nothing */ }\n    }\n}\n\n/// An identity function that *__hints__* to the compiler to be maximally pessimistic about what\n/// `black_box` could do.\n///\n/// Unlike [`std::convert::identity`], a Rust compiler is encouraged to assume that `black_box` can\n/// use `dummy` in any possible valid way that Rust code is allowed to without introducing undefined\n/// behavior in the calling code. This property makes `black_box` useful for writing code in which\n/// certain optimizations are not desired, such as benchmarks.\n///\n/// <div class=\"warning\">\n///\n/// Note however, that `black_box` is only (and can only be) provided on a \"best-effort\" basis. The\n/// extent to which it can block optimisations may vary depending upon the platform and code-gen\n/// backend used. Programs cannot rely on `black_box` for *correctness*, beyond it behaving as the\n/// identity function. As such, it **must not be relied upon to control critical program behavior.**\n/// This also means that this function does not offer any guarantees for cryptographic or security\n/// purposes.\n///\n/// This limitation is not specific to `black_box`; there is no mechanism in the entire Rust\n/// language that can provide the guarantees required for constant-time cryptography.\n/// (There is also no such mechanism in LLVM, so the same is true for every other LLVM-based compiler.)\n///\n/// </div>\n///\n/// [`std::convert::identity`]: crate::convert::identity\n///\n/// # When is this useful?\n///\n/// While not suitable in those mission-critical cases, `black_box`'s functionality can generally be\n/// relied upon for benchmarking, and should be used there. It will try to ensure that the\n/// compiler doesn't optimize away part of the intended test code based on context. For\n/// example:\n///\n/// ```\n/// fn contains(haystack: &[&str], needle: &str) -> bool {\n///     haystack.iter().any(|x| x == &needle)\n/// }\n///\n/// pub fn benchmark() {\n///     let haystack = vec![\"abc\", \"def\", \"ghi\", \"jkl\", \"mno\"];\n///     let needle = \"ghi\";\n///     for _ in 0..10 {\n///         contains(&haystack, needle);\n///     }\n/// }\n/// ```\n///\n/// The compiler could theoretically make optimizations like the following:\n///\n/// - The `needle` and `haystack` do not change, move the call to `contains` outside the loop and\n///   delete the loop\n/// - Inline `contains`\n/// - `needle` and `haystack` have values known at compile time, `contains` is always true. Remove\n///   the call and replace with `true`\n/// - Nothing is done with the result of `contains`: delete this function call entirely\n/// - `benchmark` now has no purpose: delete this function\n///\n/// It is not likely that all of the above happens, but the compiler is definitely able to make some\n/// optimizations that could result in a very inaccurate benchmark. This is where `black_box` comes\n/// in:\n///\n/// ```\n/// use std::hint::black_box;\n///\n/// // Same `contains` function.\n/// fn contains(haystack: &[&str], needle: &str) -> bool {\n///     haystack.iter().any(|x| x == &needle)\n/// }\n///\n/// pub fn benchmark() {\n///     let haystack = vec![\"abc\", \"def\", \"ghi\", \"jkl\", \"mno\"];\n///     let needle = \"ghi\";\n///     for _ in 0..10 {\n///         // Force the compiler to run `contains`, even though it is a pure function whose\n///         // results are unused.\n///         black_box(contains(\n///             // Prevent the compiler from making assumptions about the input.\n///             black_box(&haystack),\n///             black_box(needle),\n///         ));\n///     }\n/// }\n/// ```\n///\n/// This essentially tells the compiler to block optimizations across any calls to `black_box`. So,\n/// it now:\n///\n/// - Treats both arguments to `contains` as unpredictable: the body of `contains` can no longer be\n///   optimized based on argument values\n/// - Treats the call to `contains` and its result as volatile: the body of `benchmark` cannot\n///   optimize this away\n///\n/// This makes our benchmark much more realistic to how the function would actually be used, where\n/// arguments are usually not known at compile time and the result is used in some way.\n///\n/// # How to use this\n///\n/// In practice, `black_box` serves two purposes:\n///\n/// 1. It prevents the compiler from making optimizations related to the value returned by `black_box`\n/// 2. It forces the value passed to `black_box` to be calculated, even if the return value of `black_box` is unused\n///\n/// ```\n/// use std::hint::black_box;\n///\n/// let zero = 0;\n/// let five = 5;\n///\n/// // The compiler will see this and remove the `* five` call, because it knows that multiplying\n/// // any integer by 0 will result in 0.\n/// let c = zero * five;\n///\n/// // Adding `black_box` here disables the compiler's ability to reason about the first operand in the multiplication.\n/// // It is forced to assume that it can be any possible number, so it cannot remove the `* five`\n/// // operation.\n/// let c = black_box(zero) * five;\n/// ```\n///\n/// While most cases will not be as clear-cut as the above example, it still illustrates how\n/// `black_box` can be used. When benchmarking a function, you usually want to wrap its inputs in\n/// `black_box` so the compiler cannot make optimizations that would be unrealistic in real-life\n/// use.\n///\n/// ```\n/// use std::hint::black_box;\n///\n/// // This is a simple function that increments its input by 1. Note that it is pure, meaning it\n/// // has no side-effects. This function has no effect if its result is unused. (An example of a\n/// // function *with* side-effects is `println!()`.)\n/// fn increment(x: u8) -> u8 {\n///     x + 1\n/// }\n///\n/// // Here, we call `increment` but discard its result. The compiler, seeing this and knowing that\n/// // `increment` is pure, will eliminate this function call entirely. This may not be desired,\n/// // though, especially if we're trying to track how much time `increment` takes to execute.\n/// let _ = increment(black_box(5));\n///\n/// // Here, we force `increment` to be executed. This is because the compiler treats `black_box`\n/// // as if it has side-effects, and thus must compute its input.\n/// let _ = black_box(increment(black_box(5)));\n/// ```\n///\n/// There may be additional situations where you want to wrap the result of a function in\n/// `black_box` to force its execution. This is situational though, and may not have any effect\n/// (such as when the function returns a zero-sized type such as [`()` unit][unit]).\n///\n/// Note that `black_box` has no effect on how its input is treated, only its output. As such,\n/// expressions passed to `black_box` may still be optimized:\n///\n/// ```\n/// use std::hint::black_box;\n///\n/// // The compiler sees this...\n/// let y = black_box(5 * 10);\n///\n/// // ...as this. As such, it will likely simplify `5 * 10` to just `50`.\n/// let _0 = 5 * 10;\n/// let y = black_box(_0);\n/// ```\n///\n/// In the above example, the `5 * 10` expression is considered distinct from the `black_box` call,\n/// and thus is still optimized by the compiler. You can prevent this by moving the multiplication\n/// operation outside of `black_box`:\n///\n/// ```\n/// use std::hint::black_box;\n///\n/// // No assumptions can be made about either operand, so the multiplication is not optimized out.\n/// let y = black_box(5) * black_box(10);\n/// ```\n///\n/// During constant evaluation, `black_box` is treated as a no-op.\n#[inline]\n#[stable(feature = \"bench_black_box\", since = \"1.66.0\")]\n#[rustc_const_stable(feature = \"const_black_box\", since = \"1.86.0\")]\npub const fn black_box<T>(dummy: T) -> T {\n    crate::intrinsics::black_box(dummy)\n}\n\n/// An identity function that causes an `unused_must_use` warning to be\n/// triggered if the given value is not used (returned, stored in a variable,\n/// etc) by the caller.\n///\n/// This is primarily intended for use in macro-generated code, in which a\n/// [`#[must_use]` attribute][must_use] either on a type or a function would not\n/// be convenient.\n///\n/// [must_use]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-must_use-attribute\n///\n/// # Example\n///\n/// ```\n/// #![feature(hint_must_use)]\n///\n/// use core::fmt;\n///\n/// pub struct Error(/* ... */);\n///\n/// #[macro_export]\n/// macro_rules! make_error {\n///     ($($args:expr),*) => {\n///         core::hint::must_use({\n///             let error = make_error(core::format_args!($($args),*));\n///             error\n///         })\n///     };\n/// }\n///\n/// // Implementation detail of make_error! macro.\n/// #[doc(hidden)]\n/// pub fn make_error(args: fmt::Arguments<'_>) -> Error {\n///     Error(/* ... */)\n/// }\n///\n/// fn demo() -> Option<Error> {\n///     if true {\n///         // Oops, meant to write `return Some(make_error!(\"...\"));`\n///         Some(make_error!(\"...\"));\n///     }\n///     None\n/// }\n/// #\n/// # // Make rustdoc not wrap the whole snippet in fn main, so that $crate::make_error works\n/// # fn main() {}\n/// ```\n///\n/// In the above example, we'd like an `unused_must_use` lint to apply to the\n/// value created by `make_error!`. However, neither `#[must_use]` on a struct\n/// nor `#[must_use]` on a function is appropriate here, so the macro expands\n/// using `core::hint::must_use` instead.\n///\n/// - We wouldn't want `#[must_use]` on the `struct Error` because that would\n///   make the following unproblematic code trigger a warning:\n///\n///   ```\n///   # struct Error;\n///   #\n///   fn f(arg: &str) -> Result<(), Error>\n///   # { Ok(()) }\n///\n///   #[test]\n///   fn t() {\n///       // Assert that `f` returns error if passed an empty string.\n///       // A value of type `Error` is unused here but that's not a problem.\n///       f(\"\").unwrap_err();\n///   }\n///   ```\n///\n/// - Using `#[must_use]` on `fn make_error` can't help because the return value\n///   *is* used, as the right-hand side of a `let` statement. The `let`\n///   statement looks useless but is in fact necessary for ensuring that\n///   temporaries within the `format_args` expansion are not kept alive past the\n///   creation of the `Error`, as keeping them alive past that point can cause\n///   autotrait issues in async code:\n///\n///   ```\n///   # #![feature(hint_must_use)]\n///   #\n///   # struct Error;\n///   #\n///   # macro_rules! make_error {\n///   #     ($($args:expr),*) => {\n///   #         core::hint::must_use({\n///   #             // If `let` isn't used, then `f()` produces a non-Send future.\n///   #             let error = make_error(core::format_args!($($args),*));\n///   #             error\n///   #         })\n///   #     };\n///   # }\n///   #\n///   # fn make_error(args: core::fmt::Arguments<'_>) -> Error {\n///   #     Error\n///   # }\n///   #\n///   async fn f() {\n///       // Using `let` inside the make_error expansion causes temporaries like\n///       // `unsync()` to drop at the semicolon of that `let` statement, which\n///       // is prior to the await point. They would otherwise stay around until\n///       // the semicolon on *this* statement, which is after the await point,\n///       // and the enclosing Future would not implement Send.\n///       log(make_error!(\"look: {:p}\", unsync())).await;\n///   }\n///\n///   async fn log(error: Error) {/* ... */}\n///\n///   // Returns something without a Sync impl.\n///   fn unsync() -> *const () {\n///       0 as *const ()\n///   }\n///   #\n///   # fn test() {\n///   #     fn assert_send(_: impl Send) {}\n///   #     assert_send(f());\n///   # }\n///   ```\n#[unstable(feature = \"hint_must_use\", issue = \"94745\")]\n#[must_use] // <-- :)\n#[inline(always)]\npub const fn must_use<T>(value: T) -> T {\n    value\n}\n\n/// Hints to the compiler that a branch condition is likely to be true.\n/// Returns the value passed to it.\n///\n/// It can be used with `if` or boolean `match` expressions.\n///\n/// When used outside of a branch condition, it may still influence a nearby branch, but\n/// probably will not have any effect.\n///\n/// It can also be applied to parts of expressions, such as `likely(a) && unlikely(b)`, or to\n/// compound expressions, such as `likely(a && b)`. When applied to compound expressions, it has\n/// the following effect:\n/// ```text\n///     likely(!a) => !unlikely(a)\n///     likely(a && b) => likely(a) && likely(b)\n///     likely(a || b) => a || likely(b)\n/// ```\n///\n/// See also the function [`cold_path()`] which may be more appropriate for idiomatic Rust code.\n///\n/// # Examples\n///\n/// ```\n/// #![feature(likely_unlikely)]\n/// use core::hint::likely;\n///\n/// fn foo(x: i32) {\n///     if likely(x > 0) {\n///         println!(\"this branch is likely to be taken\");\n///     } else {\n///         println!(\"this branch is unlikely to be taken\");\n///     }\n///\n///     match likely(x > 0) {\n///         true => println!(\"this branch is likely to be taken\"),\n///         false => println!(\"this branch is unlikely to be taken\"),\n///     }\n///\n///     // Use outside of a branch condition may still influence a nearby branch\n///     let cond = likely(x != 0);\n///     if cond {\n///         println!(\"this branch is likely to be taken\");\n///     }\n/// }\n/// ```\n#[unstable(feature = \"likely_unlikely\", issue = \"151619\")]\n#[inline(always)]\npub const fn likely(b: bool) -> bool {\n    crate::intrinsics::likely(b)\n}\n\n/// Hints to the compiler that a branch condition is unlikely to be true.\n/// Returns the value passed to it.\n///\n/// It can be used with `if` or boolean `match` expressions.\n///\n/// When used outside of a branch condition, it may still influence a nearby branch, but\n/// probably will not have any effect.\n///\n/// It can also be applied to parts of expressions, such as `likely(a) && unlikely(b)`, or to\n/// compound expressions, such as `unlikely(a && b)`. When applied to compound expressions, it has\n/// the following effect:\n/// ```text\n///     unlikely(!a) => !likely(a)\n///     unlikely(a && b) => a && unlikely(b)\n///     unlikely(a || b) => unlikely(a) || unlikely(b)\n/// ```\n///\n/// See also the function [`cold_path()`] which may be more appropriate for idiomatic Rust code.\n///\n/// # Examples\n///\n/// ```\n/// #![feature(likely_unlikely)]\n/// use core::hint::unlikely;\n///\n/// fn foo(x: i32) {\n///     if unlikely(x > 0) {\n///         println!(\"this branch is unlikely to be taken\");\n///     } else {\n///         println!(\"this branch is likely to be taken\");\n///     }\n///\n///     match unlikely(x > 0) {\n///         true => println!(\"this branch is unlikely to be taken\"),\n///         false => println!(\"this branch is likely to be taken\"),\n///     }\n///\n///     // Use outside of a branch condition may still influence a nearby branch\n///     let cond = unlikely(x != 0);\n///     if cond {\n///         println!(\"this branch is likely to be taken\");\n///     }\n/// }\n/// ```\n#[unstable(feature = \"likely_unlikely\", issue = \"151619\")]\n#[inline(always)]\npub const fn unlikely(b: bool) -> bool {\n    crate::intrinsics::unlikely(b)\n}\n\n/// Hints to the compiler that given path is cold, i.e., unlikely to be taken. The compiler may\n/// choose to optimize paths that are not cold at the expense of paths that are cold.\n///\n/// Note that like all hints, the exact effect to codegen is not guaranteed. Using `cold_path`\n/// can actually *decrease* performance if the branch is called more than expected. It is advisable\n/// to perform benchmarks to tell if this function is useful.\n///\n/// # Examples\n///\n/// ```\n/// use core::hint::cold_path;\n///\n/// fn foo(x: &[i32]) {\n///     if let Some(first) = x.get(0) {\n///         // this is the fast path\n///     } else {\n///         // this path is unlikely\n///         cold_path();\n///     }\n/// }\n///\n/// fn bar(x: i32) -> i32 {\n///     match x {\n///         1 => 10,\n///         2 => 100,\n///         3 => { cold_path(); 1000 }, // this branch is unlikely\n///         _ => { cold_path(); 10000 }, // this is also unlikely\n///     }\n/// }\n/// ```\n///\n/// This can also be used to implement `likely` and `unlikely` helpers to hint the condition rather\n/// than the branch:\n///\n/// ```\n/// use core::hint::cold_path;\n///\n/// #[inline(always)]\n/// pub const fn likely(b: bool) -> bool {\n///     if !b {\n///         cold_path();\n///     }\n///     b\n/// }\n///\n/// #[inline(always)]\n/// pub const fn unlikely(b: bool) -> bool {\n///     if b {\n///         cold_path();\n///     }\n///     b\n/// }\n///\n/// fn foo(x: i32) {\n///     if likely(x > 0) {\n///         println!(\"this branch is likely to be taken\");\n///     } else {\n///         println!(\"this branch is unlikely to be taken\");\n///     }\n/// }\n/// ```\n#[stable(feature = \"cold_path\", since = \"1.95.0\")]\n#[rustc_const_stable(feature = \"cold_path\", since = \"1.95.0\")]\n#[inline(always)]\n// Even if for some reason the cold_path intrinsic is not visible to codegen, the coldness will\n// ensure that branches this is in are still known to be cold.\n#[cold]\npub const fn cold_path() {\n    crate::intrinsics::cold_path()\n}\n\n/// Returns either `true_val` or `false_val` depending on the value of\n/// `condition`, with a hint to the compiler that `condition` is unlikely to be\n/// correctly predicted by a CPU’s branch predictor.\n///\n/// This method is functionally equivalent to\n/// ```ignore (this is just for illustrative purposes)\n/// fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T {\n///     if b { true_val } else { false_val }\n/// }\n/// ```\n/// but might generate different assembly. In particular, on platforms with\n/// a conditional move or select instruction (like `cmov` on x86 or `csel`\n/// on ARM) the optimizer might use these instructions to avoid branches,\n/// which can benefit performance if the branch predictor is struggling\n/// with predicting `condition`, such as in an implementation of binary\n/// search.\n///\n/// Note however that this lowering is not guaranteed (on any platform) and\n/// should not be relied upon when trying to write cryptographic constant-time\n/// code. Also be aware that this lowering might *decrease* performance if\n/// `condition` is well-predictable. It is advisable to perform benchmarks to\n/// tell if this function is useful.\n///\n/// # Examples\n///\n/// Distribute values evenly between two buckets:\n/// ```\n/// use std::hash::BuildHasher;\n/// use std::hint;\n///\n/// fn append<H: BuildHasher>(hasher: &H, v: i32, bucket_one: &mut Vec<i32>, bucket_two: &mut Vec<i32>) {\n///     let hash = hasher.hash_one(&v);\n///     let bucket = hint::select_unpredictable(hash % 2 == 0, bucket_one, bucket_two);\n///     bucket.push(v);\n/// }\n/// # let hasher = std::collections::hash_map::RandomState::new();\n/// # let mut bucket_one = Vec::new();\n/// # let mut bucket_two = Vec::new();\n/// # append(&hasher, 42, &mut bucket_one, &mut bucket_two);\n/// # assert_eq!(bucket_one.len() + bucket_two.len(), 1);\n/// ```\n#[inline(always)]\n#[stable(feature = \"select_unpredictable\", since = \"1.88.0\")]\n#[rustc_const_unstable(feature = \"const_select_unpredictable\", issue = \"145938\")]\npub const fn select_unpredictable<T>(condition: bool, true_val: T, false_val: T) -> T\nwhere\n    T: [const] Destruct,\n{\n    // FIXME(https://github.com/rust-lang/unsafe-code-guidelines/issues/245):\n    // Change this to use ManuallyDrop instead.\n    let mut true_val = MaybeUninit::new(true_val);\n    let mut false_val = MaybeUninit::new(false_val);\n\n    struct DropOnPanic<T> {\n        // Invariant: valid pointer and points to an initialized value that is not further used,\n        // i.e. it can be dropped by this guard.\n        inner: *mut T,\n    }\n\n    impl<T> Drop for DropOnPanic<T> {\n        fn drop(&mut self) {\n            // SAFETY: Must be guaranteed on construction of local type `DropOnPanic`.\n            unsafe { self.inner.drop_in_place() }\n        }\n    }\n\n    let true_ptr = true_val.as_mut_ptr();\n    let false_ptr = false_val.as_mut_ptr();\n\n    // SAFETY: The value that is not selected is dropped, and the selected one\n    // is returned. This is necessary because the intrinsic doesn't drop the\n    // value that is  not selected.\n    unsafe {\n        // Extract the selected value first, ensure it is dropped as well if dropping the unselected\n        // value panics. We construct a temporary by-pointer guard around the selected value while\n        // dropping the unselected value. Arguments overlap here, so we can not use mutable\n        // reference for these arguments.\n        let guard = crate::intrinsics::select_unpredictable(condition, true_ptr, false_ptr);\n        let drop = crate::intrinsics::select_unpredictable(condition, false_ptr, true_ptr);\n\n        // SAFETY: both pointers are well-aligned and point to initialized values inside a\n        // `MaybeUninit` each. In both possible values for `condition` the pointer `guard` and\n        // `drop` do not alias (even though the two argument pairs we have selected from did alias\n        // each other).\n        let guard = DropOnPanic { inner: guard };\n        drop.drop_in_place();\n        crate::mem::forget(guard);\n\n        // Note that it is important to use the values here. Reading from the pointer we got makes\n        // LLVM forget the !unpredictable annotation sometimes (in tests, integer sized values in\n        // particular seemed to confuse it, also observed in llvm/llvm-project #82340).\n        crate::intrinsics::select_unpredictable(condition, true_val, false_val).assume_init()\n    }\n}\n\n/// The expected temporal locality of a memory prefetch operation.\n///\n/// Locality expresses how likely the prefetched data is to be reused soon,\n/// and therefore which level of cache it should be brought into.\n///\n/// The locality is just a hint, and may be ignored on some targets or by the hardware.\n///\n/// Used with functions like [`prefetch_read`] and [`prefetch_write`].\n///\n/// [`prefetch_read`]: crate::hint::prefetch_read\n/// [`prefetch_write`]: crate::hint::prefetch_write\n#[unstable(feature = \"hint_prefetch\", issue = \"146941\")]\n#[non_exhaustive]\n#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]\npub enum Locality {\n    /// Data is expected to be reused eventually.\n    ///\n    /// Typically prefetches into L3 cache (if the CPU supports it).\n    L3,\n    /// Data is expected to be reused in the near future.\n    ///\n    /// Typically prefetches into L2 cache.\n    L2,\n    /// Data is expected to be reused very soon.\n    ///\n    /// Typically prefetches into L1 cache.\n    L1,\n}\n\nimpl Locality {\n    /// Convert to the constant that LLVM associates with a locality.\n    const fn to_llvm(self) -> i32 {\n        match self {\n            Self::L3 => 1,\n            Self::L2 => 2,\n            Self::L1 => 3,\n        }\n    }\n}\n\n/// Prefetch the cache line containing `ptr` for a future read.\n///\n/// A strategically placed prefetch can reduce cache miss latency if the data is accessed\n/// soon after, but may also increase bandwidth usage or evict other cache lines.\n///\n/// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware.\n///\n/// Passing a dangling or invalid pointer is permitted: the memory will not\n/// actually be dereferenced, and no faults are raised.\n///\n/// # Examples\n///\n/// ```\n/// #![feature(hint_prefetch)]\n/// use std::hint::{Locality, prefetch_read};\n/// use std::mem::size_of_val;\n///\n/// // Prefetch all of `slice` into the L1 cache.\n/// fn prefetch_slice<T>(slice: &[T]) {\n///     // On most systems the cache line size is 64 bytes.\n///     for offset in (0..size_of_val(slice)).step_by(64) {\n///         prefetch_read(slice.as_ptr().wrapping_add(offset), Locality::L1);\n///     }\n/// }\n/// ```\n#[inline(always)]\n#[unstable(feature = \"hint_prefetch\", issue = \"146941\")]\npub const fn prefetch_read<T>(ptr: *const T, locality: Locality) {\n    match locality {\n        Locality::L3 => intrinsics::prefetch_read_data::<T, { Locality::L3.to_llvm() }>(ptr),\n        Locality::L2 => intrinsics::prefetch_read_data::<T, { Locality::L2.to_llvm() }>(ptr),\n        Locality::L1 => intrinsics::prefetch_read_data::<T, { Locality::L1.to_llvm() }>(ptr),\n    }\n}\n\n/// Prefetch the cache line containing `ptr` for a single future read, but attempt to avoid\n/// polluting the cache.\n///\n/// A strategically placed prefetch can reduce cache miss latency if the data is accessed\n/// soon after, but may also increase bandwidth usage or evict other cache lines.\n///\n/// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware.\n///\n/// Passing a dangling or invalid pointer is permitted: the memory will not\n/// actually be dereferenced, and no faults are raised.\n#[inline(always)]\n#[unstable(feature = \"hint_prefetch\", issue = \"146941\")]\npub const fn prefetch_read_non_temporal<T>(ptr: *const T, locality: Locality) {\n    // The LLVM intrinsic does not currently support specifying the locality.\n    let _ = locality;\n    intrinsics::prefetch_read_data::<T, 0>(ptr)\n}\n\n/// Prefetch the cache line containing `ptr` for a future write.\n///\n/// A strategically placed prefetch can reduce cache miss latency if the data is accessed\n/// soon after, but may also increase bandwidth usage or evict other cache lines.\n///\n/// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware.\n///\n/// Passing a dangling or invalid pointer is permitted: the memory will not\n/// actually be dereferenced, and no faults are raised.\n#[inline(always)]\n#[unstable(feature = \"hint_prefetch\", issue = \"146941\")]\npub const fn prefetch_write<T>(ptr: *mut T, locality: Locality) {\n    match locality {\n        Locality::L3 => intrinsics::prefetch_write_data::<T, { Locality::L3.to_llvm() }>(ptr),\n        Locality::L2 => intrinsics::prefetch_write_data::<T, { Locality::L2.to_llvm() }>(ptr),\n        Locality::L1 => intrinsics::prefetch_write_data::<T, { Locality::L1.to_llvm() }>(ptr),\n    }\n}\n\n/// Prefetch the cache line containing `ptr` for a single future write, but attempt to avoid\n/// polluting the cache.\n///\n/// A strategically placed prefetch can reduce cache miss latency if the data is accessed\n/// soon after, but may also increase bandwidth usage or evict other cache lines.\n///\n/// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware.\n///\n/// Passing a dangling or invalid pointer is permitted: the memory will not\n/// actually be dereferenced, and no faults are raised.\n#[inline(always)]\n#[unstable(feature = \"hint_prefetch\", issue = \"146941\")]\npub const fn prefetch_write_non_temporal<T>(ptr: *const T, locality: Locality) {\n    // The LLVM intrinsic does not currently support specifying the locality.\n    let _ = locality;\n    intrinsics::prefetch_write_data::<T, 0>(ptr)\n}\n\n/// Prefetch the cache line containing `ptr` into the instruction cache for a future read.\n///\n/// A strategically placed prefetch can reduce cache miss latency if the instructions are\n/// accessed soon after, but may also increase bandwidth usage or evict other cache lines.\n///\n/// A prefetch is a *hint*, and may be ignored on certain targets or by the hardware.\n///\n/// Passing a dangling or invalid pointer is permitted: the memory will not\n/// actually be dereferenced, and no faults are raised.\n#[inline(always)]\n#[unstable(feature = \"hint_prefetch\", issue = \"146941\")]\npub const fn prefetch_read_instruction<T>(ptr: *const T, locality: Locality) {\n    match locality {\n        Locality::L3 => intrinsics::prefetch_read_instruction::<T, { Locality::L3.to_llvm() }>(ptr),\n        Locality::L2 => intrinsics::prefetch_read_instruction::<T, { Locality::L2.to_llvm() }>(ptr),\n        Locality::L1 => intrinsics::prefetch_read_instruction::<T, { Locality::L1.to_llvm() }>(ptr),\n    }\n}\n",
    "rt.rs": "//! Runtime services\n//!\n//! The `rt` module provides a narrow set of runtime services,\n//! including the global heap (exported in `heap`) and unwinding and\n//! backtrace support. The APIs in this module are highly unstable,\n//! and should be considered as private implementation details for the\n//! time being.\n\n#![unstable(\n    feature = \"rt\",\n    reason = \"this public module should not exist and is highly likely \\\n              to disappear\",\n    issue = \"none\"\n)]\n#![doc(hidden)]\n#![deny(unsafe_op_in_unsafe_fn)]\n#![allow(unused_macros)]\n\n#[rustfmt::skip]\npub use crate::panicking::{begin_panic, panic_count};\npub use core::panicking::{panic_display, panic_fmt};\n\n#[rustfmt::skip]\nuse crate::any::Any;\nuse crate::sync::Once;\nuse crate::thread::{self, main_thread};\nuse crate::{mem, panic, sys};\n\n// This function is needed by the panic runtime.\n#[cfg(not(test))]\n#[rustc_std_internal_symbol]\nfn __rust_abort() {\n    crate::process::abort();\n}\n\n// Prints to the \"panic output\", depending on the platform this may be:\n// - the standard error output\n// - some dedicated platform specific output\n// - nothing (so this macro is a no-op)\nmacro_rules! rtprintpanic {\n    ($($t:tt)*) => {\n        #[cfg(not(panic = \"immediate-abort\"))]\n        if let Some(mut out) = crate::sys::stdio::panic_output() {\n            let _ = crate::io::Write::write_fmt(&mut out, format_args!($($t)*));\n        }\n        #[cfg(panic = \"immediate-abort\")]\n        {\n            let _ = format_args!($($t)*);\n        }\n    }\n}\n\nmacro_rules! rtabort {\n    ($($t:tt)*) => {\n        {\n            rtprintpanic!(\"fatal runtime error: {}, aborting\\n\", format_args!($($t)*));\n            crate::process::abort();\n        }\n    }\n}\n\nmacro_rules! rtassert {\n    ($e:expr) => {\n        if !$e {\n            rtabort!(concat!(\"assertion failed: \", stringify!($e)));\n        }\n    };\n}\n\nmacro_rules! rtunwrap {\n    ($ok:ident, $e:expr) => {\n        match $e {\n            $ok(v) => v,\n            ref err => {\n                let err = err.as_ref().map(drop); // map Ok/Some which might not be Debug\n                rtabort!(concat!(\"unwrap failed: \", stringify!($e), \" = {:?}\"), err)\n            }\n        }\n    };\n}\n\nfn handle_rt_panic<T>(e: Box<dyn Any + Send>) -> T {\n    mem::forget(e);\n    rtabort!(\"initialization or cleanup bug\");\n}\n\n// One-time runtime initialization.\n// Runs before `main`.\n// SAFETY: must be called only once during runtime initialization.\n// NOTE: this is not guaranteed to run, for example when Rust code is called externally.\n//\n// # The `sigpipe` parameter\n//\n// Since 2014, the Rust runtime on Unix has set the `SIGPIPE` handler to\n// `SIG_IGN`. Applications have good reasons to want a different behavior\n// though, so there is a `-Zon-broken-pipe` compiler flag that\n// can be used to select how `SIGPIPE` shall be setup (if changed at all) before\n// `fn main()` is called. See <https://github.com/rust-lang/rust/issues/97889>\n// for more info.\n//\n// The `sigpipe` parameter to this function gets its value via the code that\n// rustc generates to invoke `fn lang_start()`. The reason we have `sigpipe` for\n// all platforms and not only Unix, is because std is not allowed to have `cfg`\n// directives as this high level. See the module docs in\n// `src/tools/tidy/src/pal.rs` for more info. On all other platforms, `sigpipe`\n// has a value, but its value is ignored.\n//\n// Even though it is an `u8`, it only ever has 4 values. These are documented in\n// `compiler/rustc_session/src/config/sigpipe.rs`.\n#[cfg_attr(test, allow(dead_code))]\nunsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {\n    // Remember the main thread ID to give it the correct name.\n    // SAFETY: this is the only time and place where we call this function.\n    unsafe { main_thread::set(thread::current_id()) };\n\n    #[cfg_attr(target_os = \"teeos\", allow(unused_unsafe))]\n    unsafe {\n        sys::init(argc, argv, sigpipe)\n    };\n}\n\n/// Clean up the thread-local runtime state. This *should* be run after all other\n/// code managed by the Rust runtime, but will not cause UB if that condition is\n/// not fulfilled. Also note that this function is not guaranteed to be run, but\n/// skipping it will cause leaks and therefore is to be avoided.\npub(crate) fn thread_cleanup() {\n    // This function is run in situations where unwinding leads to an abort\n    // (think `extern \"C\"` functions). Abort here instead so that we can\n    // print a nice message.\n    panic::catch_unwind(|| {\n        crate::thread::drop_current();\n    })\n    .unwrap_or_else(handle_rt_panic);\n}\n\n// One-time runtime cleanup.\n// Runs after `main` or at program exit.\n// NOTE: this is not guaranteed to run, for example when the program aborts.\npub(crate) fn cleanup() {\n    static CLEANUP: Once = Once::new();\n    CLEANUP.call_once(|| unsafe {\n        // Flush stdout and disable buffering.\n        crate::io::cleanup();\n        // SAFETY: Only called once during runtime cleanup.\n        sys::cleanup();\n    });\n}\n\n// To reduce the generated code of the new `lang_start`, this function is doing\n// the real work.\n#[cfg(not(test))]\nfn lang_start_internal(\n    main: &(dyn Fn() -> i32 + Sync + crate::panic::RefUnwindSafe),\n    argc: isize,\n    argv: *const *const u8,\n    sigpipe: u8,\n) -> isize {\n    // Guard against the code called by this function from unwinding outside of the Rust-controlled\n    // code, which is UB. This is a requirement imposed by a combination of how the\n    // `#[lang=\"start\"]` attribute is implemented as well as by the implementation of the panicking\n    // mechanism itself.\n    //\n    // There are a couple of instances where unwinding can begin. First is inside of the\n    // `rt::init`, `rt::cleanup` and similar functions controlled by std. In those instances a\n    // panic is a std implementation bug. A quite likely one too, as there isn't any way to\n    // prevent std from accidentally introducing a panic to these functions. Another is from\n    // user code from `main` or, more nefariously, as described in e.g. issue #86030.\n    //\n    // We use `catch_unwind` with `handle_rt_panic` instead of `abort_unwind` to make the error in\n    // case of a panic a bit nicer.\n    panic::catch_unwind(move || {\n        // SAFETY: Only called once during runtime initialization.\n        unsafe { init(argc, argv, sigpipe) };\n\n        let ret_code = panic::catch_unwind(main).unwrap_or_else(move |payload| {\n            // Carefully dispose of the panic payload.\n            let payload = panic::AssertUnwindSafe(payload);\n            panic::catch_unwind(move || drop({ payload }.0)).unwrap_or_else(move |e| {\n                mem::forget(e); // do *not* drop the 2nd payload\n                rtabort!(\"drop of the panic payload panicked\");\n            });\n            // Return error code for panicking programs.\n            101\n        });\n        let ret_code = ret_code as isize;\n\n        cleanup();\n        // Guard against multiple threads calling `libc::exit` concurrently.\n        // See the documentation for `unique_thread_exit` for more information.\n        crate::sys::exit::unique_thread_exit();\n\n        ret_code\n    })\n    .unwrap_or_else(handle_rt_panic)\n}\n\n#[cfg(not(any(test, doctest)))]\n#[lang = \"start\"]\nfn lang_start<T: crate::process::Termination + 'static>(\n    main: fn() -> T,\n    argc: isize,\n    argv: *const *const u8,\n    sigpipe: u8,\n) -> isize {\n    lang_start_internal(\n        &move || crate::sys::backtrace::__rust_begin_short_backtrace(main).report().to_i32(),\n        argc,\n        argv,\n        sigpipe,\n    )\n}\n",
    "function.rs": "use crate::marker::Tuple;\n\n/// The version of the call operator that takes an immutable receiver.\n///\n/// Instances of `Fn` can be called repeatedly without mutating state.\n///\n/// *This trait (`Fn`) is not to be confused with [function pointers]\n/// (`fn`).*\n///\n/// `Fn` is implemented automatically by closures which only take immutable\n/// references to captured variables or don't capture anything at all, as well\n/// as (safe) [function pointers] (with some caveats, see their documentation\n/// for more details). Additionally, for any type `F` that implements `Fn`, `&F`\n/// implements `Fn`, too.\n///\n/// Since both [`FnMut`] and [`FnOnce`] are supertraits of `Fn`, any\n/// instance of `Fn` can be used as a parameter where a [`FnMut`] or [`FnOnce`]\n/// is expected.\n///\n/// Use `Fn` as a bound when you want to accept a parameter of function-like\n/// type and need to call it repeatedly and without mutating state (e.g., when\n/// calling it concurrently). If you do not need such strict requirements, use\n/// [`FnMut`] or [`FnOnce`] as bounds.\n///\n/// See the [chapter on closures in *The Rust Programming Language*][book] for\n/// some more information on this topic.\n///\n/// Also of note is the special syntax for `Fn` traits (e.g.\n/// `Fn(usize, bool) -> usize`). Those interested in the technical details of\n/// this can refer to [the relevant section in the *Rustonomicon*][nomicon].\n///\n/// [book]: ../../book/ch13-01-closures.html\n/// [function pointers]: fn\n/// [nomicon]: ../../nomicon/hrtb.html\n///\n/// # Examples\n///\n/// ## Calling a closure\n///\n/// ```\n/// let square = |x| x * x;\n/// assert_eq!(square(5), 25);\n/// ```\n///\n/// ## Using a `Fn` parameter\n///\n/// ```\n/// fn call_with_one<F>(func: F) -> usize\n///     where F: Fn(usize) -> usize {\n///     func(1)\n/// }\n///\n/// let double = |x| x * 2;\n/// assert_eq!(call_with_one(double), 2);\n/// ```\n#[lang = \"fn\"]\n#[stable(feature = \"rust1\", since = \"1.0.0\")]\n#[rustc_paren_sugar]\n#[rustc_on_unimplemented(\n    on(\n        Args = \"()\",\n        note = \"wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`\"\n    ),\n    on(\n        Self = \"unsafe fn\",\n        note = \"unsafe function cannot be called generically without an unsafe block\",\n        // SAFETY: tidy is not smart enough to tell that the below unsafe block is a string\n        label = \"call the function in a closure: `|| unsafe {{ /* code */ }}`\"\n    ),\n    message = \"expected a `{This:resolved}` closure, found `{Self}`\",\n    label = \"expected an `{This:resolved}` closure, found `{Self}`\"\n)]\n#[fundamental] // so that regex can rely that `&str: !FnMut`\n#[must_use = \"closures are lazy and do nothing unless called\"]\n#[rustc_const_unstable(feature = \"const_trait_impl\", issue = \"143874\")]\npub const trait Fn<Args: Tuple>: [const] FnMut<Args> {\n    /// Performs the call operation.\n    #[unstable(feature = \"fn_traits\", issue = \"29625\")]\n    extern \"rust-call\" fn call(&self, args: Args) -> Self::Output;\n}\n\n/// The version of the call operator that takes a mutable receiver.\n///\n/// Instances of `FnMut` can be called repeatedly and may mutate state.\n///\n/// `FnMut` is implemented automatically by closures which take mutable\n/// references to captured variables, as well as all types that implement\n/// [`Fn`], e.g., (safe) [function pointers] (since `FnMut` is a supertrait of\n/// [`Fn`]). Additionally, for any type `F` that implements `FnMut`, `&mut F`\n/// implements `FnMut`, too.\n///\n/// Since [`FnOnce`] is a supertrait of `FnMut`, any instance of `FnMut` can be\n/// used where a [`FnOnce`] is expected, and since [`Fn`] is a subtrait of\n/// `FnMut`, any instance of [`Fn`] can be used where `FnMut` is expected.\n///\n/// Use `FnMut` as a bound when you want to accept a parameter of function-like\n/// type and need to call it repeatedly, while allowing it to mutate state.\n/// If you don't want the parameter to mutate state, use [`Fn`] as a\n/// bound; if you don't need to call it repeatedly, use [`FnOnce`].\n///\n/// See the [chapter on closures in *The Rust Programming Language*][book] for\n/// some more information on this topic.\n///\n/// Also of note is the special syntax for `Fn` traits (e.g.\n/// `Fn(usize, bool) -> usize`). Those interested in the technical details of\n/// this can refer to [the relevant section in the *Rustonomicon*][nomicon].\n///\n/// [book]: ../../book/ch13-01-closures.html\n/// [function pointers]: fn\n/// [nomicon]: ../../nomicon/hrtb.html\n///\n/// # Examples\n///\n/// ## Calling a mutably capturing closure\n///\n/// ```\n/// let mut x = 5;\n/// {\n///     let mut square_x = || x *= x;\n///     square_x();\n/// }\n/// assert_eq!(x, 25);\n/// ```\n///\n/// ## Using a `FnMut` parameter\n///\n/// ```\n/// fn do_twice<F>(mut func: F)\n///     where F: FnMut()\n/// {\n///     func();\n///     func();\n/// }\n///\n/// let mut x: usize = 1;\n/// {\n///     let add_two_to_x = || x += 2;\n///     do_twice(add_two_to_x);\n/// }\n///\n/// assert_eq!(x, 5);\n/// ```\n#[lang = \"fn_mut\"]\n#[stable(feature = \"rust1\", since = \"1.0.0\")]\n#[rustc_paren_sugar]\n#[rustc_on_unimplemented(\n    on(\n        Args = \"()\",\n        note = \"wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`\"\n    ),\n    on(\n        Self = \"unsafe fn\",\n        note = \"unsafe function cannot be called generically without an unsafe block\",\n        // SAFETY: tidy is not smart enough to tell that the below unsafe block is a string\n        label = \"call the function in a closure: `|| unsafe {{ /* code */ }}`\"\n    ),\n    message = \"expected a `{This:resolved}` closure, found `{Self}`\",\n    label = \"expected an `{This:resolved}` closure, found `{Self}`\"\n)]\n#[fundamental] // so that regex can rely that `&str: !FnMut`\n#[must_use = \"closures are lazy and do nothing unless called\"]\n#[rustc_const_unstable(feature = \"const_trait_impl\", issue = \"143874\")]\npub const trait FnMut<Args: Tuple>: FnOnce<Args> {\n    /// Performs the call operation.\n    #[unstable(feature = \"fn_traits\", issue = \"29625\")]\n    extern \"rust-call\" fn call_mut(&mut self, args: Args) -> Self::Output;\n}\n\n/// The version of the call operator that takes a by-value receiver.\n///\n/// Instances of `FnOnce` can be called, but might not be callable multiple\n/// times. Because of this, if the only thing known about a type is that it\n/// implements `FnOnce`, it can only be called once.\n///\n/// `FnOnce` is implemented automatically by closures that might consume captured\n/// variables, as well as all types that implement [`FnMut`], e.g., (safe)\n/// [function pointers] (since `FnOnce` is a supertrait of [`FnMut`]).\n///\n/// Since both [`Fn`] and [`FnMut`] are subtraits of `FnOnce`, any instance of\n/// [`Fn`] or [`FnMut`] can be used where a `FnOnce` is expected.\n///\n/// Use `FnOnce` as a bound when you want to accept a parameter of function-like\n/// type and only need to call it once. If you need to call the parameter\n/// repeatedly, use [`FnMut`] as a bound; if you also need it to not mutate\n/// state, use [`Fn`].\n///\n/// See the [chapter on closures in *The Rust Programming Language*][book] for\n/// some more information on this topic.\n///\n/// Also of note is the special syntax for `Fn` traits (e.g.\n/// `Fn(usize, bool) -> usize`). Those interested in the technical details of\n/// this can refer to [the relevant section in the *Rustonomicon*][nomicon].\n///\n/// [book]: ../../book/ch13-01-closures.html\n/// [function pointers]: fn\n/// [nomicon]: ../../nomicon/hrtb.html\n///\n/// # Examples\n///\n/// ## Using a `FnOnce` parameter\n///\n/// ```\n/// fn consume_with_relish<F>(func: F)\n///     where F: FnOnce() -> String\n/// {\n///     // `func` consumes its captured variables, so it cannot be run more\n///     // than once.\n///     println!(\"Consumed: {}\", func());\n///\n///     println!(\"Delicious!\");\n///\n///     // Attempting to invoke `func()` again will throw a `use of moved\n///     // value` error for `func`.\n/// }\n///\n/// let x = String::from(\"x\");\n/// let consume_and_return_x = move || x;\n/// consume_with_relish(consume_and_return_x);\n///\n/// // `consume_and_return_x` can no longer be invoked at this point\n/// ```\n#[lang = \"fn_once\"]\n#[stable(feature = \"rust1\", since = \"1.0.0\")]\n#[rustc_paren_sugar]\n#[rustc_on_unimplemented(\n    on(\n        Args = \"()\",\n        note = \"wrap the `{Self}` in a closure with no arguments: `|| {{ /* code */ }}`\"\n    ),\n    on(\n        Self = \"unsafe fn\",\n        note = \"unsafe function cannot be called generically without an unsafe block\",\n        // SAFETY: tidy is not smart enough to tell that the below unsafe block is a string\n        label = \"call the function in a closure: `|| unsafe {{ /* code */ }}`\"\n    ),\n    message = \"expected a `{This:resolved}` closure, found `{Self}`\",\n    label = \"expected an `{This:resolved}` closure, found `{Self}`\"\n)]\n#[fundamental] // so that regex can rely that `&str: !FnMut`\n#[must_use = \"closures are lazy and do nothing unless called\"]\n#[rustc_const_unstable(feature = \"const_trait_impl\", issue = \"143874\")]\npub const trait FnOnce<Args: Tuple> {\n    /// The returned type after the call operator is used.\n    #[lang = \"fn_once_output\"]\n    #[stable(feature = \"fn_once_output\", since = \"1.12.0\")]\n    type Output;\n\n    /// Performs the call operation.\n    #[unstable(feature = \"fn_traits\", issue = \"29625\")]\n    extern \"rust-call\" fn call_once(self, args: Args) -> Self::Output;\n}\n\nmod impls {\n    use crate::marker::Tuple;\n\n    #[stable(feature = \"rust1\", since = \"1.0.0\")]\n    #[rustc_const_unstable(feature = \"const_trait_impl\", issue = \"143874\")]\n    const impl<A: Tuple, F: ?Sized> Fn<A> for &F\n    where\n        F: [const] Fn<A>,\n    {\n        extern \"rust-call\" fn call(&self, args: A) -> F::Output {\n            (**self).call(args)\n        }\n    }\n\n    #[stable(feature = \"rust1\", since = \"1.0.0\")]\n    #[rustc_const_unstable(feature = \"const_trait_impl\", issue = \"143874\")]\n    const impl<A: Tuple, F: ?Sized> FnMut<A> for &F\n    where\n        F: [const] Fn<A>,\n    {\n        extern \"rust-call\" fn call_mut(&mut self, args: A) -> F::Output {\n            (**self).call(args)\n        }\n    }\n\n    #[stable(feature = \"rust1\", since = \"1.0.0\")]\n    #[rustc_const_unstable(feature = \"const_trait_impl\", issue = \"143874\")]\n    const impl<A: Tuple, F: ?Sized> FnOnce<A> for &F\n    where\n        F: [const] Fn<A>,\n    {\n        type Output = F::Output;\n\n        extern \"rust-call\" fn call_once(self, args: A) -> F::Output {\n            (*self).call(args)\n        }\n    }\n\n    #[stable(feature = \"rust1\", since = \"1.0.0\")]\n    #[rustc_const_unstable(feature = \"const_trait_impl\", issue = \"143874\")]\n    const impl<A: Tuple, F: ?Sized> FnMut<A> for &mut F\n    where\n        F: [const] FnMut<A>,\n    {\n        extern \"rust-call\" fn call_mut(&mut self, args: A) -> F::Output {\n            (*self).call_mut(args)\n        }\n    }\n\n    #[stable(feature = \"rust1\", since = \"1.0.0\")]\n    #[rustc_const_unstable(feature = \"const_trait_impl\", issue = \"143874\")]\n    const impl<A: Tuple, F: ?Sized> FnOnce<A> for &mut F\n    where\n        F: [const] FnMut<A>,\n    {\n        type Output = F::Output;\n        extern \"rust-call\" fn call_once(self, args: A) -> F::Output {\n            (*self).call_mut(args)\n        }\n    }\n}\n",
    "common.rs": "#[cfg(all(test, not(target_os = \"emscripten\")))]\nmod tests;\n\nuse libc::{EXIT_FAILURE, EXIT_SUCCESS, c_int, gid_t, pid_t, uid_t};\n\npub use self::cstring_array::CStringArray;\nuse self::cstring_array::CStringIter;\nuse crate::collections::BTreeMap;\nuse crate::ffi::{CStr, CString, OsStr, OsString};\nuse crate::os::unix::prelude::*;\nuse crate::path::Path;\nuse crate::process::StdioPipes;\nuse crate::sys::fd::FileDesc;\nuse crate::sys::fs::File;\n#[cfg(not(target_os = \"fuchsia\"))]\nuse crate::sys::fs::OpenOptions;\nuse crate::sys::pipe::pipe;\nuse crate::sys::process::env::{CommandEnv, CommandEnvs, CommandResolvedEnvs};\nuse crate::sys::{FromInner, IntoInner, cvt_r};\nuse crate::{fmt, io, mem};\n\nmod cstring_array;\n\ncfg_select! {\n    target_os = \"fuchsia\" => {\n        // fuchsia doesn't have /dev/null\n    }\n    target_os = \"vxworks\" => {\n        const DEV_NULL: &CStr = c\"/null\";\n    }\n    _ => {\n        const DEV_NULL: &CStr = c\"/dev/null\";\n    }\n}\n\n// Android with api less than 21 define sig* functions inline, so it is not\n// available for dynamic link. Implementing sigemptyset and sigaddset allow us\n// to support older Android version (independent of libc version).\n// The following implementations are based on\n// https://github.com/aosp-mirror/platform_bionic/blob/ad8dcd6023294b646e5a8288c0ed431b0845da49/libc/include/android/legacy_signal_inlines.h\ncfg_select! {\n    target_os = \"android\" => {\n        #[allow(dead_code)]\n        pub unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {\n            set.write_bytes(0u8, 1);\n            return 0;\n        }\n\n        #[allow(dead_code)]\n        pub unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {\n            use crate::slice;\n            use libc::{c_ulong, sigset_t};\n\n            // The implementations from bionic (android libc) type pun `sigset_t` as an\n            // array of `c_ulong`. This works, but lets add a smoke check to make sure\n            // that doesn't change.\n            const _: () = assert!(\n                align_of::<c_ulong>() == align_of::<sigset_t>()\n                    && (size_of::<sigset_t>() % size_of::<c_ulong>()) == 0\n            );\n\n            let bit = (signum - 1) as usize;\n            if set.is_null() || bit >= (8 * size_of::<sigset_t>()) {\n                crate::sys::io::set_errno(libc::EINVAL);\n                return -1;\n            }\n            let raw = slice::from_raw_parts_mut(\n                set as *mut c_ulong,\n                size_of::<sigset_t>() / size_of::<c_ulong>(),\n            );\n            const LONG_BIT: usize = size_of::<c_ulong>() * 8;\n            raw[bit / LONG_BIT] |= 1 << (bit % LONG_BIT);\n            return 0;\n        }\n    }\n    _ => {\n        #[allow(unused_imports)]\n        pub use libc::{sigemptyset, sigaddset};\n    }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Command\n////////////////////////////////////////////////////////////////////////////////\n\npub struct Command {\n    program: CString,\n    args: CStringArray,\n    env: CommandEnv,\n\n    program_kind: ProgramKind,\n    cwd: Option<CString>,\n    chroot: Option<CString>,\n    uid: Option<uid_t>,\n    gid: Option<gid_t>,\n    saw_nul: bool,\n    closures: Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>>,\n    groups: Option<Box<[gid_t]>>,\n    stdin: Option<Stdio>,\n    stdout: Option<Stdio>,\n    stderr: Option<Stdio>,\n    #[cfg(target_os = \"linux\")]\n    create_pidfd: bool,\n    pgroup: Option<pid_t>,\n    setsid: bool,\n}\n\n// passed to do_exec() with configuration of what the child stdio should look\n// like\n#[cfg_attr(target_os = \"vita\", allow(dead_code))]\npub struct ChildPipes {\n    pub stdin: ChildStdio,\n    pub stdout: ChildStdio,\n    pub stderr: ChildStdio,\n}\n\npub enum ChildStdio {\n    Inherit,\n    Explicit(c_int),\n    Owned(FileDesc),\n\n    // On Fuchsia, null stdio is the default, so we simply don't specify\n    // any actions at the time of spawning.\n    #[cfg(target_os = \"fuchsia\")]\n    Null,\n}\n\n#[derive(Debug)]\npub enum Stdio {\n    Inherit,\n    Null,\n    MakePipe,\n    Fd(FileDesc),\n    StaticFd(BorrowedFd<'static>),\n}\n\n#[derive(Copy, Clone, Debug, Eq, PartialEq)]\npub enum ProgramKind {\n    /// A program that would be looked up on the PATH (e.g. `ls`)\n    PathLookup,\n    /// A relative path (e.g. `my-dir/foo`, `../foo`, `./foo`)\n    Relative,\n    /// An absolute path.\n    Absolute,\n}\n\nimpl ProgramKind {\n    fn new(program: &OsStr) -> Self {\n        if program.as_encoded_bytes().starts_with(b\"/\") {\n            Self::Absolute\n        } else if program.as_encoded_bytes().contains(&b'/') {\n            // If the program has more than one component in it, it is a relative path.\n            Self::Relative\n        } else {\n            Self::PathLookup\n        }\n    }\n}\n\nimpl Command {\n    pub fn new(program: &OsStr) -> Command {\n        let mut saw_nul = false;\n        let program_kind = ProgramKind::new(program.as_ref());\n        let program = os2c(program, &mut saw_nul);\n        let mut args = CStringArray::with_capacity(1);\n        args.push(program.clone());\n        Command {\n            program,\n            args,\n            env: Default::default(),\n            program_kind,\n            cwd: None,\n            chroot: None,\n            uid: None,\n            gid: None,\n            saw_nul,\n            closures: Vec::new(),\n            groups: None,\n            stdin: None,\n            stdout: None,\n            stderr: None,\n            #[cfg(target_os = \"linux\")]\n            create_pidfd: false,\n            pgroup: None,\n            setsid: false,\n        }\n    }\n\n    pub fn set_arg_0(&mut self, arg: &OsStr) {\n        // Set a new arg0\n        let arg = os2c(arg, &mut self.saw_nul);\n        self.args.write(0, arg);\n    }\n\n    pub fn arg(&mut self, arg: &OsStr) {\n        let arg = os2c(arg, &mut self.saw_nul);\n        self.args.push(arg);\n    }\n\n    pub fn cwd(&mut self, dir: &OsStr) {\n        self.cwd = Some(os2c(dir, &mut self.saw_nul));\n    }\n    pub fn uid(&mut self, id: uid_t) {\n        self.uid = Some(id);\n    }\n    pub fn gid(&mut self, id: gid_t) {\n        self.gid = Some(id);\n    }\n    pub fn groups(&mut self, groups: &[gid_t]) {\n        self.groups = Some(Box::from(groups));\n    }\n    pub fn pgroup(&mut self, pgroup: pid_t) {\n        self.pgroup = Some(pgroup);\n    }\n    pub fn chroot(&mut self, dir: &Path) {\n        self.chroot = Some(os2c(dir.as_os_str(), &mut self.saw_nul));\n        if self.cwd.is_none() {\n            self.cwd(&OsStr::new(\"/\"));\n        }\n    }\n    pub fn setsid(&mut self, setsid: bool) {\n        self.setsid = setsid;\n    }\n\n    #[cfg(target_os = \"linux\")]\n    pub fn create_pidfd(&mut self, val: bool) {\n        self.create_pidfd = val;\n    }\n\n    #[cfg(not(target_os = \"linux\"))]\n    #[allow(dead_code)]\n    pub fn get_create_pidfd(&self) -> bool {\n        false\n    }\n\n    #[cfg(target_os = \"linux\")]\n    pub fn get_create_pidfd(&self) -> bool {\n        self.create_pidfd\n    }\n\n    pub fn saw_nul(&self) -> bool {\n        self.saw_nul\n    }\n\n    pub fn get_program(&self) -> &OsStr {\n        OsStr::from_bytes(self.program.as_bytes())\n    }\n\n    #[allow(dead_code)]\n    pub fn get_program_kind(&self) -> ProgramKind {\n        self.program_kind\n    }\n\n    pub fn get_args(&self) -> CommandArgs<'_> {\n        let mut iter = self.args.iter();\n        // argv[0] contains the program name, but we are only interested in the\n        // arguments so skip it.\n        iter.next();\n        CommandArgs { iter }\n    }\n\n    pub fn get_envs(&self) -> CommandEnvs<'_> {\n        self.env.iter()\n    }\n\n    pub fn get_env_clear(&self) -> bool {\n        self.env.does_clear()\n    }\n\n    pub fn get_resolved_envs(&self) -> CommandResolvedEnvs {\n        CommandResolvedEnvs::new(self.env.capture())\n    }\n\n    pub fn get_current_dir(&self) -> Option<&Path> {\n        self.cwd.as_ref().map(|cs| Path::new(OsStr::from_bytes(cs.as_bytes())))\n    }\n\n    pub fn get_argv(&self) -> &CStringArray {\n        &self.args\n    }\n\n    pub fn get_program_cstr(&self) -> &CStr {\n        &self.program\n    }\n\n    #[allow(dead_code)]\n    pub fn get_cwd(&self) -> Option<&CStr> {\n        self.cwd.as_deref()\n    }\n    #[allow(dead_code)]\n    pub fn get_uid(&self) -> Option<uid_t> {\n        self.uid\n    }\n    #[allow(dead_code)]\n    pub fn get_gid(&self) -> Option<gid_t> {\n        self.gid\n    }\n    #[allow(dead_code)]\n    pub fn get_groups(&self) -> Option<&[gid_t]> {\n        self.groups.as_deref()\n    }\n    #[allow(dead_code)]\n    pub fn get_pgroup(&self) -> Option<pid_t> {\n        self.pgroup\n    }\n    #[allow(dead_code)]\n    pub fn get_chroot(&self) -> Option<&CStr> {\n        self.chroot.as_deref()\n    }\n    #[allow(dead_code)]\n    pub fn get_setsid(&self) -> bool {\n        self.setsid\n    }\n\n    pub fn get_closures(&mut self) -> &mut Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>> {\n        &mut self.closures\n    }\n\n    pub unsafe fn pre_exec(&mut self, f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>) {\n        self.closures.push(f);\n    }\n\n    pub fn stdin(&mut self, stdin: Stdio) {\n        self.stdin = Some(stdin);\n    }\n\n    pub fn stdout(&mut self, stdout: Stdio) {\n        self.stdout = Some(stdout);\n    }\n\n    pub fn stderr(&mut self, stderr: Stdio) {\n        self.stderr = Some(stderr);\n    }\n\n    pub fn env_mut(&mut self) -> &mut CommandEnv {\n        &mut self.env\n    }\n\n    pub fn capture_env(&mut self) -> Option<CStringArray> {\n        let maybe_env = self.env.capture_if_changed();\n        maybe_env.map(|env| construct_envp(env, &mut self.saw_nul))\n    }\n\n    #[allow(dead_code)]\n    pub fn env_saw_path(&self) -> bool {\n        self.env.have_changed_path()\n    }\n\n    #[allow(dead_code)]\n    pub fn program_is_path(&self) -> bool {\n        self.program.to_bytes().contains(&b'/')\n    }\n\n    pub fn setup_io(\n        &self,\n        default: Stdio,\n        needs_stdin: bool,\n    ) -> io::Result<(StdioPipes, ChildPipes)> {\n        let null = Stdio::Null;\n        let default_stdin = if needs_stdin { &default } else { &null };\n        let stdin = self.stdin.as_ref().unwrap_or(default_stdin);\n        let stdout = self.stdout.as_ref().unwrap_or(&default);\n        let stderr = self.stderr.as_ref().unwrap_or(&default);\n        let (their_stdin, our_stdin) = stdin.to_child_stdio(true)?;\n        let (their_stdout, our_stdout) = stdout.to_child_stdio(false)?;\n        let (their_stderr, our_stderr) = stderr.to_child_stdio(false)?;\n        let ours = StdioPipes { stdin: our_stdin, stdout: our_stdout, stderr: our_stderr };\n        let theirs = ChildPipes { stdin: their_stdin, stdout: their_stdout, stderr: their_stderr };\n        Ok((ours, theirs))\n    }\n}\n\nfn os2c(s: &OsStr, saw_nul: &mut bool) -> CString {\n    CString::new(s.as_bytes()).unwrap_or_else(|_e| {\n        *saw_nul = true;\n        c\"<string-with-nul>\".to_owned()\n    })\n}\n\nfn construct_envp(env: BTreeMap<OsString, OsString>, saw_nul: &mut bool) -> CStringArray {\n    let mut result = CStringArray::with_capacity(env.len());\n    for (mut k, v) in env {\n        // Reserve additional space for '=' and null terminator\n        k.reserve_exact(v.len() + 2);\n        k.push(\"=\");\n        k.push(&v);\n\n        // Add the new entry into the array\n        if let Ok(item) = CString::new(k.into_vec()) {\n            result.push(item);\n        } else {\n            *saw_nul = true;\n        }\n    }\n\n    result\n}\n\nimpl Stdio {\n    pub fn to_child_stdio(&self, readable: bool) -> io::Result<(ChildStdio, Option<ChildPipe>)> {\n        match *self {\n            Stdio::Inherit => Ok((ChildStdio::Inherit, None)),\n\n            // Make sure that the source descriptors are not an stdio\n            // descriptor, otherwise the order which we set the child's\n            // descriptors may blow away a descriptor which we are hoping to\n            // save. For example, suppose we want the child's stderr to be the\n            // parent's stdout, and the child's stdout to be the parent's\n            // stderr. No matter which we dup first, the second will get\n            // overwritten prematurely.\n            Stdio::Fd(ref fd) => {\n                if fd.as_raw_fd() >= 0 && fd.as_raw_fd() <= libc::STDERR_FILENO {\n                    Ok((ChildStdio::Owned(fd.duplicate()?), None))\n                } else {\n                    Ok((ChildStdio::Explicit(fd.as_raw_fd()), None))\n                }\n            }\n\n            Stdio::StaticFd(fd) => {\n                let fd = FileDesc::from_inner(fd.try_clone_to_owned()?);\n                Ok((ChildStdio::Owned(fd), None))\n            }\n\n            Stdio::MakePipe => {\n                let (reader, writer) = pipe()?;\n                let (ours, theirs) = if readable { (writer, reader) } else { (reader, writer) };\n                Ok((ChildStdio::Owned(theirs), Some(ours)))\n            }\n\n            #[cfg(not(target_os = \"fuchsia\"))]\n            Stdio::Null => {\n                let mut opts = OpenOptions::new();\n                opts.read(readable);\n                opts.write(!readable);\n                let fd = File::open_c(DEV_NULL, &opts)?;\n                Ok((ChildStdio::Owned(fd.into_inner()), None))\n            }\n\n            #[cfg(target_os = \"fuchsia\")]\n            Stdio::Null => Ok((ChildStdio::Null, None)),\n        }\n    }\n}\n\nimpl From<FileDesc> for Stdio {\n    fn from(fd: FileDesc) -> Stdio {\n        Stdio::Fd(fd)\n    }\n}\n\nimpl From<File> for Stdio {\n    fn from(file: File) -> Stdio {\n        Stdio::Fd(file.into_inner())\n    }\n}\n\nimpl From<io::Stdout> for Stdio {\n    fn from(_: io::Stdout) -> Stdio {\n        // This ought really to be is Stdio::StaticFd(input_argument.as_fd()).\n        // But AsFd::as_fd takes its argument by reference, and yields\n        // a bounded lifetime, so it's no use here. There is no AsStaticFd.\n        //\n        // Additionally AsFd is only implemented for the *locked* versions.\n        // We don't want to lock them here.  (The implications of not locking\n        // are the same as those for process::Stdio::inherit().)\n        //\n        // Arguably the hypothetical AsStaticFd and AsFd<'static>\n        // should be implemented for io::Stdout, not just for StdoutLocked.\n        Stdio::StaticFd(unsafe { BorrowedFd::borrow_raw(libc::STDOUT_FILENO) })\n    }\n}\n\nimpl From<io::Stderr> for Stdio {\n    fn from(_: io::Stderr) -> Stdio {\n        Stdio::StaticFd(unsafe { BorrowedFd::borrow_raw(libc::STDERR_FILENO) })\n    }\n}\n\nimpl ChildStdio {\n    pub fn fd(&self) -> Option<c_int> {\n        match *self {\n            ChildStdio::Inherit => None,\n            ChildStdio::Explicit(fd) => Some(fd),\n            ChildStdio::Owned(ref fd) => Some(fd.as_raw_fd()),\n\n            #[cfg(target_os = \"fuchsia\")]\n            ChildStdio::Null => None,\n        }\n    }\n}\n\nimpl fmt::Debug for Command {\n    // show all attributes but `self.closures` which does not implement `Debug`\n    // and `self.argv` which is not useful for debugging\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        if f.alternate() {\n            let mut debug_command = f.debug_struct(\"Command\");\n            debug_command.field(\"program\", &self.program).field(\"args\", &self.args);\n            if !self.env.is_unchanged() {\n                debug_command.field(\"env\", &self.env);\n            }\n\n            if self.cwd.is_some() {\n                debug_command.field(\"cwd\", &self.cwd);\n            }\n            if self.uid.is_some() {\n                debug_command.field(\"uid\", &self.uid);\n            }\n            if self.gid.is_some() {\n                debug_command.field(\"gid\", &self.gid);\n            }\n\n            if self.groups.is_some() {\n                debug_command.field(\"groups\", &self.groups);\n            }\n\n            if self.stdin.is_some() {\n                debug_command.field(\"stdin\", &self.stdin);\n            }\n            if self.stdout.is_some() {\n                debug_command.field(\"stdout\", &self.stdout);\n            }\n            if self.stderr.is_some() {\n                debug_command.field(\"stderr\", &self.stderr);\n            }\n            if self.pgroup.is_some() {\n                debug_command.field(\"pgroup\", &self.pgroup);\n            }\n\n            #[cfg(target_os = \"linux\")]\n            {\n                debug_command.field(\"create_pidfd\", &self.create_pidfd);\n            }\n\n            debug_command.finish()\n        } else {\n            if let Some(ref cwd) = self.cwd {\n                write!(f, \"cd {cwd:?} && \")?;\n            }\n            if self.env.does_clear() {\n                write!(f, \"env -i \")?;\n                // Altered env vars will be printed next, that should exactly work as expected.\n            } else {\n                // Removed env vars need the command to be wrapped in `env`.\n                let mut any_removed = false;\n                for (key, value_opt) in self.get_envs() {\n                    if value_opt.is_none() {\n                        if !any_removed {\n                            write!(f, \"env \")?;\n                            any_removed = true;\n                        }\n                        write!(f, \"-u {} \", key.to_string_lossy())?;\n                    }\n                }\n            }\n            // Altered env vars can just be added in front of the program.\n            for (key, value_opt) in self.get_envs() {\n                if let Some(value) = value_opt {\n                    write!(f, \"{}={value:?} \", key.to_string_lossy())?;\n                }\n            }\n\n            if *self.program != self.args[0] {\n                write!(f, \"[{:?}] \", self.program)?;\n            }\n            write!(f, \"{:?}\", &self.args[0])?;\n\n            for arg in self.get_args() {\n                write!(f, \" {:?}\", arg)?;\n            }\n\n            Ok(())\n        }\n    }\n}\n\n#[derive(PartialEq, Eq, Clone, Copy)]\npub struct ExitCode(u8);\n\nimpl fmt::Debug for ExitCode {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_tuple(\"unix_exit_status\").field(&self.0).finish()\n    }\n}\n\nimpl ExitCode {\n    pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _);\n    pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _);\n\n    #[inline]\n    pub fn as_i32(&self) -> i32 {\n        self.0 as i32\n    }\n}\n\nimpl From<u8> for ExitCode {\n    fn from(code: u8) -> Self {\n        Self(code)\n    }\n}\n\npub struct CommandArgs<'a> {\n    iter: CStringIter<'a>,\n}\n\nimpl<'a> Iterator for CommandArgs<'a> {\n    type Item = &'a OsStr;\n\n    fn next(&mut self) -> Option<&'a OsStr> {\n        self.iter.next().map(|cs| OsStr::from_bytes(cs.to_bytes()))\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.iter.size_hint()\n    }\n}\n\nimpl<'a> ExactSizeIterator for CommandArgs<'a> {\n    fn len(&self) -> usize {\n        self.iter.len()\n    }\n\n    fn is_empty(&self) -> bool {\n        self.iter.is_empty()\n    }\n}\n\nimpl<'a> fmt::Debug for CommandArgs<'a> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_list().entries(self.iter.clone()).finish()\n    }\n}\n\npub type ChildPipe = crate::sys::pipe::Pipe;\n\npub fn read_output(\n    out: ChildPipe,\n    stdout: &mut Vec<u8>,\n    err: ChildPipe,\n    stderr: &mut Vec<u8>,\n) -> io::Result<()> {\n    // Set both pipes into nonblocking mode as we're gonna be reading from both\n    // in the `select` loop below, and we wouldn't want one to block the other!\n    out.set_nonblocking(true)?;\n    err.set_nonblocking(true)?;\n\n    let mut fds: [libc::pollfd; 2] = unsafe { mem::zeroed() };\n    fds[0].fd = out.as_raw_fd();\n    fds[0].events = libc::POLLIN;\n    fds[1].fd = err.as_raw_fd();\n    fds[1].events = libc::POLLIN;\n    loop {\n        // wait for either pipe to become readable using `poll`\n        cvt_r(|| unsafe { libc::poll(fds.as_mut_ptr(), 2, -1) })?;\n\n        if fds[0].revents != 0 && read(&out, stdout)? {\n            err.set_nonblocking(false)?;\n            return err.read_to_end(stderr).map(drop);\n        }\n        if fds[1].revents != 0 && read(&err, stderr)? {\n            out.set_nonblocking(false)?;\n            return out.read_to_end(stdout).map(drop);\n        }\n    }\n\n    // Read as much as we can from each pipe, ignoring EWOULDBLOCK or\n    // EAGAIN. If we hit EOF, then this will happen because the underlying\n    // reader will return Ok(0), in which case we'll see `Ok` ourselves. In\n    // this case we flip the other fd back into blocking mode and read\n    // whatever's leftover on that file descriptor.\n    fn read(fd: &FileDesc, dst: &mut Vec<u8>) -> Result<bool, io::Error> {\n        match fd.read_to_end(dst) {\n            Ok(_) => Ok(true),\n            Err(e) => {\n                if e.raw_os_error() == Some(libc::EWOULDBLOCK)\n                    || e.raw_os_error() == Some(libc::EAGAIN)\n                {\n                    Ok(false)\n                } else {\n                    Err(e)\n                }\n            }\n        }\n    }\n}\n\npub fn getpid() -> u32 {\n    unsafe { libc::getpid() as u32 }\n}\n\npub fn getppid() -> u32 {\n    unsafe { libc::getppid() as u32 }\n}\n",
    "process.rs": "//! A module for working with processes.\n//!\n//! This module is mostly concerned with spawning and interacting with child\n//! processes, but it also provides [`abort`] and [`exit`] for terminating the\n//! current process.\n//!\n//! # Spawning a process\n//!\n//! The [`Command`] struct is used to configure and spawn processes:\n//!\n//! ```no_run\n//! use std::process::Command;\n//!\n//! let output = Command::new(\"echo\")\n//!     .arg(\"Hello world\")\n//!     .output()\n//!     .expect(\"Failed to execute command\");\n//!\n//! assert_eq!(b\"Hello world\\n\", output.stdout.as_slice());\n//! ```\n//!\n//! Several methods on [`Command`], such as [`spawn`] or [`output`], can be used\n//! to spawn a process. In particular, [`output`] spawns the child process and\n//! waits until the process terminates, while [`spawn`] will return a [`Child`]\n//! that represents the spawned child process.\n//!\n//! # Handling I/O\n//!\n//! The [`stdout`], [`stdin`], and [`stderr`] of a child process can be\n//! configured by passing an [`Stdio`] to the corresponding method on\n//! [`Command`]. Once spawned, they can be accessed from the [`Child`]. For\n//! example, piping output from one command into another command can be done\n//! like so:\n//!\n//! ```no_run\n//! use std::process::{Command, Stdio};\n//!\n//! // stdout must be configured with `Stdio::piped` in order to use\n//! // `echo_child.stdout`\n//! let echo_child = Command::new(\"echo\")\n//!     .arg(\"Oh no, a tpyo!\")\n//!     .stdout(Stdio::piped())\n//!     .spawn()\n//!     .expect(\"Failed to start echo process\");\n//!\n//! // Note that `echo_child` is moved here, but we won't be needing\n//! // `echo_child` anymore\n//! let echo_out = echo_child.stdout.expect(\"Failed to open echo stdout\");\n//!\n//! let mut sed_child = Command::new(\"sed\")\n//!     .arg(\"s/tpyo/typo/\")\n//!     .stdin(Stdio::from(echo_out))\n//!     .stdout(Stdio::piped())\n//!     .spawn()\n//!     .expect(\"Failed to start sed process\");\n//!\n//! let output = sed_child.wait_with_output().expect(\"Failed to wait on sed\");\n//! assert_eq!(b\"Oh no, a typo!\\n\", output.stdout.as_slice());\n//! ```\n//!\n//! Note that [`ChildStderr`] and [`ChildStdout`] implement [`Read`] and\n//! [`ChildStdin`] implements [`Write`]:\n//!\n//! ```no_run\n//! use std::process::{Command, Stdio};\n//! use std::io::Write;\n//!\n//! let mut child = Command::new(\"/bin/cat\")\n//!     .stdin(Stdio::piped())\n//!     .stdout(Stdio::piped())\n//!     .spawn()\n//!     .expect(\"failed to execute child\");\n//!\n//! // If the child process fills its stdout buffer, it may end up\n//! // waiting until the parent reads the stdout, and not be able to\n//! // read stdin in the meantime, causing a deadlock.\n//! // Writing from another thread ensures that stdout is being read\n//! // at the same time, avoiding the problem.\n//! let mut stdin = child.stdin.take().expect(\"failed to get stdin\");\n//! std::thread::spawn(move || {\n//!     stdin.write_all(b\"test\").expect(\"failed to write to stdin\");\n//! });\n//!\n//! let output = child\n//!     .wait_with_output()\n//!     .expect(\"failed to wait on child\");\n//!\n//! assert_eq!(b\"test\", output.stdout.as_slice());\n//! ```\n//!\n//! # Windows argument splitting\n//!\n//! On Unix systems arguments are passed to a new process as an array of strings,\n//! but on Windows arguments are passed as a single commandline string and it is\n//! up to the child process to parse it into an array. Therefore the parent and\n//! child processes must agree on how the commandline string is encoded.\n//!\n//! Most programs use the standard C run-time `argv`, which in practice results\n//! in consistent argument handling. However, some programs have their own way of\n//! parsing the commandline string. In these cases using [`arg`] or [`args`] may\n//! result in the child process seeing a different array of arguments than the\n//! parent process intended.\n//!\n//! Two ways of mitigating this are:\n//!\n//! * Validate untrusted input so that only a safe subset is allowed.\n//! * Use [`raw_arg`] to build a custom commandline. This bypasses the escaping\n//!   rules used by [`arg`] so should be used with due caution.\n//!\n//! `cmd.exe` and `.bat` files use non-standard argument parsing and are especially\n//! vulnerable to malicious input as they may be used to run arbitrary shell\n//! commands. Untrusted arguments should be restricted as much as possible.\n//! For examples on handling this see [`raw_arg`].\n//!\n//! ### Batch file special handling\n//!\n//! On Windows, `Command` uses the Windows API function [`CreateProcessW`] to\n//! spawn new processes. An undocumented feature of this function is that\n//! when given a `.bat` file as the application to run, it will automatically\n//! convert that into running `cmd.exe /c` with the batch file as the next argument.\n//!\n//! For historical reasons Rust currently preserves this behavior when using\n//! [`Command::new`], and escapes the arguments according to `cmd.exe` rules.\n//! Due to the complexity of `cmd.exe` argument handling, it might not be\n//! possible to safely escape some special characters, and using them will result\n//! in an error being returned at process spawn. The set of unescapeable\n//! special characters might change between releases.\n//!\n//! Also note that running batch scripts in this way may be removed in the\n//! future and so should not be relied upon.\n//!\n//! [`spawn`]: Command::spawn\n//! [`output`]: Command::output\n//!\n//! [`stdout`]: Command::stdout\n//! [`stdin`]: Command::stdin\n//! [`stderr`]: Command::stderr\n//!\n//! [`Write`]: io::Write\n//! [`Read`]: io::Read\n//!\n//! [`arg`]: Command::arg\n//! [`args`]: Command::args\n//! [`raw_arg`]: crate::os::windows::process::CommandExt::raw_arg\n//!\n//! [`CreateProcessW`]: https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw\n\n#![stable(feature = \"process\", since = \"1.0.0\")]\n#![deny(unsafe_op_in_unsafe_fn)]\n\n#[cfg(all(\n    test,\n    not(any(\n        target_os = \"emscripten\",\n        target_os = \"wasi\",\n        target_env = \"sgx\",\n        target_os = \"xous\",\n        target_os = \"trusty\",\n        target_os = \"hermit\",\n    ))\n))]\nmod tests;\n\nuse crate::convert::Infallible;\nuse crate::ffi::OsStr;\nuse crate::io::prelude::*;\nuse crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};\nuse crate::num::NonZero;\nuse crate::path::Path;\nuse crate::sys::{AsInner, AsInnerMut, FromInner, IntoInner, process as imp};\nuse crate::{fmt, format_args_nl, fs, str};\n\n/// Representation of a running or exited child process.\n///\n/// This structure is used to represent and manage child processes. A child\n/// process is created via the [`Command`] struct, which configures the\n/// spawning process and can itself be constructed using a builder-style\n/// interface.\n///\n/// There is no implementation of [`Drop`] for child processes,\n/// so if you do not ensure the `Child` has exited then it will continue to\n/// run, even after the `Child` handle to the child process has gone out of\n/// scope.\n///\n/// Calling [`wait`] (or other functions that wrap around it) will make\n/// the parent process wait until the child has actually exited before\n/// continuing.\n///\n/// # Warning\n///\n/// On some systems, calling [`wait`] or similar is necessary for the OS to\n/// release resources. A process that terminated but has not been waited on is\n/// still around as a \"zombie\". Leaving too many zombies around may exhaust\n/// global resources (for example process IDs).\n///\n/// The standard library does *not* automatically wait on child processes (not\n/// even if the `Child` is dropped), it is up to the application developer to do\n/// so. As a consequence, dropping `Child` handles without waiting on them first\n/// is not recommended in long-running applications.\n///\n/// # Examples\n///\n/// ```should_panic\n/// use std::process::Command;\n///\n/// let mut child = Command::new(\"/bin/cat\")\n///     .arg(\"file.txt\")\n///     .spawn()\n///     .expect(\"failed to execute child\");\n///\n/// let ecode = child.wait().expect(\"failed to wait on child\");\n///\n/// assert!(ecode.success());\n/// ```\n///\n/// [`wait`]: Child::wait\n#[stable(feature = \"process\", since = \"1.0.0\")]\n#[cfg_attr(not(test), rustc_diagnostic_item = \"Child\")]\npub struct Child {\n    pub(crate) handle: imp::Process,\n\n    /// The handle for writing to the child's standard input (stdin), if it\n    /// has been captured. You might find it helpful to do\n    ///\n    /// ```ignore (incomplete)\n    /// let stdin = child.stdin.take().expect(\"handle present\");\n    /// ```\n    ///\n    /// to avoid partially moving the `child` and thus blocking yourself from calling\n    /// functions on `child` while using `stdin`.\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub stdin: Option<ChildStdin>,\n\n    /// The handle for reading from the child's standard output (stdout), if it\n    /// has been captured. You might find it helpful to do\n    ///\n    /// ```ignore (incomplete)\n    /// let stdout = child.stdout.take().expect(\"handle present\");\n    /// ```\n    ///\n    /// to avoid partially moving the `child` and thus blocking yourself from calling\n    /// functions on `child` while using `stdout`.\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub stdout: Option<ChildStdout>,\n\n    /// The handle for reading from the child's standard error (stderr), if it\n    /// has been captured. You might find it helpful to do\n    ///\n    /// ```ignore (incomplete)\n    /// let stderr = child.stderr.take().expect(\"handle present\");\n    /// ```\n    ///\n    /// to avoid partially moving the `child` and thus blocking yourself from calling\n    /// functions on `child` while using `stderr`.\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub stderr: Option<ChildStderr>,\n}\n\nimpl AsInner<imp::Process> for Child {\n    #[inline]\n    fn as_inner(&self) -> &imp::Process {\n        &self.handle\n    }\n}\n\nimpl FromInner<(imp::Process, StdioPipes)> for Child {\n    fn from_inner((handle, io): (imp::Process, StdioPipes)) -> Child {\n        Child {\n            handle,\n            stdin: io.stdin.map(ChildStdin::from_inner),\n            stdout: io.stdout.map(ChildStdout::from_inner),\n            stderr: io.stderr.map(ChildStderr::from_inner),\n        }\n    }\n}\n\nimpl IntoInner<imp::Process> for Child {\n    fn into_inner(self) -> imp::Process {\n        self.handle\n    }\n}\n\n#[stable(feature = \"std_debug\", since = \"1.16.0\")]\nimpl fmt::Debug for Child {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"Child\")\n            .field(\"stdin\", &self.stdin)\n            .field(\"stdout\", &self.stdout)\n            .field(\"stderr\", &self.stderr)\n            .finish_non_exhaustive()\n    }\n}\n\n/// The pipes connected to a spawned process.\n///\n/// Used to pass pipe handles between this module and [`imp`].\npub(crate) struct StdioPipes {\n    pub stdin: Option<imp::ChildPipe>,\n    pub stdout: Option<imp::ChildPipe>,\n    pub stderr: Option<imp::ChildPipe>,\n}\n\n/// A handle to a child process's standard input (stdin).\n///\n/// This struct is used in the [`stdin`] field on [`Child`].\n///\n/// When an instance of `ChildStdin` is [dropped], the `ChildStdin`'s underlying\n/// file handle will be closed. If the child process was blocked on input prior\n/// to being dropped, it will become unblocked after dropping.\n///\n/// [`stdin`]: Child::stdin\n/// [dropped]: Drop\n#[stable(feature = \"process\", since = \"1.0.0\")]\npub struct ChildStdin {\n    inner: imp::ChildPipe,\n}\n\n// In addition to the `impl`s here, `ChildStdin` also has `impl`s for\n// `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and\n// `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and\n// `AsHandle`/`From<OwnedHandle>`/`Into<OwnedHandle>` and\n// `AsRawHandle`/`IntoRawHandle`/`FromRawHandle` on Windows.\n\n#[stable(feature = \"process\", since = \"1.0.0\")]\nimpl Write for ChildStdin {\n    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {\n        (&*self).write(buf)\n    }\n\n    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {\n        (&*self).write_vectored(bufs)\n    }\n\n    fn is_write_vectored(&self) -> bool {\n        io::Write::is_write_vectored(&&*self)\n    }\n\n    #[inline]\n    fn flush(&mut self) -> io::Result<()> {\n        (&*self).flush()\n    }\n}\n\n#[stable(feature = \"write_mt\", since = \"1.48.0\")]\nimpl Write for &ChildStdin {\n    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {\n        self.inner.write(buf)\n    }\n\n    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {\n        self.inner.write_vectored(bufs)\n    }\n\n    fn is_write_vectored(&self) -> bool {\n        self.inner.is_write_vectored()\n    }\n\n    #[inline]\n    fn flush(&mut self) -> io::Result<()> {\n        Ok(())\n    }\n}\n\nimpl AsInner<imp::ChildPipe> for ChildStdin {\n    #[inline]\n    fn as_inner(&self) -> &imp::ChildPipe {\n        &self.inner\n    }\n}\n\nimpl IntoInner<imp::ChildPipe> for ChildStdin {\n    fn into_inner(self) -> imp::ChildPipe {\n        self.inner\n    }\n}\n\nimpl FromInner<imp::ChildPipe> for ChildStdin {\n    fn from_inner(pipe: imp::ChildPipe) -> ChildStdin {\n        ChildStdin { inner: pipe }\n    }\n}\n\n#[stable(feature = \"std_debug\", since = \"1.16.0\")]\nimpl fmt::Debug for ChildStdin {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"ChildStdin\").finish_non_exhaustive()\n    }\n}\n\n/// A handle to a child process's standard output (stdout).\n///\n/// This struct is used in the [`stdout`] field on [`Child`].\n///\n/// When an instance of `ChildStdout` is [dropped], the `ChildStdout`'s\n/// underlying file handle will be closed.\n///\n/// [`stdout`]: Child::stdout\n/// [dropped]: Drop\n#[stable(feature = \"process\", since = \"1.0.0\")]\npub struct ChildStdout {\n    inner: imp::ChildPipe,\n}\n\n// In addition to the `impl`s here, `ChildStdout` also has `impl`s for\n// `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and\n// `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and\n// `AsHandle`/`From<OwnedHandle>`/`Into<OwnedHandle>` and\n// `AsRawHandle`/`IntoRawHandle`/`FromRawHandle` on Windows.\n\n#[stable(feature = \"process\", since = \"1.0.0\")]\nimpl Read for ChildStdout {\n    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {\n        self.inner.read(buf)\n    }\n\n    fn read_buf(&mut self, buf: BorrowedCursor<'_, u8>) -> io::Result<()> {\n        self.inner.read_buf(buf)\n    }\n\n    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {\n        self.inner.read_vectored(bufs)\n    }\n\n    #[inline]\n    fn is_read_vectored(&self) -> bool {\n        self.inner.is_read_vectored()\n    }\n\n    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {\n        self.inner.read_to_end(buf)\n    }\n}\n\nimpl AsInner<imp::ChildPipe> for ChildStdout {\n    #[inline]\n    fn as_inner(&self) -> &imp::ChildPipe {\n        &self.inner\n    }\n}\n\nimpl IntoInner<imp::ChildPipe> for ChildStdout {\n    fn into_inner(self) -> imp::ChildPipe {\n        self.inner\n    }\n}\n\nimpl FromInner<imp::ChildPipe> for ChildStdout {\n    fn from_inner(pipe: imp::ChildPipe) -> ChildStdout {\n        ChildStdout { inner: pipe }\n    }\n}\n\n#[stable(feature = \"std_debug\", since = \"1.16.0\")]\nimpl fmt::Debug for ChildStdout {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"ChildStdout\").finish_non_exhaustive()\n    }\n}\n\n/// A handle to a child process's stderr.\n///\n/// This struct is used in the [`stderr`] field on [`Child`].\n///\n/// When an instance of `ChildStderr` is [dropped], the `ChildStderr`'s\n/// underlying file handle will be closed.\n///\n/// [`stderr`]: Child::stderr\n/// [dropped]: Drop\n#[stable(feature = \"process\", since = \"1.0.0\")]\npub struct ChildStderr {\n    inner: imp::ChildPipe,\n}\n\n// In addition to the `impl`s here, `ChildStderr` also has `impl`s for\n// `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and\n// `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and\n// `AsHandle`/`From<OwnedHandle>`/`Into<OwnedHandle>` and\n// `AsRawHandle`/`IntoRawHandle`/`FromRawHandle` on Windows.\n\n#[stable(feature = \"process\", since = \"1.0.0\")]\nimpl Read for ChildStderr {\n    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {\n        self.inner.read(buf)\n    }\n\n    fn read_buf(&mut self, buf: BorrowedCursor<'_, u8>) -> io::Result<()> {\n        self.inner.read_buf(buf)\n    }\n\n    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {\n        self.inner.read_vectored(bufs)\n    }\n\n    #[inline]\n    fn is_read_vectored(&self) -> bool {\n        self.inner.is_read_vectored()\n    }\n\n    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {\n        self.inner.read_to_end(buf)\n    }\n}\n\nimpl AsInner<imp::ChildPipe> for ChildStderr {\n    #[inline]\n    fn as_inner(&self) -> &imp::ChildPipe {\n        &self.inner\n    }\n}\n\nimpl IntoInner<imp::ChildPipe> for ChildStderr {\n    fn into_inner(self) -> imp::ChildPipe {\n        self.inner\n    }\n}\n\nimpl FromInner<imp::ChildPipe> for ChildStderr {\n    fn from_inner(pipe: imp::ChildPipe) -> ChildStderr {\n        ChildStderr { inner: pipe }\n    }\n}\n\n#[stable(feature = \"std_debug\", since = \"1.16.0\")]\nimpl fmt::Debug for ChildStderr {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"ChildStderr\").finish_non_exhaustive()\n    }\n}\n\n/// A process builder, providing fine-grained control\n/// over how a new process should be spawned.\n///\n/// A default configuration can be\n/// generated using `Command::new(program)`, where `program` gives a path to the\n/// program to be executed. Additional builder methods allow the configuration\n/// to be changed (for example, by adding arguments) prior to spawning:\n///\n/// ```\n/// # if cfg!(not(all(target_vendor = \"apple\", not(target_os = \"macos\")))) {\n/// use std::process::Command;\n///\n/// let output = if cfg!(target_os = \"windows\") {\n///     Command::new(\"cmd\")\n///         .args([\"/C\", \"echo hello\"])\n///         .output()\n///         .expect(\"failed to execute process\")\n/// } else {\n///     Command::new(\"sh\")\n///         .arg(\"-c\")\n///         .arg(\"echo hello\")\n///         .output()\n///         .expect(\"failed to execute process\")\n/// };\n///\n/// let hello = output.stdout;\n/// # }\n/// ```\n///\n/// `Command` can be reused to spawn multiple processes. The builder methods\n/// change the command without needing to immediately spawn the process.\n///\n/// ```no_run\n/// use std::process::Command;\n///\n/// let mut echo_hello = Command::new(\"sh\");\n/// echo_hello.arg(\"-c\").arg(\"echo hello\");\n/// let hello_1 = echo_hello.output().expect(\"failed to execute process\");\n/// let hello_2 = echo_hello.output().expect(\"failed to execute process\");\n/// ```\n///\n/// Similarly, you can call builder methods after spawning a process and then\n/// spawn a new process with the modified settings.\n///\n/// ```no_run\n/// use std::process::Command;\n///\n/// let mut list_dir = Command::new(\"ls\");\n///\n/// // Execute `ls` in the current directory of the program.\n/// list_dir.status().expect(\"process failed to execute\");\n///\n/// println!();\n///\n/// // Change `ls` to execute in the root directory.\n/// list_dir.current_dir(\"/\");\n///\n/// // And then execute `ls` again but in the root directory.\n/// list_dir.status().expect(\"process failed to execute\");\n/// ```\n#[stable(feature = \"process\", since = \"1.0.0\")]\n#[cfg_attr(not(test), rustc_diagnostic_item = \"Command\")]\npub struct Command {\n    inner: imp::Command,\n}\n\nimpl Command {\n    /// Constructs a new `Command` for launching the program at\n    /// path `program`, with the following default configuration:\n    ///\n    /// * No arguments to the program\n    /// * Inherit the current process's environment\n    /// * Inherit the current process's working directory\n    /// * Inherit stdin/stdout/stderr for [`spawn`] or [`status`], but create pipes for [`output`]\n    ///\n    /// [`spawn`]: Self::spawn\n    /// [`status`]: Self::status\n    /// [`output`]: Self::output\n    ///\n    /// Builder methods are provided to change these defaults and\n    /// otherwise configure the process.\n    ///\n    /// If `program` is not an absolute path, the `PATH` environment variable\n    /// will be searched in an OS-defined way.\n    ///\n    /// # Platform-specific behavior\n    ///\n    /// The details below describe the current behavior, but these details\n    /// may change in future versions of Rust.\n    ///\n    /// On Unix, the `PATH` searched comes from the child's environment:\n    ///\n    /// - If the environment is unmodified, the child inherits the parent's\n    ///   `PATH` and that is what is searched.\n    /// - If `PATH` is explicitly set via [`env`], that new value is searched.\n    /// - If [`env_clear`] or [`env_remove`] removes `PATH` without a\n    ///   replacement, `execvp` falls back to an OS-defined default (typically\n    ///   `/bin:/usr/bin`), **not** the parent's `PATH`. This may fail to find\n    ///   programs that rely on the parent's `PATH`.\n    ///\n    /// To avoid surprises, use an absolute path or explicitly set `PATH` on\n    /// the `Command` when modifying the child's environment.\n    ///\n    /// On Windows, Rust resolves the executable path before spawning, rather\n    /// than passing the name to `CreateProcessW` for resolution. When\n    /// `program` is not an absolute path, the following locations are searched\n    /// in order:\n    ///\n    /// 1. The child's `PATH`, if explicitly set via [`env`].\n    /// 2. The directory of the current executable.\n    /// 3. The system directory (`GetSystemDirectoryW`).\n    /// 4. The Windows directory (`GetWindowsDirectoryW`).\n    /// 5. The parent process's `PATH`.\n    ///\n    /// Note: when `PATH` is cleared via [`env_clear`] or [`env_remove`] on\n    /// Windows, step 1 is skipped but the parent process's `PATH` is still\n    /// searched at step 5, unlike on Unix.\n    ///\n    /// For executable files, the `.exe` extension may be omitted. Files with\n    /// other extensions must include the extension, otherwise they will not be\n    /// found. Note that this behavior has some known limitations\n    /// (see issue #37519).\n    ///\n    /// [`env`]: Self::env\n    /// [`env_remove`]: Self::env_remove\n    /// [`env_clear`]: Self::env_clear\n    ///\n    /// # Examples\n    ///\n    /// ```no_run\n    /// use std::process::Command;\n    ///\n    /// Command::new(\"sh\")\n    ///     .spawn()\n    ///     .expect(\"sh command failed to start\");\n    /// ```\n    ///\n    /// # Caveats\n    ///\n    /// [`Command::new`] is only intended to accept the path of the program. If you pass a program\n    /// path along with arguments like `Command::new(\"ls -l\").spawn()`, it will try to search for\n    /// `ls -l` literally. The arguments need to be passed separately, such as via [`arg`] or\n    /// [`args`].\n    ///\n    /// ```no_run\n    /// use std::process::Command;\n    ///\n    /// Command::new(\"ls\")\n    ///     .arg(\"-l\") // arg passed separately\n    ///     .spawn()\n    ///     .expect(\"ls command failed to start\");\n    /// ```\n    ///\n    /// [`arg`]: Self::arg\n    /// [`args`]: Self::args\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn new<S: AsRef<OsStr>>(program: S) -> Command {\n        Command { inner: imp::Command::new(program.as_ref()) }\n    }\n\n    /// Adds an argument to pass to the program.\n    ///\n    /// Only one argument can be passed per use. So instead of:\n    ///\n    /// ```no_run\n    /// # std::process::Command::new(\"sh\")\n    /// .arg(\"-C /path/to/repo\")\n    /// # ;\n    /// ```\n    ///\n    /// usage would be:\n    ///\n    /// ```no_run\n    /// # std::process::Command::new(\"sh\")\n    /// .arg(\"-C\")\n    /// .arg(\"/path/to/repo\")\n    /// # ;\n    /// ```\n    ///\n    /// To pass multiple arguments see [`args`].\n    ///\n    /// [`args`]: Command::args\n    ///\n    /// Note that the argument is not passed through a shell, but given\n    /// literally to the program. This means that shell syntax like quotes,\n    /// escaped characters, word splitting, glob patterns, variable substitution,\n    /// etc. have no effect.\n    ///\n    /// <div class=\"warning\">\n    ///\n    /// On Windows, use caution with untrusted inputs. Most applications use the\n    /// standard convention for decoding arguments passed to them. These are safe to\n    /// use with `arg`. However, some applications such as `cmd.exe` and `.bat` files\n    /// use a non-standard way of decoding arguments. They are therefore vulnerable\n    /// to malicious input.\n    ///\n    /// In the case of `cmd.exe` this is especially important because a malicious\n    /// argument can potentially run arbitrary shell commands.\n    ///\n    /// See [Windows argument splitting][windows-args] for more details\n    /// or [`raw_arg`] for manually implementing non-standard argument encoding.\n    ///\n    /// [`raw_arg`]: crate::os::windows::process::CommandExt::raw_arg\n    /// [windows-args]: crate::process#windows-argument-splitting\n    ///\n    /// </div>\n    ///\n    /// # Examples\n    ///\n    /// ```no_run\n    /// use std::process::Command;\n    ///\n    /// Command::new(\"ls\")\n    ///     .arg(\"-l\")\n    ///     .arg(\"-a\")\n    ///     .spawn()\n    ///     .expect(\"ls command failed to start\");\n    /// ```\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command {\n        self.inner.arg(arg.as_ref());\n        self\n    }\n\n    /// Adds multiple arguments to pass to the program.\n    ///\n    /// To pass a single argument see [`arg`].\n    ///\n    /// [`arg`]: Command::arg\n    ///\n    /// Note that the arguments are not passed through a shell, but given\n    /// literally to the program. This means that shell syntax like quotes,\n    /// escaped characters, word splitting, glob patterns, variable substitution, etc.\n    /// have no effect.\n    ///\n    /// <div class=\"warning\">\n    ///\n    /// On Windows, use caution with untrusted inputs. Most applications use the\n    /// standard convention for decoding arguments passed to them. These are safe to\n    /// use with `arg`. However, some applications such as `cmd.exe` and `.bat` files\n    /// use a non-standard way of decoding arguments. They are therefore vulnerable\n    /// to malicious input.\n    ///\n    /// In the case of `cmd.exe` this is especially important because a malicious\n    /// argument can potentially run arbitrary shell commands.\n    ///\n    /// See [Windows argument splitting][windows-args] for more details\n    /// or [`raw_arg`] for manually implementing non-standard argument encoding.\n    ///\n    /// [`raw_arg`]: crate::os::windows::process::CommandExt::raw_arg\n    /// [windows-args]: crate::process#windows-argument-splitting\n    ///\n    /// </div>\n    ///\n    /// # Examples\n    ///\n    /// ```no_run\n    /// use std::process::Command;\n    ///\n    /// Command::new(\"ls\")\n    ///     .args([\"-l\", \"-a\"])\n    ///     .spawn()\n    ///     .expect(\"ls command failed to start\");\n    /// ```\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn args<I, S>(&mut self, args: I) -> &mut Command\n    where\n        I: IntoIterator<Item = S>,\n        S: AsRef<OsStr>,\n    {\n        for arg in args {\n            self.arg(arg.as_ref());\n        }\n        self\n    }\n\n    /// Inserts or updates an explicit environment variable mapping.\n    ///\n    /// This method allows you to add an environment variable mapping to the spawned process or\n    /// overwrite a previously set value. You can use [`Command::envs`] to set multiple environment\n    /// variables simultaneously.\n    ///\n    /// Child processes will inherit environment variables from their parent process by default.\n    /// Environment variables explicitly set using [`Command::env`] take precedence over inherited\n    /// variables. You can disable environment variable inheritance entirely using\n    /// [`Command::env_clear`] or for a single key using [`Command::env_remove`].\n    ///\n    /// Note that environment variable names are case-insensitive (but\n    /// case-preserving) on Windows and case-sensitive on all other platforms.\n    ///\n    /// # Examples\n    ///\n    /// ```no_run\n    /// use std::process::Command;\n    ///\n    /// Command::new(\"ls\")\n    ///     .env(\"PATH\", \"/bin\")\n    ///     .spawn()\n    ///     .expect(\"ls command failed to start\");\n    /// ```\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command\n    where\n        K: AsRef<OsStr>,\n        V: AsRef<OsStr>,\n    {\n        self.inner.env_mut().set(key.as_ref(), val.as_ref());\n        self\n    }\n\n    /// Inserts or updates multiple explicit environment variable mappings.\n    ///\n    /// This method allows you to add multiple environment variable mappings to the spawned process\n    /// or overwrite previously set values. You can use [`Command::env`] to set a single environment\n    /// variable.\n    ///\n    /// Child processes will inherit environment variables from their parent process by default.\n    /// Environment variables explicitly set using [`Command::envs`] take precedence over inherited\n    /// variables. You can disable environment variable inheritance entirely using\n    /// [`Command::env_clear`] or for a single key using [`Command::env_remove`].\n    ///\n    /// Note that environment variable names are case-insensitive (but case-preserving) on Windows\n    /// and case-sensitive on all other platforms.\n    ///\n    /// # Examples\n    ///\n    /// ```no_run\n    /// use std::process::{Command, Stdio};\n    /// use std::env;\n    /// use std::collections::HashMap;\n    ///\n    /// let filtered_env : HashMap<String, String> =\n    ///     env::vars().filter(|&(ref k, _)|\n    ///         k == \"TERM\" || k == \"TZ\" || k == \"LANG\" || k == \"PATH\"\n    ///     ).collect();\n    ///\n    /// Command::new(\"printenv\")\n    ///     .stdin(Stdio::null())\n    ///     .stdout(Stdio::inherit())\n    ///     .env_clear()\n    ///     .envs(&filtered_env)\n    ///     .spawn()\n    ///     .expect(\"printenv failed to start\");\n    /// ```\n    #[stable(feature = \"command_envs\", since = \"1.19.0\")]\n    pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Command\n    where\n        I: IntoIterator<Item = (K, V)>,\n        K: AsRef<OsStr>,\n        V: AsRef<OsStr>,\n    {\n        for (ref key, ref val) in vars {\n            self.inner.env_mut().set(key.as_ref(), val.as_ref());\n        }\n        self\n    }\n\n    /// Removes an explicitly set environment variable and prevents inheriting it from a parent\n    /// process.\n    ///\n    /// This method will remove the explicit value of an environment variable set via\n    /// [`Command::env`] or [`Command::envs`]. In addition, it will prevent the spawned child\n    /// process from inheriting that environment variable from its parent process.\n    ///\n    /// After calling [`Command::env_remove`], the value associated with its key from\n    /// [`Command::get_envs`] will be [`None`].\n    ///\n    /// To clear all explicitly set environment variables and disable all environment variable\n    /// inheritance, you can use [`Command::env_clear`].\n    ///\n    /// # Examples\n    ///\n    /// Prevent any inherited `GIT_DIR` variable from changing the target of the `git` command,\n    /// while allowing all other variables, like `GIT_AUTHOR_NAME`.\n    ///\n    /// ```no_run\n    /// use std::process::Command;\n    ///\n    /// Command::new(\"git\")\n    ///     .arg(\"commit\")\n    ///     .env_remove(\"GIT_DIR\")\n    ///     .spawn()?;\n    /// # std::io::Result::Ok(())\n    /// ```\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command {\n        self.inner.env_mut().remove(key.as_ref());\n        self\n    }\n\n    /// Clears all explicitly set environment variables and prevents inheriting any parent process\n    /// environment variables.\n    ///\n    /// This method will remove all explicitly added environment variables set via [`Command::env`]\n    /// or [`Command::envs`]. In addition, it will prevent the spawned child process from inheriting\n    /// any environment variable from its parent process.\n    ///\n    /// After calling [`Command::env_clear`], the iterator from [`Command::get_envs`] will be\n    /// empty.\n    ///\n    /// You can use [`Command::env_remove`] to clear a single mapping.\n    ///\n    /// # Examples\n    ///\n    /// The behavior of `sort` is affected by `LANG` and `LC_*` environment variables.\n    /// Clearing the environment makes `sort`'s behavior independent of the parent processes' language.\n    ///\n    /// ```no_run\n    /// use std::process::Command;\n    ///\n    /// Command::new(\"sort\")\n    ///     .arg(\"file.txt\")\n    ///     .env_clear()\n    ///     .spawn()?;\n    /// # std::io::Result::Ok(())\n    /// ```\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn env_clear(&mut self) -> &mut Command {\n        self.inner.env_mut().clear();\n        self\n    }\n\n    /// Sets the working directory for the child process.\n    ///\n    /// # Platform-specific behavior\n    ///\n    /// If the program path is relative (e.g., `\"./script.sh\"`), it's ambiguous\n    /// whether it should be interpreted relative to the parent's working\n    /// directory or relative to `current_dir`. The behavior in this case is\n    /// platform specific and unstable, and it's recommended to use\n    /// [`canonicalize`] to get an absolute program path instead.\n    ///\n    /// # Examples\n    ///\n    /// ```no_run\n    /// use std::process::Command;\n    ///\n    /// Command::new(\"ls\")\n    ///     .current_dir(\"/bin\")\n    ///     .spawn()\n    ///     .expect(\"ls command failed to start\");\n    /// ```\n    ///\n    /// [`canonicalize`]: crate::fs::canonicalize\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn current_dir<P: AsRef<Path>>(&mut self, dir: P) -> &mut Command {\n        self.inner.cwd(dir.as_ref().as_ref());\n        self\n    }\n\n    /// Configuration for the child process's standard input (stdin) handle.\n    ///\n    /// Defaults to [`inherit`] when used with [`spawn`] or [`status`], and\n    /// defaults to [`piped`] when used with [`output`].\n    ///\n    /// [`inherit`]: Stdio::inherit\n    /// [`piped`]: Stdio::piped\n    /// [`spawn`]: Self::spawn\n    /// [`status`]: Self::status\n    /// [`output`]: Self::output\n    ///\n    /// # Examples\n    ///\n    /// ```no_run\n    /// use std::process::{Command, Stdio};\n    ///\n    /// Command::new(\"ls\")\n    ///     .stdin(Stdio::null())\n    ///     .spawn()\n    ///     .expect(\"ls command failed to start\");\n    /// ```\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {\n        self.inner.stdin(cfg.into().0);\n        self\n    }\n\n    /// Configuration for the child process's standard output (stdout) handle.\n    ///\n    /// Defaults to [`inherit`] when used with [`spawn`] or [`status`], and\n    /// defaults to [`piped`] when used with [`output`].\n    ///\n    /// [`inherit`]: Stdio::inherit\n    /// [`piped`]: Stdio::piped\n    /// [`spawn`]: Self::spawn\n    /// [`status`]: Self::status\n    /// [`output`]: Self::output\n    ///\n    /// # Examples\n    ///\n    /// ```no_run\n    /// use std::process::{Command, Stdio};\n    ///\n    /// Command::new(\"ls\")\n    ///     .stdout(Stdio::null())\n    ///     .spawn()\n    ///     .expect(\"ls command failed to start\");\n    /// ```\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {\n        self.inner.stdout(cfg.into().0);\n        self\n    }\n\n    /// Configuration for the child process's standard error (stderr) handle.\n    ///\n    /// Defaults to [`inherit`] when used with [`spawn`] or [`status`], and\n    /// defaults to [`piped`] when used with [`output`].\n    ///\n    /// [`inherit`]: Stdio::inherit\n    /// [`piped`]: Stdio::piped\n    /// [`spawn`]: Self::spawn\n    /// [`status`]: Self::status\n    /// [`output`]: Self::output\n    ///\n    /// # Examples\n    ///\n    /// ```no_run\n    /// use std::process::{Command, Stdio};\n    ///\n    /// Command::new(\"ls\")\n    ///     .stderr(Stdio::null())\n    ///     .spawn()\n    ///     .expect(\"ls command failed to start\");\n    /// ```\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {\n        self.inner.stderr(cfg.into().0);\n        self\n    }\n\n    /// Executes the command as a child process, returning a handle to it.\n    ///\n    /// By default, stdin, stdout and stderr are inherited from the parent.\n    ///\n    /// # Errors\n    ///\n    /// This method returns an [`io::Error`] if the child process could not be\n    /// spawned. Common reasons include:\n    ///\n    /// * the program could not be found (for example, it does not exist, or,\n    ///   when given a bare name, it is not present in the `PATH`);\n    /// * the current process does not have permission to execute the program\n    ///   (for example, the file is not marked executable, or execution is\n    ///   denied by a security policy such as `seccomp`);\n    /// * the operating system could not create the new process because of\n    ///   resource exhaustion (for example, a limit on the number of processes\n    ///   was reached).\n    ///\n    /// An error is only returned for failures that occur while the child is\n    /// being spawned. Once the child has started successfully, anything that\n    /// happens to it afterwards — including being terminated by a signal — is\n    /// reported through its [`ExitStatus`] rather than as an error from the\n    /// spawning method.\n    ///\n    /// # Examples\n    ///\n    /// ```no_run\n    /// use std::process::Command;\n    ///\n    /// Command::new(\"ls\")\n    ///     .spawn()\n    ///     .expect(\"ls command failed to start\");\n    /// ```\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn spawn(&mut self) -> io::Result<Child> {\n        self.inner.spawn(imp::Stdio::Inherit, true).map(Child::from_inner)\n    }\n\n    /// Executes the command as a child process, waiting for it to finish and\n    /// collecting all of its output.\n    ///\n    /// By default, stdout and stderr are captured (and used to provide the\n    /// resulting output). Stdin is not inherited from the parent and any\n    /// attempt by the child process to read from the stdin stream will result\n    /// in the stream immediately closing.\n    ///\n    /// # Errors\n    ///\n    /// Like [`spawn`], this method returns an [`io::Error`] if the child\n    /// process could not be spawned; see [`spawn`] for the common reasons. It\n    /// may also return an error if reading the child's output or waiting on the\n    /// child fails.\n    ///\n    /// Note that this method does **not** return an error if the child runs and\n    /// then exits unsuccessfully, or is terminated by a signal. In those cases\n    /// it still returns [`Ok`], and the outcome is reflected in the\n    /// [`ExitStatus`] stored in the returned [`Output`].\n    ///\n    /// [`spawn`]: Command::spawn\n    ///\n    /// # Examples\n    ///\n    /// ```should_panic\n    /// use std::process::Command;\n    /// use std::io::{self, Write};\n    /// let output = Command::new(\"/bin/cat\")\n    ///     .arg(\"file.txt\")\n    ///     .output()?;\n    ///\n    /// println!(\"status: {}\", output.status);\n    /// io::stdout().write_all(&output.stdout)?;\n    /// io::stderr().write_all(&output.stderr)?;\n    ///\n    /// assert!(output.status.success());\n    /// # io::Result::Ok(())\n    /// ```\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn output(&mut self) -> io::Result<Output> {\n        let (status, stdout, stderr) = imp::output(&mut self.inner)?;\n        Ok(Output { status: ExitStatus(status), stdout, stderr })\n    }\n\n    /// Executes a command as a child process, waiting for it to finish and\n    /// collecting its status.\n    ///\n    /// By default, stdin, stdout and stderr are inherited from the parent.\n    ///\n    /// # Errors\n    ///\n    /// Like [`spawn`], this method returns an [`io::Error`] if the child\n    /// process could not be spawned; see [`spawn`] for the common reasons. It\n    /// may also return an error if waiting on the child fails.\n    ///\n    /// Note that this method does **not** return an error if the child runs and\n    /// then exits unsuccessfully, or is terminated by a signal. In those cases\n    /// it still returns [`Ok`], and the outcome is reflected in the returned\n    /// [`ExitStatus`].\n    ///\n    /// [`spawn`]: Command::spawn\n    ///\n    /// # Examples\n    ///\n    /// ```should_panic\n    /// use std::process::Command;\n    ///\n    /// let status = Command::new(\"/bin/cat\")\n    ///     .arg(\"file.txt\")\n    ///     .status()\n    ///     .expect(\"failed to execute process\");\n    ///\n    /// println!(\"process finished with: {status}\");\n    ///\n    /// assert!(status.success());\n    /// ```\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn status(&mut self) -> io::Result<ExitStatus> {\n        self.inner\n            .spawn(imp::Stdio::Inherit, true)\n            .map(Child::from_inner)\n            .and_then(|mut p| p.wait())\n    }\n\n    /// Returns the path to the program that was given to [`Command::new`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use std::process::Command;\n    ///\n    /// let cmd = Command::new(\"echo\");\n    /// assert_eq!(cmd.get_program(), \"echo\");\n    /// ```\n    #[must_use]\n    #[stable(feature = \"command_access\", since = \"1.57.0\")]\n    pub fn get_program(&self) -> &OsStr {\n        self.inner.get_program()\n    }\n\n    /// Returns an iterator of the arguments that will be passed to the program.\n    ///\n    /// This does not include the path to the program as the first argument;\n    /// it only includes the arguments specified with [`Command::arg`] and\n    /// [`Command::args`].\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use std::ffi::OsStr;\n    /// use std::process::Command;\n    ///\n    /// let mut cmd = Command::new(\"echo\");\n    /// cmd.arg(\"first\").arg(\"second\");\n    /// let args: Vec<&OsStr> = cmd.get_args().collect();\n    /// assert_eq!(args, &[\"first\", \"second\"]);\n    /// ```\n    #[stable(feature = \"command_access\", since = \"1.57.0\")]\n    pub fn get_args(&self) -> CommandArgs<'_> {\n        CommandArgs { inner: self.inner.get_args() }\n    }\n\n    /// Returns an iterator of the environment variables explicitly set for the child process.\n    ///\n    /// Environment variables explicitly set using [`Command::env`], [`Command::envs`], and\n    /// [`Command::env_remove`] can be retrieved with this method.\n    ///\n    /// Note that this output does not include environment variables inherited from the parent\n    /// process. To see the full list of environment variables, including those inherited from the\n    /// parent process, use [`Command::get_resolved_envs`].\n    ///\n    /// Each element is a tuple key/value pair `(&OsStr, Option<&OsStr>)`. A [`None`] value\n    /// indicates its key was explicitly removed via [`Command::env_remove`]. The associated key for\n    /// the [`None`] value will no longer inherit from its parent process.\n    ///\n    /// An empty iterator can indicate that no explicit mappings were added or that\n    /// [`Command::env_clear`] was called. After calling [`Command::env_clear`], the child process\n    /// will not inherit any environment variables from its parent process.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use std::ffi::OsStr;\n    /// use std::process::Command;\n    ///\n    /// let mut cmd = Command::new(\"ls\");\n    /// cmd.env(\"TERM\", \"dumb\").env_remove(\"TZ\");\n    /// let envs: Vec<(&OsStr, Option<&OsStr>)> = cmd.get_envs().collect();\n    /// assert_eq!(envs, &[\n    ///     (OsStr::new(\"TERM\"), Some(OsStr::new(\"dumb\"))),\n    ///     (OsStr::new(\"TZ\"), None)\n    /// ]);\n    /// ```\n    #[stable(feature = \"command_access\", since = \"1.57.0\")]\n    pub fn get_envs(&self) -> CommandEnvs<'_> {\n        CommandEnvs { iter: self.inner.get_envs() }\n    }\n\n    /// Returns an iterator of the environment variables that will be set when the process is spawned.\n    ///\n    /// This returns the environment as it would be if the command were executed at the time of calling\n    /// this method. The returned environment includes:\n    /// - All inherited environment variables from the parent process (unless [`Command::env_clear`] was called)\n    /// - All environment variables explicitly set via [`Command::env`] or [`Command::envs`]\n    /// - Excluding any environment variables removed via [`Command::env_remove`]\n    ///\n    /// Note that the returned environment is a snapshot at the time this method is called and will not\n    /// reflect any subsequent changes to the `Command` or the parent process's environment. Additionally,\n    /// it will not reflect changes made in a `pre_exec` hook (on Unix platforms).\n    ///\n    /// Each element is a tuple `(OsString, OsString)` representing an environment variable key and value.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// #![feature(command_resolved_envs)]\n    /// use std::process::Command;\n    /// use std::ffi::{OsString, OsStr};\n    /// use std::env;\n    /// use std::collections::HashMap;\n    ///\n    /// let mut cmd = Command::new(\"ls\");\n    /// cmd.env(\"TZ\", \"UTC\");\n    /// unsafe { env::set_var(\"EDITOR\", \"vim\"); }\n    ///\n    /// let resolved: HashMap<OsString, OsString> = cmd.get_resolved_envs().collect();\n    /// assert_eq!(resolved.get(OsStr::new(\"TZ\")), Some(&OsString::from(\"UTC\")));\n    /// assert_eq!(resolved.get(OsStr::new(\"EDITOR\")), Some(&OsString::from(\"vim\")));\n    /// ```\n    #[unstable(feature = \"command_resolved_envs\", issue = \"149070\")]\n    pub fn get_resolved_envs(&self) -> CommandResolvedEnvs {\n        self.inner.get_resolved_envs()\n    }\n\n    /// Returns the working directory for the child process.\n    ///\n    /// This returns [`None`] if the working directory will not be changed.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// use std::path::Path;\n    /// use std::process::Command;\n    ///\n    /// let mut cmd = Command::new(\"ls\");\n    /// assert_eq!(cmd.get_current_dir(), None);\n    /// cmd.current_dir(\"/bin\");\n    /// assert_eq!(cmd.get_current_dir(), Some(Path::new(\"/bin\")));\n    /// ```\n    #[must_use]\n    #[stable(feature = \"command_access\", since = \"1.57.0\")]\n    pub fn get_current_dir(&self) -> Option<&Path> {\n        self.inner.get_current_dir()\n    }\n\n    /// Returns whether the environment will be cleared for the child process.\n    ///\n    /// This returns `true` if [`Command::env_clear`] was called, and `false` otherwise.\n    /// When `true`, the child process will not inherit any environment variables from\n    /// its parent process.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// #![feature(command_resolved_envs)]\n    /// use std::process::Command;\n    ///\n    /// let mut cmd = Command::new(\"ls\");\n    /// assert_eq!(cmd.get_env_clear(), false);\n    ///\n    /// cmd.env_clear();\n    /// assert_eq!(cmd.get_env_clear(), true);\n    /// ```\n    #[must_use]\n    #[unstable(feature = \"command_resolved_envs\", issue = \"149070\")]\n    pub fn get_env_clear(&self) -> bool {\n        self.inner.get_env_clear()\n    }\n}\n\n#[stable(feature = \"rust1\", since = \"1.0.0\")]\nimpl fmt::Debug for Command {\n    /// Format the program and arguments of a Command for display. Any\n    /// non-utf8 data is lossily converted using the utf8 replacement\n    /// character.\n    ///\n    /// The default format approximates a shell invocation of the program along with its\n    /// arguments. It does not include most of the other command properties. The output is not guaranteed to work\n    /// (e.g. due to lack of shell-escaping or differences in path resolution).\n    /// On some platforms you can use [the alternate syntax] to show more fields.\n    ///\n    /// Note that the debug implementation is platform-specific.\n    ///\n    /// [the alternate syntax]: fmt#sign0\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        self.inner.fmt(f)\n    }\n}\n\nimpl AsInner<imp::Command> for Command {\n    #[inline]\n    fn as_inner(&self) -> &imp::Command {\n        &self.inner\n    }\n}\n\nimpl AsInnerMut<imp::Command> for Command {\n    #[inline]\n    fn as_inner_mut(&mut self) -> &mut imp::Command {\n        &mut self.inner\n    }\n}\n\n/// An iterator over the command arguments.\n///\n/// This struct is created by [`Command::get_args`]. See its documentation for\n/// more.\n#[must_use = \"iterators are lazy and do nothing unless consumed\"]\n#[stable(feature = \"command_access\", since = \"1.57.0\")]\n#[derive(Debug)]\npub struct CommandArgs<'a> {\n    inner: imp::CommandArgs<'a>,\n}\n\n#[stable(feature = \"command_access\", since = \"1.57.0\")]\nimpl<'a> Iterator for CommandArgs<'a> {\n    type Item = &'a OsStr;\n    fn next(&mut self) -> Option<&'a OsStr> {\n        self.inner.next()\n    }\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.inner.size_hint()\n    }\n}\n\n#[stable(feature = \"command_access\", since = \"1.57.0\")]\nimpl<'a> ExactSizeIterator for CommandArgs<'a> {\n    fn len(&self) -> usize {\n        self.inner.len()\n    }\n    fn is_empty(&self) -> bool {\n        self.inner.is_empty()\n    }\n}\n\nconst fn assert_send<T: core::marker::Send>() {}\nconst fn assert_sync<T: core::marker::Sync>() {}\n\nconst _: () = assert_send::<CommandArgs<'static>>();\nconst _: () = assert_sync::<CommandArgs<'static>>();\n\n/// An iterator over the command environment variables.\n///\n/// This struct is created by\n/// [`Command::get_envs`][crate::process::Command::get_envs]. See its\n/// documentation for more.\n#[must_use = \"iterators are lazy and do nothing unless consumed\"]\n#[stable(feature = \"command_access\", since = \"1.57.0\")]\npub struct CommandEnvs<'a> {\n    iter: imp::CommandEnvs<'a>,\n}\n\n#[stable(feature = \"command_access\", since = \"1.57.0\")]\nimpl<'a> Iterator for CommandEnvs<'a> {\n    type Item = (&'a OsStr, Option<&'a OsStr>);\n\n    fn next(&mut self) -> Option<Self::Item> {\n        self.iter.next()\n    }\n\n    fn size_hint(&self) -> (usize, Option<usize>) {\n        self.iter.size_hint()\n    }\n}\n\n#[stable(feature = \"command_access\", since = \"1.57.0\")]\nimpl<'a> ExactSizeIterator for CommandEnvs<'a> {\n    fn len(&self) -> usize {\n        self.iter.len()\n    }\n\n    fn is_empty(&self) -> bool {\n        self.iter.is_empty()\n    }\n}\n\n#[stable(feature = \"command_access\", since = \"1.57.0\")]\nimpl<'a> fmt::Debug for CommandEnvs<'a> {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        self.iter.fmt(f)\n    }\n}\n\n#[unstable(feature = \"command_resolved_envs\", issue = \"149070\")]\npub use imp::CommandResolvedEnvs;\n\n/// The output of a finished process.\n///\n/// This is returned in a Result by either the [`output`] method of a\n/// [`Command`], or the [`wait_with_output`] method of a [`Child`]\n/// process.\n///\n/// [`output`]: Command::output\n/// [`wait_with_output`]: Child::wait_with_output\n#[derive(PartialEq, Eq, Clone)]\n#[stable(feature = \"process\", since = \"1.0.0\")]\npub struct Output {\n    /// The status (exit code) of the process.\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub status: ExitStatus,\n    /// The data that the process wrote to stdout.\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub stdout: Vec<u8>,\n    /// The data that the process wrote to stderr.\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub stderr: Vec<u8>,\n}\n\nimpl Output {\n    /// Returns an error if a nonzero exit status was received.\n    ///\n    /// If the [`Command`] exited successfully,\n    /// `self` is returned.\n    ///\n    /// This is equivalent to calling [`exit_ok`](ExitStatus::exit_ok)\n    /// on [`Output.status`](Output::status).\n    ///\n    /// Note that this will throw away the [`Output::stderr`] field in the error case.\n    /// If the child process outputs useful informantion to stderr, you can:\n    /// * Use `cmd.stderr(Stdio::inherit())` to forward the\n    ///   stderr child process to the parent's stderr,\n    ///   usually printing it to console where the user can see it.\n    ///   This is usually correct for command-line applications.\n    /// * Capture `stderr` using a custom error type.\n    ///   This is usually correct for libraries.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// # #![allow(unused_features)]\n    /// #![feature(exit_status_error)]\n    /// # #[cfg(all(unix, not(target_os = \"android\"), not(all(target_vendor = \"apple\", not(target_os = \"macos\")))))] {\n    /// use std::process::Command;\n    /// assert!(Command::new(\"false\").output().unwrap().exit_ok().is_err());\n    /// # }\n    /// ```\n    #[unstable(feature = \"exit_status_error\", issue = \"84908\")]\n    pub fn exit_ok(self) -> Result<Self, ExitStatusError> {\n        self.status.exit_ok()?;\n        Ok(self)\n    }\n}\n\n// If either stderr or stdout are valid utf8 strings it prints the valid\n// strings, otherwise it prints the byte sequence instead\n#[stable(feature = \"process_output_debug\", since = \"1.7.0\")]\nimpl fmt::Debug for Output {\n    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {\n        let stdout_utf8 = str::from_utf8(&self.stdout);\n        let stdout_debug: &dyn fmt::Debug = match stdout_utf8 {\n            Ok(ref s) => s,\n            Err(_) => &self.stdout,\n        };\n\n        let stderr_utf8 = str::from_utf8(&self.stderr);\n        let stderr_debug: &dyn fmt::Debug = match stderr_utf8 {\n            Ok(ref s) => s,\n            Err(_) => &self.stderr,\n        };\n\n        fmt.debug_struct(\"Output\")\n            .field(\"status\", &self.status)\n            .field(\"stdout\", stdout_debug)\n            .field(\"stderr\", stderr_debug)\n            .finish()\n    }\n}\n\n/// Describes what to do with a standard I/O stream for a child process when\n/// passed to the [`stdin`], [`stdout`], and [`stderr`] methods of [`Command`].\n///\n/// [`stdin`]: Command::stdin\n/// [`stdout`]: Command::stdout\n/// [`stderr`]: Command::stderr\n#[stable(feature = \"process\", since = \"1.0.0\")]\npub struct Stdio(imp::Stdio);\n\nimpl Stdio {\n    /// A new pipe should be arranged to connect the parent and child processes.\n    ///\n    /// # Examples\n    ///\n    /// With stdout:\n    ///\n    /// ```no_run\n    /// use std::process::{Command, Stdio};\n    ///\n    /// let output = Command::new(\"echo\")\n    ///     .arg(\"Hello, world!\")\n    ///     .stdout(Stdio::piped())\n    ///     .output()\n    ///     .expect(\"Failed to execute command\");\n    ///\n    /// assert_eq!(String::from_utf8_lossy(&output.stdout), \"Hello, world!\\n\");\n    /// // Nothing echoed to console\n    /// ```\n    ///\n    /// With stdin:\n    ///\n    /// ```no_run\n    /// use std::io::Write;\n    /// use std::process::{Command, Stdio};\n    ///\n    /// let mut child = Command::new(\"rev\")\n    ///     .stdin(Stdio::piped())\n    ///     .stdout(Stdio::piped())\n    ///     .spawn()\n    ///     .expect(\"Failed to spawn child process\");\n    ///\n    /// let mut stdin = child.stdin.take().expect(\"Failed to open stdin\");\n    /// std::thread::spawn(move || {\n    ///     stdin.write_all(\"Hello, world!\".as_bytes()).expect(\"Failed to write to stdin\");\n    /// });\n    ///\n    /// let output = child.wait_with_output().expect(\"Failed to read stdout\");\n    /// assert_eq!(String::from_utf8_lossy(&output.stdout), \"!dlrow ,olleH\");\n    /// ```\n    ///\n    /// Writing more than a pipe buffer's worth of input to stdin without also reading\n    /// stdout and stderr at the same time may cause a deadlock.\n    /// This is an issue when running any program that doesn't guarantee that it reads\n    /// its entire stdin before writing more than a pipe buffer's worth of output.\n    /// The size of a pipe buffer varies on different targets.\n    ///\n    #[must_use]\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn piped() -> Stdio {\n        Stdio(imp::Stdio::MakePipe)\n    }\n\n    /// The child inherits from the corresponding parent descriptor.\n    ///\n    /// # Examples\n    ///\n    /// With stdout:\n    ///\n    /// ```no_run\n    /// use std::process::{Command, Stdio};\n    ///\n    /// let output = Command::new(\"echo\")\n    ///     .arg(\"Hello, world!\")\n    ///     .stdout(Stdio::inherit())\n    ///     .output()\n    ///     .expect(\"Failed to execute command\");\n    ///\n    /// assert_eq!(String::from_utf8_lossy(&output.stdout), \"\");\n    /// // \"Hello, world!\" echoed to console\n    /// ```\n    ///\n    /// With stdin:\n    ///\n    /// ```no_run\n    /// use std::process::{Command, Stdio};\n    /// use std::io::{self, Write};\n    ///\n    /// let output = Command::new(\"rev\")\n    ///     .stdin(Stdio::inherit())\n    ///     .stdout(Stdio::piped())\n    ///     .output()?;\n    ///\n    /// print!(\"You piped in the reverse of: \");\n    /// io::stdout().write_all(&output.stdout)?;\n    /// # io::Result::Ok(())\n    /// ```\n    #[must_use]\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn inherit() -> Stdio {\n        Stdio(imp::Stdio::Inherit)\n    }\n\n    /// This stream will be ignored. This is the equivalent of attaching the\n    /// stream to `/dev/null`.\n    ///\n    /// # Examples\n    ///\n    /// With stdout:\n    ///\n    /// ```no_run\n    /// use std::process::{Command, Stdio};\n    ///\n    /// let output = Command::new(\"echo\")\n    ///     .arg(\"Hello, world!\")\n    ///     .stdout(Stdio::null())\n    ///     .output()\n    ///     .expect(\"Failed to execute command\");\n    ///\n    /// assert_eq!(String::from_utf8_lossy(&output.stdout), \"\");\n    /// // Nothing echoed to console\n    /// ```\n    ///\n    /// With stdin:\n    ///\n    /// ```no_run\n    /// use std::process::{Command, Stdio};\n    ///\n    /// let output = Command::new(\"rev\")\n    ///     .stdin(Stdio::null())\n    ///     .stdout(Stdio::piped())\n    ///     .output()\n    ///     .expect(\"Failed to execute command\");\n    ///\n    /// assert_eq!(String::from_utf8_lossy(&output.stdout), \"\");\n    /// // Ignores any piped-in input\n    /// ```\n    #[must_use]\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn null() -> Stdio {\n        Stdio(imp::Stdio::Null)\n    }\n\n    /// Returns `true` if this requires [`Command`] to create a new pipe.\n    ///\n    /// # Example\n    ///\n    /// ```\n    /// #![feature(stdio_makes_pipe)]\n    /// use std::process::Stdio;\n    ///\n    /// let io = Stdio::piped();\n    /// assert_eq!(io.makes_pipe(), true);\n    /// ```\n    #[unstable(feature = \"stdio_makes_pipe\", issue = \"98288\")]\n    pub fn makes_pipe(&self) -> bool {\n        matches!(self.0, imp::Stdio::MakePipe)\n    }\n}\n\nimpl FromInner<imp::Stdio> for Stdio {\n    fn from_inner(inner: imp::Stdio) -> Stdio {\n        Stdio(inner)\n    }\n}\n\n#[stable(feature = \"std_debug\", since = \"1.16.0\")]\nimpl fmt::Debug for Stdio {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        f.debug_struct(\"Stdio\").finish_non_exhaustive()\n    }\n}\n\n#[stable(feature = \"stdio_from\", since = \"1.20.0\")]\nimpl From<ChildStdin> for Stdio {\n    /// Converts a [`ChildStdin`] into a [`Stdio`].\n    ///\n    /// # Examples\n    ///\n    /// `ChildStdin` will be converted to `Stdio` using `Stdio::from` under the hood.\n    ///\n    /// ```rust,no_run\n    /// use std::process::{Command, Stdio};\n    ///\n    /// let reverse = Command::new(\"rev\")\n    ///     .stdin(Stdio::piped())\n    ///     .spawn()\n    ///     .expect(\"failed reverse command\");\n    ///\n    /// let _echo = Command::new(\"echo\")\n    ///     .arg(\"Hello, world!\")\n    ///     .stdout(reverse.stdin.unwrap()) // Converted into a Stdio here\n    ///     .output()\n    ///     .expect(\"failed echo command\");\n    ///\n    /// // \"!dlrow ,olleH\" echoed to console\n    /// ```\n    fn from(child: ChildStdin) -> Stdio {\n        Stdio::from_inner(child.into_inner().into())\n    }\n}\n\n#[stable(feature = \"stdio_from\", since = \"1.20.0\")]\nimpl From<ChildStdout> for Stdio {\n    /// Converts a [`ChildStdout`] into a [`Stdio`].\n    ///\n    /// # Examples\n    ///\n    /// `ChildStdout` will be converted to `Stdio` using `Stdio::from` under the hood.\n    ///\n    /// ```rust,no_run\n    /// use std::process::{Command, Stdio};\n    ///\n    /// let hello = Command::new(\"echo\")\n    ///     .arg(\"Hello, world!\")\n    ///     .stdout(Stdio::piped())\n    ///     .spawn()\n    ///     .expect(\"failed echo command\");\n    ///\n    /// let reverse = Command::new(\"rev\")\n    ///     .stdin(hello.stdout.unwrap())  // Converted into a Stdio here\n    ///     .output()\n    ///     .expect(\"failed reverse command\");\n    ///\n    /// assert_eq!(reverse.stdout, b\"!dlrow ,olleH\\n\");\n    /// ```\n    fn from(child: ChildStdout) -> Stdio {\n        Stdio::from_inner(child.into_inner().into())\n    }\n}\n\n#[stable(feature = \"stdio_from\", since = \"1.20.0\")]\nimpl From<ChildStderr> for Stdio {\n    /// Converts a [`ChildStderr`] into a [`Stdio`].\n    ///\n    /// # Examples\n    ///\n    /// ```rust,no_run\n    /// use std::process::{Command, Stdio};\n    ///\n    /// let reverse = Command::new(\"rev\")\n    ///     .arg(\"non_existing_file.txt\")\n    ///     .stderr(Stdio::piped())\n    ///     .spawn()\n    ///     .expect(\"failed reverse command\");\n    ///\n    /// let cat = Command::new(\"cat\")\n    ///     .arg(\"-\")\n    ///     .stdin(reverse.stderr.unwrap()) // Converted into a Stdio here\n    ///     .output()\n    ///     .expect(\"failed echo command\");\n    ///\n    /// assert_eq!(\n    ///     String::from_utf8_lossy(&cat.stdout),\n    ///     \"rev: cannot open non_existing_file.txt: No such file or directory\\n\"\n    /// );\n    /// ```\n    fn from(child: ChildStderr) -> Stdio {\n        Stdio::from_inner(child.into_inner().into())\n    }\n}\n\n#[stable(feature = \"stdio_from\", since = \"1.20.0\")]\nimpl From<fs::File> for Stdio {\n    /// Converts a [`File`](fs::File) into a [`Stdio`].\n    ///\n    /// # Examples\n    ///\n    /// `File` will be converted to `Stdio` using `Stdio::from` under the hood.\n    ///\n    /// ```rust,no_run\n    /// use std::fs::File;\n    /// use std::process::Command;\n    ///\n    /// // With the `foo.txt` file containing \"Hello, world!\"\n    /// let file = File::open(\"foo.txt\")?;\n    ///\n    /// let reverse = Command::new(\"rev\")\n    ///     .stdin(file)  // Implicit File conversion into a Stdio\n    ///     .output()?;\n    ///\n    /// assert_eq!(reverse.stdout, b\"!dlrow ,olleH\");\n    /// # std::io::Result::Ok(())\n    /// ```\n    fn from(file: fs::File) -> Stdio {\n        Stdio::from_inner(file.into_inner().into())\n    }\n}\n\n#[stable(feature = \"stdio_from_stdio\", since = \"1.74.0\")]\nimpl From<io::Stdout> for Stdio {\n    /// Redirect command stdout/stderr to our stdout\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// #![feature(exit_status_error)]\n    /// use std::io;\n    /// use std::process::Command;\n    ///\n    /// # fn test() -> Result<(), Box<dyn std::error::Error>> {\n    /// let output = Command::new(\"whoami\")\n    // \"whoami\" is a command which exists on both Unix and Windows,\n    // and which succeeds, producing some stdout output but no stderr.\n    ///     .stdout(io::stdout())\n    ///     .output()?;\n    /// output.status.exit_ok()?;\n    /// assert!(output.stdout.is_empty());\n    /// # Ok(())\n    /// # }\n    /// #\n    /// # if cfg!(all(unix, not(target_os = \"android\"), not(all(target_vendor = \"apple\", not(target_os = \"macos\"))))) {\n    /// #     test().unwrap();\n    /// # }\n    /// ```\n    fn from(inherit: io::Stdout) -> Stdio {\n        Stdio::from_inner(inherit.into())\n    }\n}\n\n#[stable(feature = \"stdio_from_stdio\", since = \"1.74.0\")]\nimpl From<io::Stderr> for Stdio {\n    /// Redirect command stdout/stderr to our stderr\n    ///\n    /// # Examples\n    ///\n    /// ```rust\n    /// #![feature(exit_status_error)]\n    /// use std::io;\n    /// use std::process::Command;\n    ///\n    /// # fn test() -> Result<(), Box<dyn std::error::Error>> {\n    /// let output = Command::new(\"whoami\")\n    ///     .stdout(io::stderr())\n    ///     .output()?;\n    /// output.status.exit_ok()?;\n    /// assert!(output.stdout.is_empty());\n    /// # Ok(())\n    /// # }\n    /// #\n    /// # if cfg!(all(unix, not(target_os = \"android\"), not(all(target_vendor = \"apple\", not(target_os = \"macos\"))))) {\n    /// #     test().unwrap();\n    /// # }\n    /// ```\n    fn from(inherit: io::Stderr) -> Stdio {\n        Stdio::from_inner(inherit.into())\n    }\n}\n\n#[stable(feature = \"anonymous_pipe\", since = \"1.87.0\")]\nimpl From<io::PipeWriter> for Stdio {\n    fn from(pipe: io::PipeWriter) -> Self {\n        Stdio::from_inner(pipe.into_inner().into())\n    }\n}\n\n#[stable(feature = \"anonymous_pipe\", since = \"1.87.0\")]\nimpl From<io::PipeReader> for Stdio {\n    fn from(pipe: io::PipeReader) -> Self {\n        Stdio::from_inner(pipe.into_inner().into())\n    }\n}\n\n/// Describes the result of a process after it has terminated.\n///\n/// This `struct` is used to represent the exit status or other termination of a child process.\n/// Child processes are created via the [`Command`] struct and their exit\n/// status is exposed through the [`status`] method, or the [`wait`] method\n/// of a [`Child`] process.\n///\n/// An `ExitStatus` represents every possible disposition of a process.  On Unix this\n/// is the **wait status**.  It is *not* simply an *exit status* (a value passed to `exit`).\n///\n/// For proper error reporting of failed processes, print the value of `ExitStatus` or\n/// `ExitStatusError` using their implementations of [`Display`](crate::fmt::Display).\n///\n/// # Differences from `ExitCode`\n///\n/// [`ExitCode`] is intended for terminating the currently running process, via\n/// the `Termination` trait, in contrast to `ExitStatus`, which represents the\n/// termination of a child process. These APIs are separate due to platform\n/// compatibility differences and their expected usage; it is not generally\n/// possible to exactly reproduce an `ExitStatus` from a child for the current\n/// process after the fact.\n///\n/// [`status`]: Command::status\n/// [`wait`]: Child::wait\n//\n// We speak slightly loosely (here and in various other places in the stdlib docs) about `exit`\n// vs `_exit`.  Naming of Unix system calls is not standardised across Unices, so terminology is a\n// matter of convention and tradition.  For clarity we usually speak of `exit`, even when we might\n// mean an underlying system call such as `_exit`.\n#[derive(PartialEq, Eq, Clone, Copy, Debug)]\n#[stable(feature = \"process\", since = \"1.0.0\")]\npub struct ExitStatus(imp::ExitStatus);\n\n/// The default value is one which indicates successful completion.\n#[stable(feature = \"process_exitstatus_default\", since = \"1.73.0\")]\nimpl Default for ExitStatus {\n    fn default() -> Self {\n        // Ideally this would be done by ExitCode::default().into() but that is complicated.\n        ExitStatus::from_inner(imp::ExitStatus::default())\n    }\n}\n\nimpl ExitStatus {\n    /// Was termination successful?  Returns a `Result`.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// #![feature(exit_status_error)]\n    /// # if cfg!(all(unix, not(all(target_vendor = \"apple\", not(target_os = \"macos\"))))) {\n    /// use std::process::Command;\n    ///\n    /// let status = Command::new(\"ls\")\n    ///     .arg(\"/dev/nonexistent\")\n    ///     .status()\n    ///     .expect(\"ls could not be executed\");\n    ///\n    /// println!(\"ls: {status}\");\n    /// status.exit_ok().expect_err(\"/dev/nonexistent could be listed!\");\n    /// # } // cfg!(unix)\n    /// ```\n    #[unstable(feature = \"exit_status_error\", issue = \"84908\")]\n    pub fn exit_ok(&self) -> Result<(), ExitStatusError> {\n        self.0.exit_ok().map_err(ExitStatusError)\n    }\n\n    /// Was termination successful? Signal termination is not considered a\n    /// success, and success is defined as a zero exit status.\n    ///\n    /// # Examples\n    ///\n    /// ```rust,no_run\n    /// use std::process::Command;\n    ///\n    /// let status = Command::new(\"mkdir\")\n    ///     .arg(\"projects\")\n    ///     .status()\n    ///     .expect(\"failed to execute mkdir\");\n    ///\n    /// if status.success() {\n    ///     println!(\"'projects/' directory created\");\n    /// } else {\n    ///     println!(\"failed to create 'projects/' directory: {status}\");\n    /// }\n    /// ```\n    #[must_use]\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn success(&self) -> bool {\n        self.0.exit_ok().is_ok()\n    }\n\n    /// Returns the exit code of the process, if any.\n    ///\n    /// In Unix terms the return value is the **exit status**: the value passed to `exit`, if the\n    /// process finished by calling `exit`.  Note that on Unix the exit status is truncated to 8\n    /// bits, and that values that didn't come from a program's call to `exit` may be invented by the\n    /// runtime system (often, for example, 255, 254, 127 or 126).\n    ///\n    /// On Unix, this will return `None` if the process was terminated by a signal.\n    /// [`ExitStatusExt`](crate::os::unix::process::ExitStatusExt) is an\n    /// extension trait for extracting any such signal, and other details, from the `ExitStatus`.\n    ///\n    /// # Examples\n    ///\n    /// ```no_run\n    /// use std::process::Command;\n    ///\n    /// let status = Command::new(\"mkdir\")\n    ///     .arg(\"projects\")\n    ///     .status()\n    ///     .expect(\"failed to execute mkdir\");\n    ///\n    /// match status.code() {\n    ///     Some(code) => println!(\"Exited with status code: {code}\"),\n    ///     None => println!(\"Process terminated by signal\")\n    /// }\n    /// ```\n    #[must_use]\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn code(&self) -> Option<i32> {\n        self.0.code()\n    }\n}\n\nimpl AsInner<imp::ExitStatus> for ExitStatus {\n    #[inline]\n    fn as_inner(&self) -> &imp::ExitStatus {\n        &self.0\n    }\n}\n\nimpl FromInner<imp::ExitStatus> for ExitStatus {\n    fn from_inner(s: imp::ExitStatus) -> ExitStatus {\n        ExitStatus(s)\n    }\n}\n\n#[stable(feature = \"process\", since = \"1.0.0\")]\nimpl fmt::Display for ExitStatus {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        self.0.fmt(f)\n    }\n}\n\n/// Describes the result of a process after it has failed\n///\n/// Produced by the [`.exit_ok`](ExitStatus::exit_ok) method on [`ExitStatus`].\n///\n/// # Examples\n///\n/// ```\n/// #![feature(exit_status_error)]\n/// # if cfg!(all(unix, not(target_os = \"android\"), not(all(target_vendor = \"apple\", not(target_os = \"macos\"))))) {\n/// use std::process::{Command, ExitStatusError};\n///\n/// fn run(cmd: &str) -> Result<(), ExitStatusError> {\n///     Command::new(cmd).status().unwrap().exit_ok()?;\n///     Ok(())\n/// }\n///\n/// run(\"true\").unwrap();\n/// run(\"false\").unwrap_err();\n/// # } // cfg!(unix)\n/// ```\n#[derive(PartialEq, Eq, Clone, Copy, Debug)]\n#[unstable(feature = \"exit_status_error\", issue = \"84908\")]\n// The definition of imp::ExitStatusError should ideally be such that\n// Result<(), imp::ExitStatusError> has an identical representation to imp::ExitStatus.\npub struct ExitStatusError(imp::ExitStatusError);\n\n#[unstable(feature = \"exit_status_error\", issue = \"84908\")]\n#[doc(test(attr(allow(unused_features))))]\nimpl ExitStatusError {\n    /// Reports the exit code, if applicable, from an `ExitStatusError`.\n    ///\n    /// In Unix terms the return value is the **exit status**: the value passed to `exit`, if the\n    /// process finished by calling `exit`.  Note that on Unix the exit status is truncated to 8\n    /// bits, and that values that didn't come from a program's call to `exit` may be invented by the\n    /// runtime system (often, for example, 255, 254, 127 or 126).\n    ///\n    /// On Unix, this will return `None` if the process was terminated by a signal.  If you want to\n    /// handle such situations specially, consider using methods from\n    /// [`ExitStatusExt`](crate::os::unix::process::ExitStatusExt).\n    ///\n    /// If the process finished by calling `exit` with a nonzero value, this will return\n    /// that exit status.\n    ///\n    /// If the error was something else, it will return `None`.\n    ///\n    /// If the process exited successfully (ie, by calling `exit(0)`), there is no\n    /// `ExitStatusError`.  So the return value from `ExitStatusError::code()` is always nonzero.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// #![feature(exit_status_error)]\n    /// # #[cfg(all(unix, not(target_os = \"android\"), not(all(target_vendor = \"apple\", not(target_os = \"macos\")))))] {\n    /// use std::process::Command;\n    ///\n    /// let bad = Command::new(\"false\").status().unwrap().exit_ok().unwrap_err();\n    /// assert_eq!(bad.code(), Some(1));\n    /// # } // #[cfg(unix)]\n    /// ```\n    #[must_use]\n    pub fn code(&self) -> Option<i32> {\n        self.code_nonzero().map(Into::into)\n    }\n\n    /// Reports the exit code, if applicable, from an `ExitStatusError`, as a [`NonZero`].\n    ///\n    /// This is exactly like [`code()`](Self::code), except that it returns a <code>[NonZero]<[i32]></code>.\n    ///\n    /// Plain `code`, returning a plain integer, is provided because it is often more convenient.\n    /// The returned value from `code()` is indeed also nonzero; use `code_nonzero()` when you want\n    /// a type-level guarantee of nonzeroness.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// #![feature(exit_status_error)]\n    ///\n    /// # if cfg!(all(unix, not(target_os = \"android\"), not(all(target_vendor = \"apple\", not(target_os = \"macos\"))))) {\n    /// use std::num::NonZero;\n    /// use std::process::Command;\n    ///\n    /// let bad = Command::new(\"false\").status().unwrap().exit_ok().unwrap_err();\n    /// assert_eq!(bad.code_nonzero().unwrap(), NonZero::new(1).unwrap());\n    /// # } // cfg!(unix)\n    /// ```\n    #[must_use]\n    pub fn code_nonzero(&self) -> Option<NonZero<i32>> {\n        self.0.code()\n    }\n\n    /// Converts an `ExitStatusError` (back) to an `ExitStatus`.\n    #[must_use]\n    pub fn into_status(&self) -> ExitStatus {\n        ExitStatus(self.0.into())\n    }\n}\n\n#[unstable(feature = \"exit_status_error\", issue = \"84908\")]\nimpl From<ExitStatusError> for ExitStatus {\n    fn from(error: ExitStatusError) -> Self {\n        Self(error.0.into())\n    }\n}\n\n#[unstable(feature = \"exit_status_error\", issue = \"84908\")]\nimpl fmt::Display for ExitStatusError {\n    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {\n        write!(f, \"process exited unsuccessfully: {}\", self.into_status())\n    }\n}\n\n#[unstable(feature = \"exit_status_error\", issue = \"84908\")]\nimpl crate::error::Error for ExitStatusError {}\n\n/// This type represents the status code the current process can return\n/// to its parent under normal termination.\n///\n/// `ExitCode` is intended to be consumed only by the standard library (via\n/// [`Termination::report()`]). For forwards compatibility with potentially\n/// unusual targets, this type currently does not provide `Eq`, `Hash`, or\n/// access to the raw value. This type does provide `PartialEq` for\n/// comparison, but note that there may potentially be multiple failure\n/// codes, some of which will _not_ compare equal to `ExitCode::FAILURE`.\n/// The standard library provides the canonical `SUCCESS` and `FAILURE`\n/// exit codes as well as `From<u8> for ExitCode` for constructing other\n/// arbitrary exit codes.\n///\n/// # Portability\n///\n/// Numeric values used in this type don't have portable meanings, and\n/// different platforms may mask different amounts of them.\n///\n/// For the platform's canonical successful and unsuccessful codes, see\n/// the [`SUCCESS`] and [`FAILURE`] associated items.\n///\n/// [`SUCCESS`]: ExitCode::SUCCESS\n/// [`FAILURE`]: ExitCode::FAILURE\n///\n/// # Differences from `ExitStatus`\n///\n/// `ExitCode` is intended for terminating the currently running process, via\n/// the `Termination` trait, in contrast to [`ExitStatus`], which represents the\n/// termination of a child process. These APIs are separate due to platform\n/// compatibility differences and their expected usage; it is not generally\n/// possible to exactly reproduce an `ExitStatus` from a child for the current\n/// process after the fact.\n///\n/// # Examples\n///\n/// `ExitCode` can be returned from the `main` function of a crate, as it implements\n/// [`Termination`]:\n///\n/// ```\n/// use std::process::ExitCode;\n/// # fn check_foo() -> bool { true }\n///\n/// fn main() -> ExitCode {\n///     if !check_foo() {\n///         return ExitCode::from(42);\n///     }\n///\n///     ExitCode::SUCCESS\n/// }\n/// ```\n#[derive(Clone, Copy, Debug, PartialEq)]\n#[stable(feature = \"process_exitcode\", since = \"1.61.0\")]\npub struct ExitCode(imp::ExitCode);\n\n#[stable(feature = \"process_exitcode\", since = \"1.61.0\")]\nimpl ExitCode {\n    /// The canonical `ExitCode` for successful termination on this platform.\n    ///\n    /// Note that a `()`-returning `main` implicitly results in a successful\n    /// termination, so there's no need to return this from `main` unless\n    /// you're also returning other possible codes.\n    #[stable(feature = \"process_exitcode\", since = \"1.61.0\")]\n    pub const SUCCESS: ExitCode = ExitCode(imp::ExitCode::SUCCESS);\n\n    /// The canonical `ExitCode` for unsuccessful termination on this platform.\n    ///\n    /// If you're only returning this and `SUCCESS` from `main`, consider\n    /// instead returning `Err(_)` and `Ok(())` respectively, which will\n    /// return the same codes (but will also `eprintln!` the error).\n    #[stable(feature = \"process_exitcode\", since = \"1.61.0\")]\n    pub const FAILURE: ExitCode = ExitCode(imp::ExitCode::FAILURE);\n\n    /// Exit the current process with the given `ExitCode`.\n    ///\n    /// Note that this has the same caveats as [`process::exit()`][exit], namely that this function\n    /// terminates the process immediately, so no destructors on the current stack or any other\n    /// thread's stack will be run. Also see those docs for some important notes on interop with C\n    /// code. If a clean shutdown is needed, it is recommended to simply return this ExitCode from\n    /// the `main` function, as demonstrated in the [type documentation](#examples).\n    ///\n    /// # Differences from `process::exit()`\n    ///\n    /// `process::exit()` accepts any `i32` value as the exit code for the process; however, there\n    /// are platforms that only use a subset of that value (see [`process::exit` platform-specific\n    /// behavior][exit#platform-specific-behavior]). `ExitCode` exists because of this; only\n    /// `ExitCode`s that are supported by a majority of our platforms can be created, so those\n    /// problems don't exist (as much) with this method.\n    ///\n    /// # Examples\n    ///\n    /// ```\n    /// #![feature(exitcode_exit_method)]\n    /// # use std::process::ExitCode;\n    /// # use std::fmt;\n    /// # enum UhOhError { GenericProblem, Specific, WithCode { exit_code: ExitCode, _x: () } }\n    /// # impl fmt::Display for UhOhError {\n    /// #     fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result { unimplemented!() }\n    /// # }\n    /// // there's no way to gracefully recover from an UhOhError, so we just\n    /// // print a message and exit\n    /// fn handle_unrecoverable_error(err: UhOhError) -> ! {\n    ///     eprintln!(\"UH OH! {err}\");\n    ///     let code = match err {\n    ///         UhOhError::GenericProblem => ExitCode::FAILURE,\n    ///         UhOhError::Specific => ExitCode::from(3),\n    ///         UhOhError::WithCode { exit_code, .. } => exit_code,\n    ///     };\n    ///     code.exit_process()\n    /// }\n    /// ```\n    #[unstable(feature = \"exitcode_exit_method\", issue = \"97100\")]\n    pub fn exit_process(self) -> ! {\n        exit(self.to_i32())\n    }\n}\n\nimpl ExitCode {\n    // This is private/perma-unstable because ExitCode is opaque; we don't know that i32 will serve\n    // all usecases, for example windows seems to use u32, unix uses the 8-15th bits of an i32, we\n    // likely want to isolate users anything that could restrict the platform specific\n    // representation of an ExitCode\n    //\n    // More info: https://internals.rust-lang.org/t/mini-pre-rfc-redesigning-process-exitstatus/5426\n    /// Converts an `ExitCode` into an i32\n    #[unstable(\n        feature = \"process_exitcode_internals\",\n        reason = \"exposed only for libstd\",\n        issue = \"none\"\n    )]\n    #[inline]\n    #[doc(hidden)]\n    pub fn to_i32(self) -> i32 {\n        self.0.as_i32()\n    }\n}\n\n/// The default value is [`ExitCode::SUCCESS`]\n#[stable(feature = \"process_exitcode_default\", since = \"1.75.0\")]\nimpl Default for ExitCode {\n    fn default() -> Self {\n        ExitCode::SUCCESS\n    }\n}\n\n#[stable(feature = \"process_exitcode\", since = \"1.61.0\")]\nimpl From<u8> for ExitCode {\n    /// Constructs an `ExitCode` from an arbitrary u8 value.\n    fn from(code: u8) -> Self {\n        ExitCode(imp::ExitCode::from(code))\n    }\n}\n\nimpl AsInner<imp::ExitCode> for ExitCode {\n    #[inline]\n    fn as_inner(&self) -> &imp::ExitCode {\n        &self.0\n    }\n}\n\nimpl FromInner<imp::ExitCode> for ExitCode {\n    fn from_inner(s: imp::ExitCode) -> ExitCode {\n        ExitCode(s)\n    }\n}\n\nimpl Child {\n    /// Forces the child process to exit. If the child has already exited, `Ok(())`\n    /// is returned.\n    ///\n    /// The mapping to [`ErrorKind`]s is not part of the compatibility contract of the function.\n    ///\n    /// This is equivalent to sending a SIGKILL on Unix platforms.\n    ///\n    /// # Examples\n    ///\n    /// ```no_run\n    /// use std::process::Command;\n    ///\n    /// let mut command = Command::new(\"yes\");\n    /// if let Ok(mut child) = command.spawn() {\n    ///     child.kill().expect(\"command couldn't be killed\");\n    /// } else {\n    ///     println!(\"yes command didn't start\");\n    /// }\n    /// ```\n    ///\n    /// [`ErrorKind`]: io::ErrorKind\n    /// [`InvalidInput`]: io::ErrorKind::InvalidInput\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    #[cfg_attr(not(test), rustc_diagnostic_item = \"child_kill\")]\n    pub fn kill(&mut self) -> io::Result<()> {\n        self.handle.kill()\n    }\n\n    /// Returns the OS-assigned process identifier associated with this child.\n    ///\n    /// # Examples\n    ///\n    /// ```no_run\n    /// use std::process::Command;\n    ///\n    /// let mut command = Command::new(\"ls\");\n    /// if let Ok(child) = command.spawn() {\n    ///     println!(\"Child's ID is {}\", child.id());\n    /// } else {\n    ///     println!(\"ls command didn't start\");\n    /// }\n    /// ```\n    #[must_use]\n    #[stable(feature = \"process_id\", since = \"1.3.0\")]\n    #[cfg_attr(not(test), rustc_diagnostic_item = \"child_id\")]\n    pub fn id(&self) -> u32 {\n        self.handle.id()\n    }\n\n    /// Waits for the child to exit completely, returning the status that it\n    /// exited with. This function will continue to have the same return value\n    /// after it has been called at least once.\n    ///\n    /// The stdin handle to the child process, if any, will be closed\n    /// before waiting. This helps avoid deadlock: it ensures that the\n    /// child does not block waiting for input from the parent, while\n    /// the parent waits for the child to exit.\n    ///\n    /// # Examples\n    ///\n    /// ```no_run\n    /// use std::process::Command;\n    ///\n    /// let mut command = Command::new(\"ls\");\n    /// if let Ok(mut child) = command.spawn() {\n    ///     child.wait().expect(\"command wasn't running\");\n    ///     println!(\"Child has finished its execution!\");\n    /// } else {\n    ///     println!(\"ls command didn't start\");\n    /// }\n    /// ```\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn wait(&mut self) -> io::Result<ExitStatus> {\n        drop(self.stdin.take());\n        self.handle.wait().map(ExitStatus)\n    }\n\n    /// Attempts to collect the exit status of the child if it has already\n    /// exited.\n    ///\n    /// This function will not block the calling thread and will only\n    /// check to see if the child process has exited or not. If the child has\n    /// exited then on Unix the process ID is reaped. This function is\n    /// guaranteed to repeatedly return a successful exit status so long as the\n    /// child has already exited.\n    ///\n    /// If the child has exited, then `Ok(Some(status))` is returned. If the\n    /// exit status is not available at this time then `Ok(None)` is returned.\n    /// If an error occurs, then that error is returned.\n    ///\n    /// Note that unlike `wait`, this function will not attempt to drop stdin.\n    ///\n    /// # Examples\n    ///\n    /// ```no_run\n    /// use std::process::Command;\n    ///\n    /// let mut child = Command::new(\"ls\").spawn()?;\n    ///\n    /// match child.try_wait() {\n    ///     Ok(Some(status)) => println!(\"exited with: {status}\"),\n    ///     Ok(None) => {\n    ///         println!(\"status not ready yet, let's really wait\");\n    ///         let res = child.wait();\n    ///         println!(\"result: {res:?}\");\n    ///     }\n    ///     Err(e) => println!(\"error attempting to wait: {e}\"),\n    /// }\n    /// # std::io::Result::Ok(())\n    /// ```\n    #[stable(feature = \"process_try_wait\", since = \"1.18.0\")]\n    pub fn try_wait(&mut self) -> io::Result<Option<ExitStatus>> {\n        Ok(self.handle.try_wait()?.map(ExitStatus))\n    }\n\n    /// Simultaneously waits for the child to exit and collect all remaining\n    /// output on the stdout/stderr handles, returning an `Output`\n    /// instance.\n    ///\n    /// The stdin handle to the child process, if any, will be closed\n    /// before waiting. This helps avoid deadlock: it ensures that the\n    /// child does not block waiting for input from the parent, while\n    /// the parent waits for the child to exit.\n    ///\n    /// By default, stdin, stdout and stderr are inherited from the parent.\n    /// In order to capture the output into this `Result<Output>` it is\n    /// necessary to create new pipes between parent and child. Use\n    /// `stdout(Stdio::piped())` or `stderr(Stdio::piped())`, respectively.\n    ///\n    /// # Examples\n    ///\n    /// ```should_panic\n    /// use std::process::{Command, Stdio};\n    ///\n    /// let child = Command::new(\"/bin/cat\")\n    ///     .arg(\"file.txt\")\n    ///     .stdout(Stdio::piped())\n    ///     .spawn()\n    ///     .expect(\"failed to execute child\");\n    ///\n    /// let output = child\n    ///     .wait_with_output()\n    ///     .expect(\"failed to wait on child\");\n    ///\n    /// assert!(output.status.success());\n    /// ```\n    ///\n    #[stable(feature = \"process\", since = \"1.0.0\")]\n    pub fn wait_with_output(mut self) -> io::Result<Output> {\n        drop(self.stdin.take());\n\n        let (mut stdout, mut stderr) = (Vec::new(), Vec::new());\n        match (self.stdout.take(), self.stderr.take()) {\n            (None, None) => {}\n            (Some(mut out), None) => {\n                let res = out.read_to_end(&mut stdout);\n                res.unwrap();\n            }\n            (None, Some(mut err)) => {\n                let res = err.read_to_end(&mut stderr);\n                res.unwrap();\n            }\n            (Some(out), Some(err)) => {\n                let res = imp::read_output(out.inner, &mut stdout, err.inner, &mut stderr);\n                res.unwrap();\n            }\n        }\n\n        let status = self.wait()?;\n        Ok(Output { status, stdout, stderr })\n    }\n}\n\n/// Terminates the current process with the specified exit code.\n///\n/// This function will never return and will immediately terminate the current\n/// process. The exit code is passed through to the underlying OS and will be\n/// available for consumption by another process.\n///\n/// Note that because this function never returns, and that it terminates the\n/// process, no destructors on the current stack or any other thread's stack\n/// will be run. If a clean shutdown is needed it is recommended to only call\n/// this function at a known point where there are no more destructors left\n/// to run; or, preferably, simply return a type implementing [`Termination`]\n/// (such as [`ExitCode`] or `Result`) from the `main` function and avoid this\n/// function altogether:\n///\n/// ```\n/// # use std::io::Error as MyError;\n/// fn main() -> Result<(), MyError> {\n///     // ...\n///     Ok(())\n/// }\n/// ```\n///\n/// In its current implementation, this function will execute exit handlers registered with `atexit`\n/// as well as other platform-specific exit handlers (e.g. `fini` sections of ELF shared objects).\n/// This means that Rust requires that all exit handlers are safe to execute at any time. In\n/// particular, if an exit handler cleans up some state that might be concurrently accessed by other\n/// threads, it is required that the exit handler performs suitable synchronization with those\n/// threads. (The alternative to this requirement would be to not run exit handlers at all, which is\n/// considered undesirable. Note that returning from `main` also calls `exit`, so making `exit` an\n/// unsafe operation is not an option.)\n///\n/// ## Platform-specific behavior\n///\n/// **Unix**: On Unix-like platforms, it is unlikely that all 32 bits of `exit`\n/// will be visible to a parent process inspecting the exit code. On most\n/// Unix-like platforms, only the eight least-significant bits are considered.\n///\n/// For example, the exit code for this example will be `0` on Linux, but `256`\n/// on Windows:\n///\n/// ```no_run\n/// use std::process;\n///\n/// process::exit(0x0100);\n/// ```\n///\n/// ### Safe interop with C code\n///\n/// On Unix, this function is currently implemented using the `exit` C function [`exit`][C-exit]. As\n/// of C23, the C standard does not permit multiple threads to call `exit` concurrently. Rust\n/// mitigates this with a lock, but if C code calls `exit`, that can still cause undefined behavior.\n/// Note that returning from `main` is equivalent to calling `exit`.\n///\n/// Therefore, it is undefined behavior to have two concurrent threads perform the following\n/// without synchronization:\n/// - One thread calls Rust's `exit` function or returns from Rust's `main` function\n/// - Another thread calls the C function `exit` or `quick_exit`, or returns from C's `main` function\n///\n/// Note that if a binary contains multiple copies of the Rust runtime (e.g., when combining\n/// multiple `cdylib` or `staticlib`), they each have their own separate lock, so from the\n/// perspective of code running in one of the Rust runtimes, the \"outside\" Rust code is basically C\n/// code, and concurrent `exit` again causes undefined behavior.\n///\n/// Individual C implementations might provide more guarantees than the standard and permit concurrent\n/// calls to `exit`; consult the documentation of your C implementation for details.\n///\n/// For some of the on-going discussion to make `exit` thread-safe in C, see:\n/// - [Rust issue #126600](https://github.com/rust-lang/rust/issues/126600)\n/// - [Austin Group Bugzilla (for POSIX)](https://austingroupbugs.net/view.php?id=1845)\n/// - [GNU C library Bugzilla](https://sourceware.org/bugzilla/show_bug.cgi?id=31997)\n///\n/// [C-exit]: https://en.cppreference.com/w/c/program/exit\n#[stable(feature = \"rust1\", since = \"1.0.0\")]\n#[cfg_attr(not(test), rustc_diagnostic_item = \"process_exit\")]\npub fn exit(code: i32) -> ! {\n    crate::rt::cleanup();\n    crate::sys::exit::exit(code)\n}\n\n/// Terminates the process in an abnormal fashion.\n///\n/// The function will never return and will immediately terminate the current\n/// process in a platform specific \"abnormal\" manner. As a consequence,\n/// no destructors on the current stack or any other thread's stack\n/// will be run, Rust IO buffers (eg, from `BufWriter`) will not be flushed,\n/// and C stdio buffers will (on most platforms) not be flushed.\n///\n/// This is in contrast to the default behavior of [`panic!`] which unwinds\n/// the current thread's stack and calls all destructors.\n/// When `panic=\"abort\"` is set, either as an argument to `rustc` or in a\n/// crate's Cargo.toml, [`panic!`] and `abort` are similar. However,\n/// [`panic!`] will still call the [panic hook] while `abort` will not.\n///\n/// If a clean shutdown is needed it is recommended to only call\n/// this function at a known point where there are no more destructors left\n/// to run.\n///\n/// The process's termination will be similar to that from the C `abort()`\n/// function.  On Unix, the process will terminate with signal `SIGABRT`, which\n/// typically means that the shell prints \"Aborted\".\n///\n/// # Examples\n///\n/// ```no_run\n/// use std::process;\n///\n/// fn main() {\n///     println!(\"aborting\");\n///\n///     process::abort();\n///\n///     // execution never gets here\n/// }\n/// ```\n///\n/// The `abort` function terminates the process, so the destructor will not\n/// get run on the example below:\n///\n/// ```no_run\n/// use std::process;\n///\n/// struct HasDrop;\n///\n/// impl Drop for HasDrop {\n///     fn drop(&mut self) {\n///         println!(\"This will never be printed!\");\n///     }\n/// }\n///\n/// fn main() {\n///     let _x = HasDrop;\n///     process::abort();\n///     // the destructor implemented for HasDrop will never get run\n/// }\n/// ```\n///\n/// [panic hook]: crate::panic::set_hook\n#[stable(feature = \"process_abort\", since = \"1.17.0\")]\n#[cold]\n#[cfg_attr(not(test), rustc_diagnostic_item = \"process_abort\")]\n#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces\npub fn abort() -> ! {\n    crate::sys::abort_internal();\n}\n\n#[doc(inline)]\n#[unstable(feature = \"abort_immediate\", issue = \"154601\")]\npub use core::process::abort_immediate;\n\n/// Returns the OS-assigned process identifier associated with this process.\n///\n/// # Examples\n///\n/// ```no_run\n/// use std::process;\n///\n/// println!(\"My pid is {}\", process::id());\n/// ```\n#[must_use]\n#[stable(feature = \"getpid\", since = \"1.26.0\")]\npub fn id() -> u32 {\n    imp::getpid()\n}\n\n/// A trait for implementing arbitrary return types in the `main` function.\n///\n/// The C-main function only supports returning integers.\n/// So, every type implementing the `Termination` trait has to be converted\n/// to an integer.\n///\n/// The default implementations are returning `libc::EXIT_SUCCESS` to indicate\n/// a successful execution. In case of a failure, `libc::EXIT_FAILURE` is returned.\n///\n/// Because different runtimes have different specifications on the return value\n/// of the `main` function, this trait is likely to be available only on\n/// standard library's runtime for convenience. Other runtimes are not required\n/// to provide similar functionality.\n#[cfg_attr(not(any(test, doctest)), lang = \"termination\")]\n#[stable(feature = \"termination_trait_lib\", since = \"1.61.0\")]\n#[rustc_on_unimplemented(on(\n    cause = \"MainFunctionType\",\n    message = \"`main` has invalid return type `{Self}`\",\n    label = \"`main` can only return types that implement `{This}`\"\n))]\npub trait Termination {\n    /// Is called to get the representation of the value as status code.\n    /// This status code is returned to the operating system.\n    #[stable(feature = \"termination_trait_lib\", since = \"1.61.0\")]\n    fn report(self) -> ExitCode;\n}\n\n#[stable(feature = \"termination_trait_lib\", since = \"1.61.0\")]\nimpl Termination for () {\n    #[inline]\n    fn report(self) -> ExitCode {\n        ExitCode::SUCCESS\n    }\n}\n\n#[stable(feature = \"termination_trait_lib\", since = \"1.61.0\")]\nimpl Termination for ! {\n    fn report(self) -> ExitCode {\n        self\n    }\n}\n\n#[stable(feature = \"termination_trait_lib\", since = \"1.61.0\")]\nimpl Termination for Infallible {\n    fn report(self) -> ExitCode {\n        match self {}\n    }\n}\n\n#[stable(feature = \"termination_trait_lib\", since = \"1.61.0\")]\nimpl Termination for ExitCode {\n    #[inline]\n    fn report(self) -> ExitCode {\n        self\n    }\n}\n\n#[stable(feature = \"termination_trait_lib\", since = \"1.61.0\")]\nimpl<T: Termination, E: fmt::Debug> Termination for Result<T, E> {\n    fn report(self) -> ExitCode {\n        match self {\n            Ok(val) => val.report(),\n            Err(err) => {\n                io::attempt_print_to_stderr(format_args_nl!(\"Error: {err:?}\"));\n                ExitCode::FAILURE\n            }\n        }\n    }\n}\n",
}

thread 'main' (1173793) panicked at /home/frank/repos/rust_main_dist/tests/run-make/embed-source-dwarf/rmake.rs:66:5:
assertion `left == right` failed
  left: 7
 right: 1
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
------------------------------------------

---- [run-make] tests/run-make/embed-source-dwarf stdout end ----
---- [run-make] tests/run-make/remap-path-prefix-std stdout ----

error: rmake recipe failed to complete
status: exit status: 101
command: cd "/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/test/run-make/remap-path-prefix-std/rmake_out" && env -u RUSTFLAGS -u __RUSTC_DEBUG_ASSERTIONS_ENABLED -u __STD_DEBUG_ASSERTIONS_ENABLED AR="ar" BUILD_ROOT="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu" CC="cc" CC_DEFAULT_FLAGS="-ffunction-sections -fdata-sections -fPIC -m64" CXX="c++" CXX_DEFAULT_FLAGS="-ffunction-sections -fdata-sections -fPIC -m64" HOST_RUSTC_DYLIB_PATH="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage2/lib" LD_LIBRARY_PATH="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/bootstrap-tools/x86_64-unknown-linux-gnu/release/build/run_make_support/878a16a0b6f5304f/out:/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib" LD_LIB_PATH_ENVVAR="LD_LIBRARY_PATH" LLVM_BIN_DIR="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/llvm/bin" LLVM_COMPONENTS="aarch64 aarch64asmparser aarch64codegen aarch64desc aarch64disassembler aarch64info aarch64utils abi aggressiveinstcombine all all-targets amdgpu amdgpuasmparser amdgpucodegen amdgpudesc amdgpudisassembler amdgpuinfo amdgputargetmca amdgpuutils analysis arm armasmparser armcodegen armdesc armdisassembler arminfo armutils asmparser asmprinter avr avrasmparser avrcodegen avrdesc avrdisassembler avrinfo binaryformat bitreader bitstreamreader bitwriter bpf bpfasmparser bpfcodegen bpfdesc bpfdisassembler bpfinfo cas cfguard cgdata codegen codegentypes core coroutines coverage csky cskyasmparser cskycodegen cskydesc cskydisassembler cskyinfo debuginfobtf debuginfocodeview debuginfodwarf debuginfodwarflowlevel debuginfogsym debuginfologicalview debuginfomsf debuginfopdb demangle dlltooldriver dtlto dwarfcfichecker dwarflinker dwarflinkerclassic dwarflinkerparallel dwp engine executionengine extensions filecheck frontendatomic frontenddirective frontenddriver frontendhlsl frontendoffloading frontendopenacc frontendopenmp fuzzercli fuzzmutate globalisel hexagon hexagonasmparser hexagoncodegen hexagondesc hexagondisassembler hexagoninfo hipstdpar instcombine instrumentation interfacestub interpreter ipo irprinter irreader jitlink libdriver lineeditor linker loongarch loongarchasmparser loongarchcodegen loongarchdesc loongarchdisassembler loongarchinfo lto m68k m68kasmparser m68kcodegen m68kdesc m68kdisassembler m68kinfo mc mca mcdisassembler mcjit mcparser mips mipsasmparser mipscodegen mipsdesc mipsdisassembler mipsinfo mirparser msp430 msp430asmparser msp430codegen msp430desc msp430disassembler msp430info native nativecodegen nvptx nvptxcodegen nvptxdesc nvptxinfo objcarcopts objcopy object objectyaml option orcdebugging orcjit orcshared orctargetprocess passes plugins powerpc powerpcasmparser powerpccodegen powerpcdesc powerpcdisassembler powerpcinfo profiledata remarks riscv riscvasmparser riscvcodegen riscvdesc riscvdisassembler riscvinfo riscvtargetmca runtimedyld sandboxir scalaropts selectiondag sparc sparcasmparser sparccodegen sparcdesc sparcdisassembler sparcinfo support supportlsp symbolize systemz systemzasmparser systemzcodegen systemzdesc systemzdisassembler systemzinfo tablegen target targetparser telemetry textapi textapibinaryreader transformutils vectorize webassembly webassemblyasmparser webassemblycodegen webassemblydesc webassemblydisassembler webassemblyinfo webassemblyutils windowsdriver windowsmanifest x86 x86asmparser x86codegen x86desc x86disassembler x86info x86targetmca xray xtensa xtensaasmparser xtensacodegen xtensadesc xtensadisassembler xtensainfo" LLVM_FILECHECK="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/llvm/build/bin/FileCheck" NODE="/home/frank/.nvm/versions/node/v22.12.0/bin/node" PYTHON="/usr/bin/python3" RUSTC="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" RUSTDOC="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" SOURCE_ROOT="/home/frank/repos/rust_main_dist" TARGET="x86_64-unknown-linux-gnu" TARGET_EXE_DYLIB_PATH="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib" __BOOTSTRAP_JOBS="24" __RMAKE_VERBOSE_SUBPROCESS_OUTPUT="1" __STD_REMAP_DEBUGINFO_ENABLED="1" "/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/test/run-make/remap-path-prefix-std/rmake"
stdout: none
--- stderr -------------------------------
LD_LIBRARY_PATH="/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/test/run-make/remap-path-prefix-std/rmake_out:/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage2/lib:/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/bootstrap-tools/x86_64-unknown-linux-gnu/release/build/run_make_support/878a16a0b6f5304f/out:/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/lib" "/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage2/bin/rustc" "-L" "/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/test/run-make/remap-path-prefix-std/rmake_out" "--print" "target-libdir" "--target=x86_64-unknown-linux-gnu"
output status: `exit status: 0`
=== STDOUT ===
/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/stage2/lib/rustlib/x86_64-unknown-linux-gnu/lib



=== STDERR ===



"/home/frank/repos/rust_main_dist/build/x86_64-unknown-linux-gnu/llvm/bin/llvm-dwarfdump" "libstd.rlib"
output status: `exit status: 0`
=== STDOUT ===
libstd.rlib(lib.rmeta): file format elf64-x86-64

.debug_info contents:
libstd.rlib(lib.rmeta-link):    file format elf64-x86-64

.debug_info contents:
libstd.rlib(std-ce07ea729ba8f4d3.std.a9f0e8103256732d-cgu.0.rcgu.o):    file format elf64-x86-64

.debug_info contents:



=== STDERR ===



assert_contains:
=== HAYSTACK ===
libstd.rlib(lib.rmeta): file format elf64-x86-64

.debug_info contents:
libstd.rlib(lib.rmeta-link):    file format elf64-x86-64

.debug_info contents:
libstd.rlib(std-ce07ea729ba8f4d3.std.a9f0e8103256732d-cgu.0.rcgu.o):    file format elf64-x86-64

.debug_info contents:

=== NEEDLE ===
/rustc/

thread 'main' (1188860) panicked at /home/frank/repos/rust_main_dist/tests/run-make/remap-path-prefix-std/rmake.rs:51:10:
needle was not found in haystack
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
------------------------------------------

---- [run-make] tests/run-make/remap-path-prefix-std stdout end ----

failures:
    [run-make] tests/run-make/embed-source-dwarf
    [run-make] tests/run-make/remap-path-prefix-std

test result: FAILED. 373 passed; 2 failed; 108 ignored; 0 measured; 0 filtered out; finished in 51.33s

Some tests failed in compiletest suite=run-make mode=run-make host=x86_64-unknown-linux-gnu target=x86_64-unknown-linux-gnu
Build completed unsuccessfully in 0:05:55

which is less scary as it doesn't have that

error: the compiler unexpectedly panicked. This is a bug

note: we would appreciate a bug report: https://github.com/rust-lang/rust/issues/new?labels=C-bug%2C+I-ICE%2C+T-rustdoc&template=ice.md

near the end.

@camelid camelid left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems good, but I think it might be better to leave the original issue open since we should add an error in bootstrap itself for this situation like you suggested in #158219 (comment). Also, I'm a little perplexed why our tests aren't resilient to being run in dist mode in the first place. It seems like something that we should support.

View changes since this review




aborting due to `-Z treat-err-as-bug=1`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any idea why this disappeared? Is it some kind of compiletest magic that wasn't working properly before?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just the two extra new lines at the end of the regex.

@steffahn steffahn Jun 23, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I.e. the new normalize-stderr regex ends in .*:\n.*\n removing the extra line (which in general is the panic message or something like that, I think). Among the search results I had already linked above, only half do it that way though.

//@ normalize-stderr: "thread 'rustc'.*panicked.*:\n.*\n" -> ""

The other commonly-used one would have left the aborting due to … line.

//@ normalize-stderr: "thread 'rustc'.*panicked.*\n" -> ""

@steffahn steffahn Jun 23, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be completely honest I had the exact same thought initially, too. "some kind of compiletest magic" seemed plausible. I needed to test things out more times both ways one more time make sure that it works the same in the dist or non-dist branch/folder I had open… and took probably 5+ minutes before realizing that these \ns in the regex are what's doing it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh that makes sense, thank you.

@camelid camelid added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 23, 2026
@steffahn

Copy link
Copy Markdown
Member Author

I unlinked the issue

@steffahn steffahn added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 23, 2026
@workingjubilee

Copy link
Copy Markdown
Member

Also, I'm a little perplexed why our tests aren't resilient to being run in dist mode in the first place. It seems like something that we should support.

I'm okay with our stuff failing in someone else's CI, honestly, though that might be mostly just reaction to the frequency of "we patched the compiler, but now it doesn't work" coming up. But the accumulated reason it failed has gone from "huh? there's nothing here?" (my mistake) through "well you do have to explicitly invoke this test" all the way to "...how does that even matter?" and... I'd rather it fail consistently or not, yes.

@steffahn

Copy link
Copy Markdown
Member Author

I'd rather it fail consistently or not, yes

I also believe this would be the best result. That's why I'm happy to either leave #158219 open as @camelid suggested, or open a follow-up issue that's more explicitly opened about that general goal, rather starting with a user reporting an “ICE”.

Anyway, this PR still seems a good first step since the stdout presentation with ICE error message content is especially confusing.


As for “fail consistently” - I’m not familiar with the details of what dist actually changes (these are configuration presets as far as I understood) so to arrive at a "fail consistently" solution, someone needs to figure out what about dist makes (some of?) those tests fail that still fail after this PR.

@camelid camelid left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Agreed that this is a good fix for now, but that we should also make testing in dist mode behave in a more consistent way that doesn't lead to confusing errors. I'm fine with either reusing the existing issue or making a new one, so I'll leave it to you.

View changes since this review




aborting due to `-Z treat-err-as-bug=1`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh that makes sense, thank you.

@camelid

camelid commented Jun 24, 2026

Copy link
Copy Markdown
Member

@bors r+ rollup

@rust-bors

rust-bors Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

📌 Commit 8949cf2 has been approved by camelid

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 24, 2026
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jun 25, 2026
Make normalization in a test case resilient to dist compilation

This fixes rust-lang#158219 by adapting the `tests/rustdoc-ui/ice-bug-report-url` test case such that it will no longer fail with the remapping prefixes from rust-lang#150110

This was previously sometimes the first test failure if someone tried `x.py test` on a compiler checkout configured with `dist` setup, prominently featuring the new (mismatching) test `stdout` containing the scary ICE error message.

---

The new normalization regex is taken from many existing test cases,
see: [↝ this code search ⮺](https://github.com/search?q=repo%3Arust-lang%2Frust+%2Fthread+%27rustc%27%5C.%5C*panicked%2F&type=code)

which includes files such as [`tests/ui/treat-err-as-bug/span_delayed_bug.rs`](https://github.com/rust-lang/rust/blob/4429659e4745016bd3f26a4a421843edc7fbc422/tests/ui/treat-err-as-bug/span_delayed_bug.rs#L4) or [`tests/ui/treat-err-as-bug/err.rs`](https://github.com/rust-lang/rust/blob/4429659e4745016bd3f26a4a421843edc7fbc422/tests/ui/treat-err-as-bug/err.rs#L4).
@steffahn

Copy link
Copy Markdown
Member Author

I'm fine with either reusing the existing issue or making a new one, so I'll leave it to you.

I’ve opened a new one

and re-linked this PR to fix the issue it aims to fix ^^

JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jun 25, 2026
Make normalization in a test case resilient to dist compilation

This fixes rust-lang#158219 by adapting the `tests/rustdoc-ui/ice-bug-report-url` test case such that it will no longer fail with the remapping prefixes from rust-lang#150110

This was previously sometimes the first test failure if someone tried `x.py test` on a compiler checkout configured with `dist` setup, prominently featuring the new (mismatching) test `stdout` containing the scary ICE error message.

---

The new normalization regex is taken from many existing test cases,
see: [↝ this code search ⮺](https://github.com/search?q=repo%3Arust-lang%2Frust+%2Fthread+%27rustc%27%5C.%5C*panicked%2F&type=code)

which includes files such as [`tests/ui/treat-err-as-bug/span_delayed_bug.rs`](https://github.com/rust-lang/rust/blob/4429659e4745016bd3f26a4a421843edc7fbc422/tests/ui/treat-err-as-bug/span_delayed_bug.rs#L4) or [`tests/ui/treat-err-as-bug/err.rs`](https://github.com/rust-lang/rust/blob/4429659e4745016bd3f26a4a421843edc7fbc422/tests/ui/treat-err-as-bug/err.rs#L4).
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jun 25, 2026
Make normalization in a test case resilient to dist compilation

This fixes rust-lang#158219 by adapting the `tests/rustdoc-ui/ice-bug-report-url` test case such that it will no longer fail with the remapping prefixes from rust-lang#150110

This was previously sometimes the first test failure if someone tried `x.py test` on a compiler checkout configured with `dist` setup, prominently featuring the new (mismatching) test `stdout` containing the scary ICE error message.

---

The new normalization regex is taken from many existing test cases,
see: [↝ this code search ⮺](https://github.com/search?q=repo%3Arust-lang%2Frust+%2Fthread+%27rustc%27%5C.%5C*panicked%2F&type=code)

which includes files such as [`tests/ui/treat-err-as-bug/span_delayed_bug.rs`](https://github.com/rust-lang/rust/blob/4429659e4745016bd3f26a4a421843edc7fbc422/tests/ui/treat-err-as-bug/span_delayed_bug.rs#L4) or [`tests/ui/treat-err-as-bug/err.rs`](https://github.com/rust-lang/rust/blob/4429659e4745016bd3f26a4a421843edc7fbc422/tests/ui/treat-err-as-bug/err.rs#L4).
rust-bors Bot pushed a commit that referenced this pull request Jun 25, 2026
…uwer

Rollup of 17 pull requests

Successful merges:

 - #153697 (Add arg splat experiment initial tuple impl)
 - #158294 (Use .drectve for MSVC DLL exports)
 - #158253 (codegen_ssa: multiply scalable vec size by `vscale`)
 - #158308 (Fix bug when rustdoc "go to only result" setting is not working as expected")
 - #158345 (Use `transmute_neo` in `assume_init`)
 - #158369 (std: abort when `resume_unwind` is called inside the panic hook)
 - #158374 (disallow tail calling extern "rust-call" functions)
 - #158380 (Revert "rebuild LLVM when `bootstrap.toml` config changes")
 - #154398 (Add test for async Send with PhantomData<*mut ()> + unsafe impl Send + dyn Trait)
 - #157181 (autodiff: stop always needing an alloca)
 - #158278 (autodiff - typtree cleanups)
 - #158311 (doc(unstable-book): fix typo "earier" -> "earlier" in default-visibility flag)
 - #158318 (Make normalization in a test case resilient to dist compilation)
 - #158338 (Reorganize `tests/ui/issues` [14/N])
 - #158343 (Include `Item::const_stability` info in rustdoc JSON.)
 - #158355 (Fixup the refactoring errors in #156246)
 - #158390 (Fix: auto trait, const trait bound)

Failed merges:

 - #155535 (export symbols: support macos/windows(32/64))
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jun 25, 2026
Make normalization in a test case resilient to dist compilation

This fixes rust-lang#158219 by adapting the `tests/rustdoc-ui/ice-bug-report-url` test case such that it will no longer fail with the remapping prefixes from rust-lang#150110

This was previously sometimes the first test failure if someone tried `x.py test` on a compiler checkout configured with `dist` setup, prominently featuring the new (mismatching) test `stdout` containing the scary ICE error message.

---

The new normalization regex is taken from many existing test cases,
see: [↝ this code search ⮺](https://github.com/search?q=repo%3Arust-lang%2Frust+%2Fthread+%27rustc%27%5C.%5C*panicked%2F&type=code)

which includes files such as [`tests/ui/treat-err-as-bug/span_delayed_bug.rs`](https://github.com/rust-lang/rust/blob/4429659e4745016bd3f26a4a421843edc7fbc422/tests/ui/treat-err-as-bug/span_delayed_bug.rs#L4) or [`tests/ui/treat-err-as-bug/err.rs`](https://github.com/rust-lang/rust/blob/4429659e4745016bd3f26a4a421843edc7fbc422/tests/ui/treat-err-as-bug/err.rs#L4).
rust-bors Bot pushed a commit that referenced this pull request Jun 25, 2026
…uwer

Rollup of 17 pull requests

Successful merges:

 - #153697 (Add arg splat experiment initial tuple impl)
 - #155535 (export symbols: support macos/windows(32/64))
 - #158253 (codegen_ssa: multiply scalable vec size by `vscale`)
 - #158308 (Fix bug when rustdoc "go to only result" setting is not working as expected")
 - #158345 (Use `transmute_neo` in `assume_init`)
 - #158369 (std: abort when `resume_unwind` is called inside the panic hook)
 - #158374 (disallow tail calling extern "rust-call" functions)
 - #158380 (Revert "rebuild LLVM when `bootstrap.toml` config changes")
 - #154398 (Add test for async Send with PhantomData<*mut ()> + unsafe impl Send + dyn Trait)
 - #157181 (autodiff: stop always needing an alloca)
 - #158278 (autodiff - typtree cleanups)
 - #158311 (doc(unstable-book): fix typo "earier" -> "earlier" in default-visibility flag)
 - #158318 (Make normalization in a test case resilient to dist compilation)
 - #158338 (Reorganize `tests/ui/issues` [14/N])
 - #158343 (Include `Item::const_stability` info in rustdoc JSON.)
 - #158355 (Fixup the refactoring errors in #156246)
 - #158390 (Fix: auto trait, const trait bound)
rust-bors Bot pushed a commit that referenced this pull request Jun 25, 2026
…uwer

Rollup of 17 pull requests

Successful merges:

 - #153697 (Add arg splat experiment initial tuple impl)
 - #155535 (export symbols: support macos/windows(32/64))
 - #158253 (codegen_ssa: multiply scalable vec size by `vscale`)
 - #158308 (Fix bug when rustdoc "go to only result" setting is not working as expected")
 - #158345 (Use `transmute_neo` in `assume_init`)
 - #158369 (std: abort when `resume_unwind` is called inside the panic hook)
 - #158374 (disallow tail calling extern "rust-call" functions)
 - #158380 (Revert "rebuild LLVM when `bootstrap.toml` config changes")
 - #154398 (Add test for async Send with PhantomData<*mut ()> + unsafe impl Send + dyn Trait)
 - #157181 (autodiff: stop always needing an alloca)
 - #158278 (autodiff - typtree cleanups)
 - #158311 (doc(unstable-book): fix typo "earier" -> "earlier" in default-visibility flag)
 - #158318 (Make normalization in a test case resilient to dist compilation)
 - #158338 (Reorganize `tests/ui/issues` [14/N])
 - #158343 (Include `Item::const_stability` info in rustdoc JSON.)
 - #158355 (Fixup the refactoring errors in #156246)
 - #158390 (Fix: auto trait, const trait bound)
rust-bors Bot pushed a commit that referenced this pull request Jun 25, 2026
…uwer

Rollup of 17 pull requests

Successful merges:

 - #153697 (Add arg splat experiment initial tuple impl)
 - #155535 (export symbols: support macos/windows(32/64))
 - #158253 (codegen_ssa: multiply scalable vec size by `vscale`)
 - #158308 (Fix bug when rustdoc "go to only result" setting is not working as expected")
 - #158345 (Use `transmute_neo` in `assume_init`)
 - #158369 (std: abort when `resume_unwind` is called inside the panic hook)
 - #158374 (disallow tail calling extern "rust-call" functions)
 - #158380 (Revert "rebuild LLVM when `bootstrap.toml` config changes")
 - #154398 (Add test for async Send with PhantomData<*mut ()> + unsafe impl Send + dyn Trait)
 - #157181 (autodiff: stop always needing an alloca)
 - #158278 (autodiff - typtree cleanups)
 - #158311 (doc(unstable-book): fix typo "earier" -> "earlier" in default-visibility flag)
 - #158318 (Make normalization in a test case resilient to dist compilation)
 - #158338 (Reorganize `tests/ui/issues` [14/N])
 - #158343 (Include `Item::const_stability` info in rustdoc JSON.)
 - #158355 (Fixup the refactoring errors in #156246)
 - #158390 (Fix: auto trait, const trait bound)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UI tests fail on dist profile in confusing manner (making it look almost like an ICE happened)

4 participants