Repository: rust-lang/rust
File: src/tools/miri/src/bin/miri.rs (Rust)

Code before:
/// Parses the input as a float in the range from 0.0 to 1.0 (inclusive).
fn parse_rate(input: &str) -> Result<f64, &'static str> {
    match input.parse::<f64>() {
        Ok(rate) if rate >= 0.0 && rate <= 1.0 => Ok(rate),
        Ok(_) => Err("must be between `0.0` and `1.0`"),
        Err(_) => Err("requires a `f64` between `0.0` and `1.0`"),
    }
}

/// Parses a seed range
///
/// This function is used for the `-Zmiri-many-seeds` flag. It expects the range in the form
/// `<from>..<to>`. `<from>` is inclusive, `<to>` is exclusive. `<from>` can be omitted,
/// in which case it is assumed to be `0`.
fn parse_range(val: &str) -> Result<Range<u32>, &'static str> {
    let (from, to) = val.split_once("..").ok_or("expected `from..to`")?;
    let from: u32 = if from.is_empty() { 0 } else { from.parse().map_err(|_| "invalid `from`")? };
    let to: u32 = to.parse().map_err(|_| "invalid `to`")?;
    Ok(from..to)
}

fn main() -> ExitCode {
    let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());

    // Snapshot a copy of the environment before `rustc` starts messing with it.
    // (`install_ice_hook` might change `RUST_BACKTRACE`.)
    let env_snapshot = env::vars_os().collect::<Vec<_>>();

    let args = rustc_driver::catch_fatal_errors(|| rustc_driver::args::raw_args(&early_dcx))
        .unwrap_or_else(|_| std::process::exit(rustc_driver::EXIT_FAILURE));

    // If the environment asks us to actually be rustc, then do that.
    if let Some(crate_kind) = env::var_os("MIRI_BE_RUSTC") {
        if crate_kind == "host" {
            // For host crates like proc macros and build scripts, we are an entirely normal rustc.
            // These eventually produce actual binaries and never run in Miri.
            return rustc_driver::main();
        } else if crate_kind != "target" {
            panic!("invalid `MIRI_BE_RUSTC` value: {crate_kind:?}")
        };

        // Earliest rustc setup.
        rustc_driver::install_ice_hook(rustc_driver::DEFAULT_BUG_REPORT_URL, |_| ());
        rustc_driver::init_rustc_env_logger(&early_dcx);

        let mut args = args;
        // Splice in the default arguments after the program name.
        // Some options have different defaults in Miri than in plain rustc; apply those by making
        // them the first arguments after the binary name (but later arguments can overwrite them).
        args.splice(1..1, miri::MIRI_DEFAULT_ARGS.iter().map(ToString::to_string));


Review comment (suggestion):
We have a custom `exit` function in this file that does some custom stuff. It's probably better to keep calling that here instead of changing the logic.

Code after:
fn parse_comma_list<T: FromStr>(input: &str) -> Result<Vec<T>, T::Err> {
    input.split(',').map(str::parse::<T>).collect()
}

/// Parses the input as a float in the range from 0.0 to 1.0 (inclusive).
fn parse_rate(input: &str) -> Result<f64, &'static str> {
    match input.parse::<f64>() {
        Ok(rate) if rate >= 0.0 && rate <= 1.0 => Ok(rate),
        Ok(_) => Err("must be between `0.0` and `1.0`"),
        Err(_) => Err("requires a `f64` between `0.0` and `1.0`"),
    }
}

/// Parses a seed range
///
/// This function is used for the `-Zmiri-many-seeds` flag. It expects the range in the form
/// `<from>..<to>`. `<from>` is inclusive, `<to>` is exclusive. `<from>` can be omitted,
/// in which case it is assumed to be `0`.
fn parse_range(val: &str) -> Result<Range<u32>, &'static str> {
    let (from, to) = val.split_once("..").ok_or("expected `from..to`")?;
    let from: u32 = if from.is_empty() { 0 } else { from.parse().map_err(|_| "invalid `from`")? };
    let to: u32 = to.parse().map_err(|_| "invalid `to`")?;
    Ok(from..to)
}

fn main() -> ExitCode {
    let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());

    // Snapshot a copy of the environment before `rustc` starts messing with it.
    // (`install_ice_hook` might change `RUST_BACKTRACE`.)
    let env_snapshot = env::vars_os().collect::<Vec<_>>();

    let args = rustc_driver::catch_fatal_errors(|| rustc_driver::args::raw_args(&early_dcx))
        .unwrap_or_else(|_| std::process::exit(rustc_driver::EXIT_FAILURE));

    // If the environment asks us to actually be rustc, then do that.
    if let Some(crate_kind) = env::var_os("MIRI_BE_RUSTC") {
        if crate_kind == "host" {
            // For host crates like proc macros and build scripts, we are an entirely normal rustc.
            // These eventually produce actual binaries and never run in Miri.
            return rustc_driver::main();
        } else if crate_kind != "target" {
            panic!("invalid `MIRI_BE_RUSTC` value: {crate_kind:?}")
        };

        // Earliest rustc setup.
        rustc_driver::install_ice_hook(rustc_driver::DEFAULT_BUG_REPORT_URL, |_| ());
        rustc_driver::init_rustc_env_logger(&early_dcx);

        let mut args = args;
        // Splice in the default arguments after the program name.