//! Contains infrastructure for configuring the compiler, including parsing
//! command-line options.

use std::collections::btree_map::{
    Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
};
use std::collections::{BTreeMap, BTreeSet};
use std::ffi::OsStr;
use std::hash::Hash;
use std::path::{Path, PathBuf};
use std::str::{self, FromStr};
use std::sync::LazyLock;
use std::{cmp, fs, iter};

use externs::{ExternOpt, split_extern_opt};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_data_structures::stable_hasher::{StableHasher, StableOrd, ToStableHashKey};
use rustc_errors::emitter::HumanReadableErrorType;
use rustc_errors::{ColorConfig, DiagCtxtFlags};
use rustc_feature::UnstableFeatures;
use rustc_hashes::Hash64;
use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic};
use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION};
use rustc_span::source_map::FilePathMapping;
use rustc_span::{
    FileName, RealFileName, RemapPathScopeComponents, SourceFileHashAlgorithm, Symbol, sym,
};
use rustc_target::spec::{
    FramePointer, LinkSelfContainedComponents, LinkerFeatures, PanicStrategy, SplitDebuginfo,
    Target, TargetTuple,
};
use tracing::debug;

pub use crate::config::cfg::{Cfg, CheckCfg, ExpectedValues};
use crate::config::native_libs::parse_native_libs;
pub use crate::config::print_request::{PrintKind, PrintRequest};
use crate::errors::FileWriteFail;
pub use crate::options::*;
use crate::search_paths::SearchPath;
use crate::utils::CanonicalizedPath;
use crate::{EarlyDiagCtxt, HashStableContext, Session, filesearch, lint};

mod cfg;
mod externs;
mod native_libs;
mod print_request;
pub mod sigpipe;

/// The different settings that the `-C strip` flag can have.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum Strip {
    /// Do not strip at all.
    None,

    /// Strip debuginfo.
    Debuginfo,

    /// Strip all symbols.
    Symbols,
}

/// The different settings that the `-C control-flow-guard` flag can have.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum CFGuard {
    /// Do not emit Control Flow Guard metadata or checks.
    Disabled,

    /// Emit Control Flow Guard metadata but no checks.
    NoChecks,

    /// Emit Control Flow Guard metadata and checks.
    Checks,
}

/// The different settings that the `-Z cf-protection` flag can have.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum CFProtection {
    /// Do not enable control-flow protection
    None,

    /// Emit control-flow protection for branches (enables indirect branch tracking).
    Branch,

    /// Emit control-flow protection for returns.
    Return,

    /// Emit control-flow protection for both branches and returns.
    Full,
}

#[derive(Clone, Copy, Debug, PartialEq, Hash, HashStable_Generic, Encodable, Decodable)]
pub enum OptLevel {
    /// `-Copt-level=0`
    No,
    /// `-Copt-level=1`
    Less,
    /// `-Copt-level=2`
    More,
    /// `-Copt-level=3` / `-O`
    Aggressive,
    /// `-Copt-level=s`
    Size,
    /// `-Copt-level=z`
    SizeMin,
}

/// This is what the `LtoCli` values get mapped to after resolving defaults and
/// and taking other command line options into account.
///
/// Note that linker plugin-based LTO is a different mechanism entirely.
#[derive(Clone, PartialEq, Encodable, Decodable)]
pub enum Lto {
    /// Don't do any LTO whatsoever.
    No,

    /// Do a full-crate-graph (inter-crate) LTO with ThinLTO.
    Thin,

    /// Do a local ThinLTO (intra-crate, over the CodeGen Units of the local crate only). This is
    /// only relevant if multiple CGUs are used.
    ThinLocal,

    /// Do a full-crate-graph (inter-crate) LTO with "fat" LTO.
    Fat,
}

/// The different settings that the `-C lto` flag can have.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum LtoCli {
    /// `-C lto=no`
    No,
    /// `-C lto=yes`
    Yes,
    /// `-C lto`
    NoParam,
    /// `-C lto=thin`
    Thin,
    /// `-C lto=fat`
    Fat,
    /// No `-C lto` flag passed
    Unspecified,
}

/// The different settings that the `-C instrument-coverage` flag can have.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum InstrumentCoverage {
    /// `-C instrument-coverage=no` (or `off`, `false` etc.)
    No,
    /// `-C instrument-coverage` or `-C instrument-coverage=yes`
    Yes,
}

/// Individual flag values controlled by `-Zcoverage-options`.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
pub struct CoverageOptions {
    pub level: CoverageLevel,

    /// **(internal test-only flag)**
    /// `-Zcoverage-options=discard-all-spans-in-codegen`: During codegen,
    /// discard all coverage spans as though they were invalid. Needed by
    /// regression tests for #133606, because we don't have an easy way to
    /// reproduce it from actual source code.
    pub discard_all_spans_in_codegen: bool,
}

/// Controls whether branch coverage is enabled.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
pub enum CoverageLevel {
    /// Instrument for coverage at the MIR block level.
    #[default]
    Block,
    /// Also instrument branch points (includes block coverage).
    Branch,
    /// Same as branch coverage, but also adds branch instrumentation for
    /// certain boolean expressions that are not directly used for branching.
    ///
    /// For example, in the following code, `b` does not directly participate
    /// in a branch, but condition coverage will instrument it as its own
    /// artificial branch:
    /// ```
    /// # let (a, b) = (false, true);
    /// let x = a && b;
    /// //           ^ last operand
    /// ```
    ///
    /// This level is mainly intended to be a stepping-stone towards full MC/DC
    /// instrumentation, so it might be removed in the future when MC/DC is
    /// sufficiently complete, or if it is making MC/DC changes difficult.
    Condition,
}

// The different settings that the `-Z offload` flag can have.
#[derive(Clone, PartialEq, Hash, Debug, Encodable, Decodable)]
pub enum Offload {
    /// Entry point for `std::offload`, enables kernel compilation for a gpu device
    Device,
    /// Second step in the offload pipeline, generates the host code to call kernels.
    Host(String),
    /// Test is similar to Host, but allows testing without a device artifact.
    Test,
}

/// The different settings that the `-Z autodiff` flag can have.
#[derive(Clone, PartialEq, Hash, Debug, Encodable, Decodable)]
pub enum AutoDiff {
    /// Enable the autodiff opt pipeline
    Enable,

    /// Print TypeAnalysis information
    PrintTA,
    /// Print TypeAnalysis information for a specific function
    PrintTAFn(String),
    /// Print ActivityAnalysis Information
    PrintAA,
    /// Print Performance Warnings from Enzyme
    PrintPerf,
    /// Print intermediate IR generation steps
    PrintSteps,
    /// Print the module, before running autodiff.
    PrintModBefore,
    /// Print the module after running autodiff.
    PrintModAfter,
    /// Print the module after running autodiff and optimizations.
    PrintModFinal,

    /// Print all passes scheduled by LLVM
    PrintPasses,
    /// Disable extra opt run after running autodiff
    NoPostopt,
    /// Enzyme's loose type debug helper (can cause incorrect gradients!!)
    /// Usable in cases where Enzyme errors with `can not deduce type of X`.
    LooseTypes,
    /// Runs Enzyme's aggressive inlining
    Inline,
    /// Disable Type Tree
    NoTT,
}

/// The different settings that the `-Z annotate-moves` flag can have.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum AnnotateMoves {
    /// `-Z annotate-moves=no` (or `off`, `false` etc.)
    Disabled,
    /// `-Z annotate-moves` or `-Z annotate-moves=yes` (use default size limit)
    /// `-Z annotate-moves=SIZE` (use specified size limit)
    Enabled(Option<u64>),
}

/// Settings for `-Z instrument-xray` flag.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub struct InstrumentXRay {
    /// `-Z instrument-xray=always`, force instrumentation
    pub always: bool,
    /// `-Z instrument-xray=never`, disable instrumentation
    pub never: bool,
    /// `-Z instrument-xray=ignore-loops`, ignore presence of loops,
    /// instrument functions based only on instruction count
    pub ignore_loops: bool,
    /// `-Z instrument-xray=instruction-threshold=N`, explicitly set instruction threshold
    /// for instrumentation, or `None` to use compiler's default
    pub instruction_threshold: Option<usize>,
    /// `-Z instrument-xray=skip-entry`, do not instrument function entry
    pub skip_entry: bool,
    /// `-Z instrument-xray=skip-exit`, do not instrument function exit
    pub skip_exit: bool,
}

#[derive(Clone, PartialEq, Hash, Debug)]
pub enum LinkerPluginLto {
    LinkerPlugin(PathBuf),
    LinkerPluginAuto,
    Disabled,
}

impl LinkerPluginLto {
    pub fn enabled(&self) -> bool {
        match *self {
            LinkerPluginLto::LinkerPlugin(_) | LinkerPluginLto::LinkerPluginAuto => true,
            LinkerPluginLto::Disabled => false,
        }
    }
}

/// The different values `-C link-self-contained` can take: a list of individually enabled or
/// disabled components used during linking, coming from the rustc distribution, instead of being
/// found somewhere on the host system.
///
/// They can be set in bulk via `-C link-self-contained=yes|y|on` or `-C
/// link-self-contained=no|n|off`, and those boolean values are the historical defaults.
///
/// But each component is fine-grained, and can be unstably targeted, to use:
/// - some CRT objects
/// - the libc static library
/// - libgcc/libunwind libraries
/// - a linker we distribute
/// - some sanitizer runtime libraries
/// - all other MinGW libraries and Windows import libs
///
#[derive(Default, Clone, PartialEq, Debug)]
pub struct LinkSelfContained {
    /// Whether the user explicitly set `-C link-self-contained` on or off, the historical values.
    /// Used for compatibility with the existing opt-in and target inference.
    pub explicitly_set: Option<bool>,

    /// The components that are enabled on the CLI, using the `+component` syntax or one of the
    /// `true` shortcuts.
    enabled_components: LinkSelfContainedComponents,

    /// The components that are disabled on the CLI, using the `-component` syntax or one of the
    /// `false` shortcuts.
    disabled_components: LinkSelfContainedComponents,
}

impl LinkSelfContained {
    /// Incorporates an enabled or disabled component as specified on the CLI, if possible.
    /// For example: `+linker`, and `-crto`.
    pub(crate) fn handle_cli_component(&mut self, component: &str) -> Option<()> {
        // Note that for example `-Cself-contained=y -Cself-contained=-linker` is not an explicit
        // set of all values like `y` or `n` used to be. Therefore, if this flag had previously been
        // set in bulk with its historical values, then manually setting a component clears that
        // `explicitly_set` state.
        if let Some(component_to_enable) = component.strip_prefix('+') {
            self.explicitly_set = None;
            self.enabled_components
                .insert(LinkSelfContainedComponents::from_str(component_to_enable).ok()?);
            Some(())
        } else if let Some(component_to_disable) = component.strip_prefix('-') {
            self.explicitly_set = None;
            self.disabled_components
                .insert(LinkSelfContainedComponents::from_str(component_to_disable).ok()?);
            Some(())
        } else {
            None
        }
    }

    /// Turns all components on or off and records that this was done explicitly for compatibility
    /// purposes.
    pub(crate) fn set_all_explicitly(&mut self, enabled: bool) {
        self.explicitly_set = Some(enabled);

        if enabled {
            self.enabled_components = LinkSelfContainedComponents::all();
            self.disabled_components = LinkSelfContainedComponents::empty();
        } else {
            self.enabled_components = LinkSelfContainedComponents::empty();
            self.disabled_components = LinkSelfContainedComponents::all();
        }
    }

    /// Helper creating a fully enabled `LinkSelfContained` instance. Used in tests.
    pub fn on() -> Self {
        let mut on = LinkSelfContained::default();
        on.set_all_explicitly(true);
        on
    }

    /// To help checking CLI usage while some of the values are unstable: returns whether one of the
    /// unstable components was set individually, for the given `TargetTuple`. This would also
    /// require the `-Zunstable-options` flag, to be allowed.
    fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
        if self.explicitly_set.is_some() {
            return Ok(());
        }

        // `-C link-self-contained=-linker` is only stable on x64 linux.
        let has_minus_linker = self.disabled_components.is_linker_enabled();
        if has_minus_linker && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
            return Err(format!(
                "`-C link-self-contained=-linker` is unstable on the `{target_tuple}` \
                    target. The `-Z unstable-options` flag must also be passed to use it on this target",
            ));
        }

        // Any `+linker` or other component used is unstable, and that's an error.
        let unstable_enabled = self.enabled_components;
        let unstable_disabled = self.disabled_components - LinkSelfContainedComponents::LINKER;
        if !unstable_enabled.union(unstable_disabled).is_empty() {
            return Err(String::from(
                "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` \
                are stable, the `-Z unstable-options` flag must also be passed to use \
                the unstable values",
            ));
        }

        Ok(())
    }

    /// Returns whether the self-contained linker component was enabled on the CLI, using the
    /// `-C link-self-contained=+linker` syntax, or one of the `true` shortcuts.
    pub fn is_linker_enabled(&self) -> bool {
        self.enabled_components.contains(LinkSelfContainedComponents::LINKER)
    }

    /// Returns whether the self-contained linker component was disabled on the CLI, using the
    /// `-C link-self-contained=-linker` syntax, or one of the `false` shortcuts.
    pub fn is_linker_disabled(&self) -> bool {
        self.disabled_components.contains(LinkSelfContainedComponents::LINKER)
    }

    /// Returns CLI inconsistencies to emit errors: individual components were both enabled and
    /// disabled.
    fn check_consistency(&self) -> Option<LinkSelfContainedComponents> {
        if self.explicitly_set.is_some() {
            None
        } else {
            let common = self.enabled_components.intersection(self.disabled_components);
            if common.is_empty() { None } else { Some(common) }
        }
    }
}

/// The different values that `-C linker-features` can take on the CLI: a list of individually
/// enabled or disabled features used during linking.
///
/// There is no need to enable or disable them in bulk. Each feature is fine-grained, and can be
/// used to turn `LinkerFeatures` on or off, without needing to change the linker flavor:
/// - using the system lld, or the self-contained `rust-lld` linker
/// - using a C/C++ compiler to drive the linker (not yet exposed on the CLI)
/// - etc.
#[derive(Default, Copy, Clone, PartialEq, Debug)]
pub struct LinkerFeaturesCli {
    /// The linker features that are enabled on the CLI, using the `+feature` syntax.
    pub enabled: LinkerFeatures,

    /// The linker features that are disabled on the CLI, using the `-feature` syntax.
    pub disabled: LinkerFeatures,
}

impl LinkerFeaturesCli {
    /// Accumulates an enabled or disabled feature as specified on the CLI, if possible.
    /// For example: `+lld`, and `-lld`.
    pub(crate) fn handle_cli_feature(&mut self, feature: &str) -> Option<()> {
        // Duplicate flags are reduced as we go, the last occurrence wins:
        // `+feature,-feature,+feature` only enables the feature, and does not record it as both
        // enabled and disabled on the CLI.
        // We also only expose `+/-lld` at the moment, as it's currently the only implemented linker
        // feature and toggling `LinkerFeatures::CC` would be a noop.
        match feature {
            "+lld" => {
                self.enabled.insert(LinkerFeatures::LLD);
                self.disabled.remove(LinkerFeatures::LLD);
                Some(())
            }
            "-lld" => {
                self.disabled.insert(LinkerFeatures::LLD);
                self.enabled.remove(LinkerFeatures::LLD);
                Some(())
            }
            _ => None,
        }
    }

    /// When *not* using `-Z unstable-options` on the CLI, ensure only stable linker features are
    /// used, for the given `TargetTuple`. Returns `Ok` if no unstable variants are used.
    /// The caller should ensure that e.g. `nightly_options::is_unstable_enabled()`
    /// returns false.
    pub(crate) fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
        // `-C linker-features=-lld` is only stable on x64 linux.
        let has_minus_lld = self.disabled.is_lld_enabled();
        if has_minus_lld && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
            return Err(format!(
                "`-C linker-features=-lld` is unstable on the `{target_tuple}` \
                    target. The `-Z unstable-options` flag must also be passed to use it on this target",
            ));
        }

        // Any `+lld` or non-lld feature used is unstable, and that's an error.
        let unstable_enabled = self.enabled;
        let unstable_disabled = self.disabled - LinkerFeatures::LLD;
        if !unstable_enabled.union(unstable_disabled).is_empty() {
            let unstable_features: Vec<_> = unstable_enabled
                .iter()
                .map(|f| format!("+{}", f.as_str().unwrap()))
                .chain(unstable_disabled.iter().map(|f| format!("-{}", f.as_str().unwrap())))
                .collect();
            return Err(format!(
                "`-C linker-features={}` is unstable, and also requires the \
                `-Z unstable-options` flag to be used",
                unstable_features.join(","),
            ));
        }

        Ok(())
    }
}

/// Used with `-Z assert-incr-state`.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum IncrementalStateAssertion {
    /// Found and loaded an existing session directory.
    ///
    /// Note that this says nothing about whether any particular query
    /// will be found to be red or green.
    Loaded,
    /// Did not load an existing session directory.
    NotLoaded,
}

/// The different settings that can be enabled via the `-Z location-detail` flag.
#[derive(Copy, Clone, PartialEq, Hash, Debug)]
pub struct LocationDetail {
    pub file: bool,
    pub line: bool,
    pub column: bool,
}

impl LocationDetail {
    pub(crate) fn all() -> Self {
        Self { file: true, line: true, column: true }
    }
}

/// Values for the `-Z fmt-debug` flag.
#[derive(Copy, Clone, PartialEq, Hash, Debug)]
pub enum FmtDebug {
    /// Derive fully-featured implementation
    Full,
    /// Print only type name, without fields
    Shallow,
    /// `#[derive(Debug)]` and `{:?}` are no-ops
    None,
}

impl FmtDebug {
    pub(crate) fn all() -> [Symbol; 3] {
        [sym::full, sym::none, sym::shallow]
    }
}

#[derive(Clone, PartialEq, Hash, Debug, Encodable, Decodable)]
pub enum SwitchWithOptPath {
    Enabled(Option<PathBuf>),
    Disabled,
}

impl SwitchWithOptPath {
    pub fn enabled(&self) -> bool {
        match *self {
            SwitchWithOptPath::Enabled(_) => true,
            SwitchWithOptPath::Disabled => false,
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable_Generic)]
#[derive(Encodable, BlobDecodable)]
pub enum SymbolManglingVersion {
    Legacy,
    V0,
    Hashed,
}

#[derive(Clone, Copy, Debug, PartialEq, Hash)]
pub enum DebugInfo {
    None,
    LineDirectivesOnly,
    LineTablesOnly,
    Limited,
    Full,
}

#[derive(Clone, Copy, Debug, PartialEq, Hash)]
pub enum DebugInfoCompression {
    None,
    Zlib,
    Zstd,
}

#[derive(Clone, Copy, Debug, PartialEq, Hash)]
pub enum MirStripDebugInfo {
    None,
    LocalsInTinyFunctions,
    AllLocals,
}

/// Split debug-information is enabled by `-C split-debuginfo`, this enum is only used if split
/// debug-information is enabled (in either `Packed` or `Unpacked` modes), and the platform
/// uses DWARF for debug-information.
///
/// Some debug-information requires link-time relocation and some does not. LLVM can partition
/// the debuginfo into sections depending on whether or not it requires link-time relocation. Split
/// DWARF provides a mechanism which allows the linker to skip the sections which don't require
/// link-time relocation - either by putting those sections in DWARF object files, or by keeping
/// them in the object file in such a way that the linker will skip them.
#[derive(Clone, Copy, Debug, PartialEq, Hash, Encodable, Decodable)]
pub enum SplitDwarfKind {
    /// Sections which do not require relocation are written into object file but ignored by the
    /// linker.
    Single,
    /// Sections which do not require relocation are written into a DWARF object (`.dwo`) file
    /// which is ignored by the linker.
    Split,
}

impl FromStr for SplitDwarfKind {
    type Err = ();

    fn from_str(s: &str) -> Result<Self, ()> {
        Ok(match s {
            "single" => SplitDwarfKind::Single,
            "split" => SplitDwarfKind::Split,
            _ => return Err(()),
        })
    }
}

macro_rules! define_output_types {
    (
        $(
            $(#[doc = $doc:expr])*
            $Variant:ident => {
                shorthand: $shorthand:expr,
                extension: $extension:expr,
                description: $description:expr,
                default_filename: $default_filename:expr,
                is_text: $is_text:expr,
                compatible_with_cgus_and_single_output: $compatible:expr
            }
        ),* $(,)?
    ) => {
        #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, HashStable_Generic)]
        #[derive(Encodable, Decodable)]
        pub enum OutputType {
            $(
                $(#[doc = $doc])*
                $Variant,
            )*
        }


        impl StableOrd for OutputType {
            const CAN_USE_UNSTABLE_SORT: bool = true;

            // Trivial C-Style enums have a stable sort order across compilation sessions.
            const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
        }

        impl<HCX: HashStableContext> ToStableHashKey<HCX> for OutputType {
            type KeyType = Self;

            fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType {
                *self
            }
        }


        impl OutputType {
            pub fn iter_all() -> impl Iterator<Item = OutputType> {
                static ALL_VARIANTS: &[OutputType] = &[
                    $(
                        OutputType::$Variant,
                    )*
                ];
                ALL_VARIANTS.iter().copied()
            }

            fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool {
                match *self {
                    $(
                        OutputType::$Variant => $compatible,
                    )*
                }
            }

            pub fn shorthand(&self) -> &'static str {
                match *self {
                    $(
                        OutputType::$Variant => $shorthand,
                    )*
                }
            }

            fn from_shorthand(shorthand: &str) -> Option<Self> {
                match shorthand {
                    $(
                        s if s == $shorthand => Some(OutputType::$Variant),
                    )*
                    _ => None,
                }
            }

            fn shorthands_display() -> String {
                let shorthands = vec![
                    $(
                        format!("`{}`", $shorthand),
                    )*
                ];
                shorthands.join(", ")
            }

            pub fn extension(&self) -> &'static str {
                match *self {
                    $(
                        OutputType::$Variant => $extension,
                    )*
                }
            }

            pub fn is_text_output(&self) -> bool {
                match *self {
                    $(
                        OutputType::$Variant => $is_text,
                    )*
                }
            }

            pub fn description(&self) -> &'static str {
                match *self {
                    $(
                        OutputType::$Variant => $description,
                    )*
                }
            }

            pub fn default_filename(&self) -> &'static str {
                match *self {
                    $(
                        OutputType::$Variant => $default_filename,
                    )*
                }
            }


        }
    }
}

define_output_types! {
    Assembly => {
        shorthand: "asm",
        extension: "s",
        description: "Generates a file with the crate's assembly code",
        default_filename: "CRATE_NAME.s",
        is_text: true,
        compatible_with_cgus_and_single_output: false
    },
    #[doc = "This is the optimized bitcode, which could be either pre-LTO or non-LTO bitcode,"]
    #[doc = "depending on the specific request type."]
    Bitcode => {
        shorthand: "llvm-bc",
        extension: "bc",
        description: "Generates a binary file containing the LLVM bitcode",
        default_filename: "CRATE_NAME.bc",
        is_text: false,
        compatible_with_cgus_and_single_output: false
    },
    DepInfo => {
        shorthand: "dep-info",
        extension: "d",
        description: "Generates a file with Makefile syntax that indicates all the source files that were loaded to generate the crate",
        default_filename: "CRATE_NAME.d",
        is_text: true,
        compatible_with_cgus_and_single_output: true
    },
    Exe => {
        shorthand: "link",
        extension: "",
        description: "Generates the crates specified by --crate-type. This is the default if --emit is not specified",
        default_filename: "(platform and crate-type dependent)",
        is_text: false,
        compatible_with_cgus_and_single_output: true
    },
    LlvmAssembly => {
        shorthand: "llvm-ir",
        extension: "ll",
        description: "Generates a file containing LLVM IR",
        default_filename: "CRATE_NAME.ll",
        is_text: true,
        compatible_with_cgus_and_single_output: false
    },
    Metadata => {
        shorthand: "metadata",
        extension: "rmeta",
        description: "Generates a file containing metadata about the crate",
        default_filename: "libCRATE_NAME.rmeta",
        is_text: false,
        compatible_with_cgus_and_single_output: true
    },
    Mir => {
        shorthand: "mir",
        extension: "mir",
        description: "Generates a file containing rustc's mid-level intermediate representation",
        default_filename: "CRATE_NAME.mir",
        is_text: true,
        compatible_with_cgus_and_single_output: false
    },
    Object => {
        shorthand: "obj",
        extension: "o",
        description: "Generates a native object file",
        default_filename: "CRATE_NAME.o",
        is_text: false,
        compatible_with_cgus_and_single_output: false
    },
    #[doc = "This is the summary or index data part of the ThinLTO bitcode."]
    ThinLinkBitcode => {
        shorthand: "thin-link-bitcode",
        extension: "indexing.o",
        description: "Generates the ThinLTO summary as bitcode",
        default_filename: "CRATE_NAME.indexing.o",
        is_text: false,
        compatible_with_cgus_and_single_output: false
    },
}

/// The type of diagnostics output to generate.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)]
pub enum ErrorOutputType {
    /// Output meant for the consumption of humans.
    #[default]
    HumanReadable {
        kind: HumanReadableErrorType = HumanReadableErrorType { short: false, unicode: false },
        color_config: ColorConfig = ColorConfig::Auto,
    },
    /// Output that's consumed by other tools such as `rustfix` or the `RLS`.
    Json {
        /// Render the JSON in a human readable way (with indents and newlines).
        pretty: bool,
        /// The JSON output includes a `rendered` field that includes the rendered
        /// human output.
        json_rendered: HumanReadableErrorType,
        color_config: ColorConfig,
    },
}

#[derive(Clone, Hash, Debug)]
pub enum ResolveDocLinks {
    /// Do not resolve doc links.
    None,
    /// Resolve doc links on exported items only for crate types that have metadata.
    ExportedMetadata,
    /// Resolve doc links on exported items.
    Exported,
    /// Resolve doc links on all items.
    All,
}

/// Use tree-based collections to cheaply get a deterministic `Hash` implementation.
/// *Do not* switch `BTreeMap` out for an unsorted container type! That would break
/// dependency tracking for command-line arguments. Also only hash keys, since tracking
/// should only depend on the output types, not the paths they're written to.
#[derive(Clone, Debug, Hash, HashStable_Generic, Encodable, Decodable)]
pub struct OutputTypes(BTreeMap<OutputType, Option<OutFileName>>);

impl OutputTypes {
    pub fn new(entries: &[(OutputType, Option<OutFileName>)]) -> OutputTypes {
        OutputTypes(BTreeMap::from_iter(entries.iter().map(|&(k, ref v)| (k, v.clone()))))
    }

    pub(crate) fn get(&self, key: &OutputType) -> Option<&Option<OutFileName>> {
        self.0.get(key)
    }

    pub fn contains_key(&self, key: &OutputType) -> bool {
        self.0.contains_key(key)
    }

    /// Returns `true` if user specified a name and not just produced type
    pub fn contains_explicit_name(&self, key: &OutputType) -> bool {
        matches!(self.0.get(key), Some(Some(..)))
    }

    pub fn iter(&self) -> BTreeMapIter<'_, OutputType, Option<OutFileName>> {
        self.0.iter()
    }

    pub fn keys(&self) -> BTreeMapKeysIter<'_, OutputType, Option<OutFileName>> {
        self.0.keys()
    }

    pub fn values(&self) -> BTreeMapValuesIter<'_, OutputType, Option<OutFileName>> {
        self.0.values()
    }

    pub fn len(&self) -> usize {
        self.0.len()
    }

    /// Returns `true` if any of the output types require codegen or linking.
    pub fn should_codegen(&self) -> bool {
        self.0.keys().any(|k| match *k {
            OutputType::Bitcode
            | OutputType::ThinLinkBitcode
            | OutputType::Assembly
            | OutputType::LlvmAssembly
            | OutputType::Mir
            | OutputType::Object
            | OutputType::Exe => true,
            OutputType::Metadata | OutputType::DepInfo => false,
        })
    }

    /// Returns `true` if any of the output types require linking.
    pub fn should_link(&self) -> bool {
        self.0.keys().any(|k| match *k {
            OutputType::Bitcode
            | OutputType::ThinLinkBitcode
            | OutputType::Assembly
            | OutputType::LlvmAssembly
            | OutputType::Mir
            | OutputType::Metadata
            | OutputType::Object
            | OutputType::DepInfo => false,
            OutputType::Exe => true,
        })
    }
}

/// Use tree-based collections to cheaply get a deterministic `Hash` implementation.
/// *Do not* switch `BTreeMap` or `BTreeSet` out for an unsorted container type! That
/// would break dependency tracking for command-line arguments.
#[derive(Clone)]
pub struct Externs(BTreeMap<String, ExternEntry>);

#[derive(Clone, Debug)]
pub struct ExternEntry {
    pub location: ExternLocation,
    /// Indicates this is a "private" dependency for the
    /// `exported_private_dependencies` lint.
    ///
    /// This can be set with the `priv` option like
    /// `--extern priv:name=foo.rlib`.
    pub is_private_dep: bool,
    /// Add the extern entry to the extern prelude.
    ///
    /// This can be disabled with the `noprelude` option like
    /// `--extern noprelude:name`.
    pub add_prelude: bool,
    /// The extern entry shouldn't be considered for unused dependency warnings.
    ///
    /// `--extern nounused:std=/path/to/lib/libstd.rlib`. This is used to
    /// suppress `unused-crate-dependencies` warnings.
    pub nounused_dep: bool,
    /// If the extern entry is not referenced in the crate, force it to be resolved anyway.
    ///
    /// Allows a dependency satisfying, for instance, a missing panic handler to be injected
    /// without modifying source:
    /// `--extern force:extras=/path/to/lib/libstd.rlib`
    pub force: bool,
}

#[derive(Clone, Debug)]
pub enum ExternLocation {
    /// Indicates to look for the library in the search paths.
    ///
    /// Added via `--extern name`.
    FoundInLibrarySearchDirectories,
    /// The locations where this extern entry must be found.
    ///
    /// The `CrateLoader` is responsible for loading these and figuring out
    /// which one to use.
    ///
    /// Added via `--extern prelude_name=some_file.rlib`
    ExactPaths(BTreeSet<CanonicalizedPath>),
}

impl Externs {
    /// Used for testing.
    pub fn new(data: BTreeMap<String, ExternEntry>) -> Externs {
        Externs(data)
    }

    pub fn get(&self, key: &str) -> Option<&ExternEntry> {
        self.0.get(key)
    }

    pub fn iter(&self) -> BTreeMapIter<'_, String, ExternEntry> {
        self.0.iter()
    }
}

impl ExternEntry {
    fn new(location: ExternLocation) -> ExternEntry {
        ExternEntry {
            location,
            is_private_dep: false,
            add_prelude: false,
            nounused_dep: false,
            force: false,
        }
    }

    pub fn files(&self) -> Option<impl Iterator<Item = &CanonicalizedPath>> {
        match &self.location {
            ExternLocation::ExactPaths(set) => Some(set.iter()),
            _ => None,
        }
    }
}

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Default)]
pub struct NextSolverConfig {
    /// Whether the new trait solver should be enabled in coherence.
    pub coherence: bool = true,
    /// Whether the new trait solver should be enabled everywhere.
    /// This is only `true` if `coherence` is also enabled.
    pub globally: bool = false,
}

#[derive(Clone)]
pub enum Input {
    /// Load source code from a file.
    File(PathBuf),
    /// Load source code from a string.
    Str {
        /// A string that is shown in place of a filename.
        name: FileName,
        /// An anonymous string containing the source code.
        input: String,
    },
}

impl Input {
    pub fn filestem(&self) -> &str {
        if let Input::File(ifile) = self {
            // If for some reason getting the file stem as a UTF-8 string fails,
            // then fallback to a fixed name.
            if let Some(name) = ifile.file_stem().and_then(OsStr::to_str) {
                return name;
            }
        }
        "rust_out"
    }

    pub fn file_name(&self, session: &Session) -> FileName {
        match *self {
            Input::File(ref ifile) => FileName::Real(
                session
                    .psess
                    .source_map()
                    .path_mapping()
                    .to_real_filename(session.psess.source_map().working_dir(), ifile.as_path()),
            ),
            Input::Str { ref name, .. } => name.clone(),
        }
    }

    pub fn opt_path(&self) -> Option<&Path> {
        match self {
            Input::File(file) => Some(file),
            Input::Str { name, .. } => match name {
                FileName::Real(real) => real.local_path(),
                FileName::CfgSpec(_) => None,
                FileName::Anon(_) => None,
                FileName::MacroExpansion(_) => None,
                FileName::ProcMacroSourceCode(_) => None,
                FileName::CliCrateAttr(_) => None,
                FileName::Custom(_) => None,
                FileName::DocTest(path, _) => Some(path),
                FileName::InlineAsm(_) => None,
            },
        }
    }
}

#[derive(Clone, Hash, Debug, HashStable_Generic, PartialEq, Eq, Encodable, Decodable)]
pub enum OutFileName {
    Real(PathBuf),
    Stdout,
}

impl OutFileName {
    pub fn parent(&self) -> Option<&Path> {
        match *self {
            OutFileName::Real(ref path) => path.parent(),
            OutFileName::Stdout => None,
        }
    }

    pub fn filestem(&self) -> Option<&OsStr> {
        match *self {
            OutFileName::Real(ref path) => path.file_stem(),
            OutFileName::Stdout => Some(OsStr::new("stdout")),
        }
    }

    pub fn is_stdout(&self) -> bool {
        match *self {
            OutFileName::Real(_) => false,
            OutFileName::Stdout => true,
        }
    }

    pub fn is_tty(&self) -> bool {
        use std::io::IsTerminal;
        match *self {
            OutFileName::Real(_) => false,
            OutFileName::Stdout => std::io::stdout().is_terminal(),
        }
    }

    pub fn as_path(&self) -> &Path {
        match *self {
            OutFileName::Real(ref path) => path.as_ref(),
            OutFileName::Stdout => Path::new("stdout"),
        }
    }

    /// For a given output filename, return the actual name of the file that
    /// can be used to write codegen data of type `flavor`. For real-path
    /// output filenames, this would be trivial as we can just use the path.
    /// Otherwise for stdout, return a temporary path so that the codegen data
    /// may be later copied to stdout.
    pub fn file_for_writing(
        &self,
        outputs: &OutputFilenames,
        flavor: OutputType,
        codegen_unit_name: &str,
        invocation_temp: Option<&str>,
    ) -> PathBuf {
        match *self {
            OutFileName::Real(ref path) => path.clone(),
            OutFileName::Stdout => {
                outputs.temp_path_for_cgu(flavor, codegen_unit_name, invocation_temp)
            }
        }
    }

    pub fn overwrite(&self, content: &str, sess: &Session) {
        match self {
            OutFileName::Stdout => print!("{content}"),
            OutFileName::Real(path) => {
                if let Err(e) = fs::write(path, content) {
                    sess.dcx().emit_fatal(FileWriteFail { path, err: e.to_string() });
                }
            }
        }
    }
}

#[derive(Clone, Hash, Debug, HashStable_Generic, Encodable, Decodable)]
pub struct OutputFilenames {
    pub(crate) out_directory: PathBuf,
    /// Crate name. Never contains '-'.
    crate_stem: String,
    /// Typically based on `.rs` input file name. Any '-' is preserved.
    filestem: String,
    pub single_output_file: Option<OutFileName>,
    temps_directory: Option<PathBuf>,
    explicit_dwo_out_directory: Option<PathBuf>,
    pub outputs: OutputTypes,
}

pub const RLINK_EXT: &str = "rlink";
pub const RUST_CGU_EXT: &str = "rcgu";
pub const DWARF_OBJECT_EXT: &str = "dwo";
pub const MAX_FILENAME_LENGTH: usize = 143; // ecryptfs limits filenames to 143 bytes see #49914

/// Ensure the filename is not too long, as some filesystems have a limit.
/// If the filename is too long, hash part of it and append the hash to the filename.
/// This is a workaround for long crate names generating overly long filenames.
fn maybe_strip_file_name(mut path: PathBuf) -> PathBuf {
    if path.file_name().map_or(0, |name| name.len()) > MAX_FILENAME_LENGTH {
        let filename = path.file_name().unwrap().to_string_lossy();
        let hash_len = 64 / 4; // Hash64 is 64 bits encoded in hex
        let hyphen_len = 1; // the '-' we insert between hash and suffix

        // number of bytes of suffix we can keep so that "hash-<suffix>" fits
        let allowed_suffix = MAX_FILENAME_LENGTH.saturating_sub(hash_len + hyphen_len);

        // number of bytes to remove from the start
        let stripped_bytes = filename.len().saturating_sub(allowed_suffix);

        // ensure we don't cut in a middle of a char
        let split_at = filename.ceil_char_boundary(stripped_bytes);

        let mut hasher = StableHasher::new();
        filename[..split_at].hash(&mut hasher);
        let hash = hasher.finish::<Hash64>();

        path.set_file_name(format!("{:x}-{}", hash, &filename[split_at..]));
    }
    path
}
impl OutputFilenames {
    pub fn new(
        out_directory: PathBuf,
        out_crate_name: String,
        out_filestem: String,
        single_output_file: Option<OutFileName>,
        temps_directory: Option<PathBuf>,
        explicit_dwo_out_directory: Option<PathBuf>,
        extra: String,
        outputs: OutputTypes,
    ) -> Self {
        OutputFilenames {
            out_directory,
            single_output_file,
            temps_directory,
            explicit_dwo_out_directory,
            outputs,
            crate_stem: format!("{out_crate_name}{extra}"),
            filestem: format!("{out_filestem}{extra}"),
        }
    }

    pub fn path(&self, flavor: OutputType) -> OutFileName {
        self.outputs
            .get(&flavor)
            .and_then(|p| p.to_owned())
            .or_else(|| self.single_output_file.clone())
            .unwrap_or_else(|| OutFileName::Real(self.output_path(flavor)))
    }

    pub fn interface_path(&self) -> PathBuf {
        self.out_directory.join(format!("lib{}.rs", self.crate_stem))
    }

    /// Gets the output path where a compilation artifact of the given type
    /// should be placed on disk.
    fn output_path(&self, flavor: OutputType) -> PathBuf {
        let extension = flavor.extension();
        match flavor {
            OutputType::Metadata => {
                self.out_directory.join(format!("lib{}.{}", self.crate_stem, extension))
            }
            _ => self.with_directory_and_extension(&self.out_directory, extension),
        }
    }

    /// Gets the path where a compilation artifact of the given type for the
    /// given codegen unit should be placed on disk. If codegen_unit_name is
    /// None, a path distinct from those of any codegen unit will be generated.
    pub fn temp_path_for_cgu(
        &self,
        flavor: OutputType,
        codegen_unit_name: &str,
        invocation_temp: Option<&str>,
    ) -> PathBuf {
        let extension = flavor.extension();
        self.temp_path_ext_for_cgu(extension, codegen_unit_name, invocation_temp)
    }

    /// Like `temp_path`, but specifically for dwarf objects.
    pub fn temp_path_dwo_for_cgu(
        &self,
        codegen_unit_name: &str,
        invocation_temp: Option<&str>,
    ) -> PathBuf {
        let p = self.temp_path_ext_for_cgu(DWARF_OBJECT_EXT, codegen_unit_name, invocation_temp);
        if let Some(dwo_out) = &self.explicit_dwo_out_directory {
            let mut o = dwo_out.clone();
            o.push(p.file_name().unwrap());
            o
        } else {
            p
        }
    }

    /// Like `temp_path`, but also supports things where there is no corresponding
    /// OutputType, like noopt-bitcode or lto-bitcode.
    pub fn temp_path_ext_for_cgu(
        &self,
        ext: &str,
        codegen_unit_name: &str,
        invocation_temp: Option<&str>,
    ) -> PathBuf {
        let mut extension = codegen_unit_name.to_string();

        // Append `.{invocation_temp}` to ensure temporary files are unique.
        if let Some(rng) = invocation_temp {
            extension.push('.');
            extension.push_str(rng);
        }

        // FIXME: This is sketchy that we're not appending `.rcgu` when the ext is empty.
        // Append `.rcgu.{ext}`.
        if !ext.is_empty() {
            extension.push('.');
            extension.push_str(RUST_CGU_EXT);
            extension.push('.');
            extension.push_str(ext);
        }

        let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
        maybe_strip_file_name(self.with_directory_and_extension(temps_directory, &extension))
    }

    pub fn temp_path_for_diagnostic(&self, ext: &str) -> PathBuf {
        let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
        self.with_directory_and_extension(temps_directory, &ext)
    }

    pub fn with_extension(&self, extension: &str) -> PathBuf {
        self.with_directory_and_extension(&self.out_directory, extension)
    }

    pub fn with_directory_and_extension(&self, directory: &Path, extension: &str) -> PathBuf {
        let mut path = directory.join(&self.filestem);
        path.set_extension(extension);
        path
    }

    /// Returns the path for the Split DWARF file - this can differ depending on which Split DWARF
    /// mode is being used, which is the logic that this function is intended to encapsulate.
    pub fn split_dwarf_path(
        &self,
        split_debuginfo_kind: SplitDebuginfo,
        split_dwarf_kind: SplitDwarfKind,
        cgu_name: &str,
        invocation_temp: Option<&str>,
    ) -> Option<PathBuf> {
        let obj_out = self.temp_path_for_cgu(OutputType::Object, cgu_name, invocation_temp);
        let dwo_out = self.temp_path_dwo_for_cgu(cgu_name, invocation_temp);
        match (split_debuginfo_kind, split_dwarf_kind) {
            (SplitDebuginfo::Off, SplitDwarfKind::Single | SplitDwarfKind::Split) => None,
            // Single mode doesn't change how DWARF is emitted, but does add Split DWARF attributes
            // (pointing at the path which is being determined here). Use the path to the current
            // object file.
            (SplitDebuginfo::Packed | SplitDebuginfo::Unpacked, SplitDwarfKind::Single) => {
                Some(obj_out)
            }
            // Split mode emits the DWARF into a different file, use that path.
            (SplitDebuginfo::Packed | SplitDebuginfo::Unpacked, SplitDwarfKind::Split) => {
                Some(dwo_out)
            }
        }
    }
}

pub(crate) fn parse_remap_path_scope(
    early_dcx: &EarlyDiagCtxt,
    matches: &getopts::Matches,
    unstable_opts: &UnstableOptions,
) -> RemapPathScopeComponents {
    if let Some(v) = matches.opt_str("remap-path-scope") {
        let mut slot = RemapPathScopeComponents::empty();
        for s in v.split(',') {
            slot |= match s {
                "macro" => RemapPathScopeComponents::MACRO,
                "diagnostics" => RemapPathScopeComponents::DIAGNOSTICS,
                "documentation" => {
                    if !unstable_opts.unstable_options {
                        early_dcx.early_fatal("remapping `documentation` path scope requested but `-Zunstable-options` not specified");
                    }

                    RemapPathScopeComponents::DOCUMENTATION
                },
                "debuginfo" => RemapPathScopeComponents::DEBUGINFO,
                "coverage" => RemapPathScopeComponents::COVERAGE,
                "object" => RemapPathScopeComponents::OBJECT,
                "all" => RemapPathScopeComponents::all(),
                _ => early_dcx.early_fatal("argument for `--remap-path-scope` must be a comma separated list of scopes: `macro`, `diagnostics`, `documentation`, `debuginfo`, `coverage`, `object`, `all`"),
            }
        }
        slot
    } else {
        RemapPathScopeComponents::all()
    }
}

#[derive(Clone, Debug)]
pub struct Sysroot {
    pub explicit: Option<PathBuf>,
    pub default: PathBuf,
}

impl Sysroot {
    pub fn new(explicit: Option<PathBuf>) -> Sysroot {
        Sysroot { explicit, default: filesearch::default_sysroot() }
    }

    /// Return explicit sysroot if it was passed with `--sysroot`, or default sysroot otherwise.
    pub fn path(&self) -> &Path {
        self.explicit.as_deref().unwrap_or(&self.default)
    }

    /// Returns both explicit sysroot if it was passed with `--sysroot` and the default sysroot.
    pub fn all_paths(&self) -> impl Iterator<Item = &Path> {
        self.explicit.as_deref().into_iter().chain(iter::once(&*self.default))
    }
}

pub fn host_tuple() -> &'static str {
    // Get the host triple out of the build environment. This ensures that our
    // idea of the host triple is the same as for the set of libraries we've
    // actually built. We can't just take LLVM's host triple because they
    // normalize all ix86 architectures to i386.
    //
    // Instead of grabbing the host triple (for the current host), we grab (at
    // compile time) the target triple that this rustc is built with and
    // calling that (at runtime) the host triple.
    (option_env!("CFG_COMPILER_HOST_TRIPLE")).expect("CFG_COMPILER_HOST_TRIPLE")
}

fn file_path_mapping(
    remap_path_prefix: Vec<(PathBuf, PathBuf)>,
    remap_path_scope: RemapPathScopeComponents,
) -> FilePathMapping {
    FilePathMapping::new(remap_path_prefix.clone(), remap_path_scope)
}

impl Default for Options {
    fn default() -> Options {
        let unstable_opts = UnstableOptions::default();

        // FIXME(Urgau): This is a hack that ideally shouldn't exist, but rustdoc
        // currently uses this `Default` implementation, so we have no choice but
        // to create a default working directory.
        let working_dir = {
            let working_dir = std::env::current_dir().unwrap();
            let file_mapping = file_path_mapping(Vec::new(), RemapPathScopeComponents::empty());
            file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
        };

        Options {
            assert_incr_state: None,
            crate_types: Vec::new(),
            optimize: OptLevel::No,
            debuginfo: DebugInfo::None,
            lint_opts: Vec::new(),
            lint_cap: None,
            describe_lints: false,
            output_types: OutputTypes(BTreeMap::new()),
            search_paths: vec![],
            sysroot: Sysroot::new(None),
            target_triple: TargetTuple::from_tuple(host_tuple()),
            test: false,
            incremental: None,
            untracked_state_hash: Default::default(),
            unstable_opts,
            prints: Vec::new(),
            cg: Default::default(),
            error_format: ErrorOutputType::default(),
            diagnostic_width: None,
            externs: Externs(BTreeMap::new()),
            crate_name: None,
            libs: Vec::new(),
            unstable_features: UnstableFeatures::Disallow,
            debug_assertions: true,
            actually_rustdoc: false,
            resolve_doc_links: ResolveDocLinks::None,
            trimmed_def_paths: false,
            cli_forced_codegen_units: None,
            cli_forced_local_thinlto_off: false,
            remap_path_prefix: Vec::new(),
            remap_path_scope: RemapPathScopeComponents::all(),
            real_rust_source_base_dir: None,
            real_rustc_dev_source_base_dir: None,
            edition: DEFAULT_EDITION,
            json_artifact_notifications: false,
            json_timings: false,
            json_unused_externs: JsonUnusedExterns::No,
            json_future_incompat: false,
            pretty: None,
            working_dir,
            color: ColorConfig::Auto,
            logical_env: FxIndexMap::default(),
            verbose: false,
            target_modifiers: BTreeMap::default(),
        }
    }
}

impl Options {
    /// Returns `true` if there is a reason to build the dep graph.
    pub fn build_dep_graph(&self) -> bool {
        self.incremental.is_some()
            || self.unstable_opts.dump_dep_graph
            || self.unstable_opts.query_dep_graph
    }

    pub fn file_path_mapping(&self) -> FilePathMapping {
        file_path_mapping(self.remap_path_prefix.clone(), self.remap_path_scope)
    }

    /// Returns `true` if there will be an output file generated.
    pub fn will_create_output_file(&self) -> bool {
        !self.unstable_opts.parse_crate_root_only && // The file is just being parsed
            self.unstable_opts.ls.is_empty() // The file is just being queried
    }

    #[inline]
    pub fn share_generics(&self) -> bool {
        match self.unstable_opts.share_generics {
            Some(setting) => setting,
            None => match self.optimize {
                OptLevel::No | OptLevel::Less | OptLevel::Size | OptLevel::SizeMin => true,
                OptLevel::More | OptLevel::Aggressive => false,
            },
        }
    }

    pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
        self.cg.symbol_mangling_version.unwrap_or(if self.unstable_features.is_nightly_build() {
            SymbolManglingVersion::V0
        } else {
            SymbolManglingVersion::Legacy
        })
    }

    #[inline]
    pub fn autodiff_enabled(&self) -> bool {
        self.unstable_opts.autodiff.contains(&AutoDiff::Enable)
    }
}

impl UnstableOptions {
    pub fn dcx_flags(&self, can_emit_warnings: bool) -> DiagCtxtFlags {
        DiagCtxtFlags {
            can_emit_warnings,
            treat_err_as_bug: self.treat_err_as_bug,
            eagerly_emit_delayed_bugs: self.eagerly_emit_delayed_bugs,
            macro_backtrace: self.macro_backtrace,
            deduplicate_diagnostics: self.deduplicate_diagnostics,
            track_diagnostics: self.track_diagnostics,
        }
    }

    pub fn src_hash_algorithm(&self, target: &Target) -> SourceFileHashAlgorithm {
        self.src_hash_algorithm.unwrap_or_else(|| {
            if target.is_like_msvc {
                SourceFileHashAlgorithm::Sha256
            } else {
                SourceFileHashAlgorithm::Md5
            }
        })
    }

    pub fn checksum_hash_algorithm(&self) -> Option<SourceFileHashAlgorithm> {
        self.checksum_hash_algorithm
    }
}

// The type of entry function, so users can have their own entry functions
#[derive(Copy, Clone, PartialEq, Hash, Debug, HashStable_Generic)]
pub enum EntryFnType {
    Main {
        /// Specifies what to do with `SIGPIPE` before calling `fn main()`.
        ///
        /// What values that are valid and what they mean must be in sync
        /// across rustc and libstd, but we don't want it public in libstd,
        /// so we take a bit of an unusual approach with simple constants
        /// and an `include!()`.
        sigpipe: u8,
    },
}

pub use rustc_hir::attrs::CrateType;

#[derive(Clone, Hash, Debug, PartialEq, Eq, Encodable, Decodable)]
pub enum Passes {
    Some(Vec<String>),
    All,
}

impl Passes {
    fn is_empty(&self) -> bool {
        match *self {
            Passes::Some(ref v) => v.is_empty(),
            Passes::All => false,
        }
    }

    pub(crate) fn extend(&mut self, passes: impl IntoIterator<Item = String>) {
        match *self {
            Passes::Some(ref mut v) => v.extend(passes),
            Passes::All => {}
        }
    }
}

#[derive(Clone, Copy, Hash, Debug, PartialEq)]
pub enum PAuthKey {
    A,
    B,
}

#[derive(Clone, Copy, Hash, Debug, PartialEq)]
pub struct PacRet {
    pub leaf: bool,
    pub pc: bool,
    pub key: PAuthKey,
}

#[derive(Clone, Copy, Hash, Debug, PartialEq, Default)]
pub struct BranchProtection {
    pub bti: bool,
    pub pac_ret: Option<PacRet>,
    pub gcs: bool,
}

pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
    // First disallow some configuration given on the command line
    cfg::disallow_cfgs(sess, &user_cfg);

    // Then combine the configuration requested by the session (command line) with
    // some default and generated configuration items.
    user_cfg.extend(cfg::default_configuration(sess));
    user_cfg
}

pub fn build_target_config(
    early_dcx: &EarlyDiagCtxt,
    target: &TargetTuple,
    sysroot: &Path,
    unstable_options: bool,
) -> Target {
    match Target::search(target, sysroot, unstable_options) {
        Ok((target, warnings)) => {
            for warning in warnings.warning_messages() {
                early_dcx.early_warn(warning)
            }

            if !matches!(target.pointer_width, 16 | 32 | 64) {
                early_dcx.early_fatal(format!(
                    "target specification was invalid: unrecognized target-pointer-width {}",
                    target.pointer_width
                ))
            }
            target
        }
        Err(e) => {
            let mut err =
                early_dcx.early_struct_fatal(format!("error loading target specification: {e}"));
            err.help("run `rustc --print target-list` for a list of built-in targets");
            err.emit()
        }
    }
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum OptionStability {
    Stable,
    Unstable,
}

#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum OptionKind {
    /// An option that takes a value, and cannot appear more than once (e.g. `--out-dir`).
    ///
    /// Corresponds to [`getopts::Options::optopt`].
    Opt,

    /// An option that takes a value, and can appear multiple times (e.g. `--emit`).
    ///
    /// Corresponds to [`getopts::Options::optmulti`].
    Multi,

    /// An option that does not take a value, and cannot appear more than once (e.g. `--help`).
    ///
    /// Corresponds to [`getopts::Options::optflag`].
    /// The `hint` string must be empty.
    Flag,

    /// An option that does not take a value, and can appear multiple times (e.g. `-O`).
    ///
    /// Corresponds to [`getopts::Options::optflagmulti`].
    /// The `hint` string must be empty.
    FlagMulti,
}

pub struct RustcOptGroup {
    /// The "primary" name for this option. Normally equal to `long_name`,
    /// except for options that don't have a long name, in which case
    /// `short_name` is used.
    ///
    /// This is needed when interacting with `getopts` in some situations,
    /// because if an option has both forms, that library treats the long name
    /// as primary and the short name as an alias.
    pub name: &'static str,
    stability: OptionStability,
    kind: OptionKind,

    short_name: &'static str,
    long_name: &'static str,
    desc: &'static str,
    value_hint: &'static str,

    /// If true, this option should not be printed by `rustc --help`, but
    /// should still be printed by `rustc --help -v`.
    pub is_verbose_help_only: bool,
}

impl RustcOptGroup {
    pub fn is_stable(&self) -> bool {
        self.stability == OptionStability::Stable
    }

    pub fn apply(&self, options: &mut getopts::Options) {
        let &Self { short_name, long_name, desc, value_hint, .. } = self;
        match self.kind {
            OptionKind::Opt => options.optopt(short_name, long_name, desc, value_hint),
            OptionKind::Multi => options.optmulti(short_name, long_name, desc, value_hint),
            OptionKind::Flag => options.optflag(short_name, long_name, desc),
            OptionKind::FlagMulti => options.optflagmulti(short_name, long_name, desc),
        };
    }

    /// This is for diagnostics-only.
    pub fn long_name(&self) -> &str {
        self.long_name
    }
}

pub fn make_opt(
    stability: OptionStability,
    kind: OptionKind,
    short_name: &'static str,
    long_name: &'static str,
    desc: &'static str,
    value_hint: &'static str,
) -> RustcOptGroup {
    // "Flag" options don't have a value, and therefore don't have a value hint.
    match kind {
        OptionKind::Opt | OptionKind::Multi => {}
        OptionKind::Flag | OptionKind::FlagMulti => assert_eq!(value_hint, ""),
    }
    RustcOptGroup {
        name: cmp::max_by_key(short_name, long_name, |s| s.len()),
        stability,
        kind,
        short_name,
        long_name,
        desc,
        value_hint,
        is_verbose_help_only: false,
    }
}

static EDITION_STRING: LazyLock<String> = LazyLock::new(|| {
    format!(
        "Specify which edition of the compiler to use when compiling code. \
The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE_EDITION}."
    )
});

static EMIT_HELP: LazyLock<String> = LazyLock::new(|| {
    let mut result =
        String::from("Comma separated list of types of output for the compiler to emit.\n");
    result.push_str("Each TYPE has the default FILE name:\n");

    for output in OutputType::iter_all() {
        result.push_str(&format!("*  {} - {}\n", output.shorthand(), output.default_filename()));
    }

    result
});

/// Returns all rustc command line options, including metadata for
/// each option, such as whether the option is stable.
///
/// # Option style guidelines
///
/// - `<param>`: Indicates a required parameter
/// - `[param]`: Indicates an optional parameter
/// - `|`: Indicates a mutually exclusive option
/// - `*`: a list element with description
pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
    use OptionKind::{Flag, FlagMulti, Multi, Opt};
    use OptionStability::{Stable, Unstable};

    use self::make_opt as opt;

    let mut options = vec![
        opt(Stable, Flag, "h", "help", "Display this message", ""),
        opt(
            Stable,
            Multi,
            "",
            "cfg",
            "Configure the compilation environment.\n\
                SPEC supports the syntax `<NAME>[=\"<VALUE>\"]`.",
            "<SPEC>",
        ),
        opt(Stable, Multi, "", "check-cfg", "Provide list of expected cfgs for checking", "<SPEC>"),
        opt(
            Stable,
            Multi,
            "L",
            "",
            "Add a directory to the library search path. \
                The optional KIND can be one of <dependency|crate|native|framework|all> (default: all).",
            "[<KIND>=]<PATH>",
        ),
        opt(
            Stable,
            Multi,
            "l",
            "",
            "Link the generated crate(s) to the specified native\n\
                library NAME. The optional KIND can be one of\n\
                <static|framework|dylib> (default: dylib).\n\
                Optional comma separated MODIFIERS\n\
                <bundle|verbatim|whole-archive|as-needed>\n\
                may be specified each with a prefix of either '+' to\n\
                enable or '-' to disable.",
            "[<KIND>[:<MODIFIERS>]=]<NAME>[:<RENAME>]",
        ),
        make_crate_type_option(),
        opt(Stable, Opt, "", "crate-name", "Specify the name of the crate being built", "<NAME>"),
        opt(Stable, Opt, "", "edition", &EDITION_STRING, EDITION_NAME_LIST),
        opt(Stable, Multi, "", "emit", &EMIT_HELP, "<TYPE>[=<FILE>]"),
        opt(Stable, Multi, "", "print", &print_request::PRINT_HELP, "<INFO>[=<FILE>]"),
        opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
        opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=3", ""),
        opt(Stable, Opt, "o", "", "Write output to FILENAME", "<FILENAME>"),
        opt(Stable, Opt, "", "out-dir", "Write output to compiler-chosen filename in DIR", "<DIR>"),
        opt(
            Stable,
            Opt,
            "",
            "explain",
            "Provide a detailed explanation of an error message",
            "<OPT>",
        ),
        opt(Stable, Flag, "", "test", "Build a test harness", ""),
        opt(Stable, Opt, "", "target", "Target tuple for which the code is compiled", "<TARGET>"),
        opt(Stable, Multi, "A", "allow", "Set lint allowed", "<LINT>"),
        opt(Stable, Multi, "W", "warn", "Set lint warnings", "<LINT>"),
        opt(Stable, Multi, "", "force-warn", "Set lint force-warn", "<LINT>"),
        opt(Stable, Multi, "D", "deny", "Set lint denied", "<LINT>"),
        opt(Stable, Multi, "F", "forbid", "Set lint forbidden", "<LINT>"),
        opt(
            Stable,
            Multi,
            "",
            "cap-lints",
            "Set the most restrictive lint level. More restrictive lints are capped at this level",
            "<LEVEL>",
        ),
        opt(Stable, Multi, "C", "codegen", "Set a codegen option", "<OPT>[=<VALUE>]"),
        opt(Stable, Flag, "V", "version", "Print version info and exit", ""),
        opt(Stable, Flag, "v", "verbose", "Use verbose output", ""),
    ];

    // Options in this list are hidden from `rustc --help` by default, but are
    // shown by `rustc --help -v`.
    let verbose_only = [
        opt(
            Stable,
            Multi,
            "",
            "extern",
            "Specify where an external rust library is located",
            "<NAME>[=<PATH>]",
        ),
        opt(Stable, Opt, "", "sysroot", "Override the system root", "<PATH>"),
        opt(Unstable, Multi, "Z", "", "Set unstable / perma-unstable options", "<FLAG>"),
        opt(
            Stable,
            Opt,
            "",
            "error-format",
            "How errors and other messages are produced",
            "<human|json|short>",
        ),
        opt(Stable, Multi, "", "json", "Configure the JSON output of the compiler", "<CONFIG>"),
        opt(
            Stable,
            Opt,
            "",
            "color",
            "Configure coloring of output:
                * auto   = colorize, if output goes to a tty (default);
                * always = always colorize output;
                * never  = never colorize output",
            "<auto|always|never>",
        ),
        opt(
            Stable,
            Opt,
            "",
            "diagnostic-width",
            "Inform rustc of the width of the output so that diagnostics can be truncated to fit",
            "<WIDTH>",
        ),
        opt(
            Stable,
            Multi,
            "",
            "remap-path-prefix",
            "Remap source names in all output (compiler messages and output files)",
            "<FROM>=<TO>",
        ),
        opt(
            Stable,
            Opt,
            "",
            "remap-path-scope",
            "Defines which scopes of paths should be remapped by `--remap-path-prefix`",
            "<macro,diagnostics,debuginfo,coverage,object,all>",
        ),
        opt(Unstable, Multi, "", "env-set", "Inject an environment variable", "<VAR>=<VALUE>"),
    ];
    options.extend(verbose_only.into_iter().map(|mut opt| {
        opt.is_verbose_help_only = true;
        opt
    }));

    options
}

pub fn get_cmd_lint_options(
    early_dcx: &EarlyDiagCtxt,
    matches: &getopts::Matches,
) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
    let mut lint_opts_with_position = vec![];
    let mut describe_lints = false;

    for level in [lint::Allow, lint::Warn, lint::ForceWarn, lint::Deny, lint::Forbid] {
        for (arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
            if lint_name == "help" {
                describe_lints = true;
            } else {
                lint_opts_with_position.push((arg_pos, lint_name.replace('-', "_"), level));
            }
        }
    }

    lint_opts_with_position.sort_by_key(|x| x.0);
    let lint_opts = lint_opts_with_position
        .iter()
        .cloned()
        .map(|(_, lint_name, level)| (lint_name, level))
        .collect();

    let lint_cap = matches.opt_str("cap-lints").map(|cap| {
        lint::Level::from_str(&cap)
            .unwrap_or_else(|| early_dcx.early_fatal(format!("unknown lint level: `{cap}`")))
    });

    (lint_opts, describe_lints, lint_cap)
}

/// Parses the `--color` flag.
pub fn parse_color(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> ColorConfig {
    match matches.opt_str("color").as_deref() {
        Some("auto") => ColorConfig::Auto,
        Some("always") => ColorConfig::Always,
        Some("never") => ColorConfig::Never,

        None => ColorConfig::Auto,

        Some(arg) => early_dcx.early_fatal(format!(
            "argument for `--color` must be auto, \
                 always or never (instead was `{arg}`)"
        )),
    }
}

/// Possible json config files
pub struct JsonConfig {
    pub json_rendered: HumanReadableErrorType,
    pub json_color: ColorConfig,
    json_artifact_notifications: bool,
    /// Output start and end timestamps of several high-level compilation sections
    /// (frontend, backend, linker).
    json_timings: bool,
    pub json_unused_externs: JsonUnusedExterns,
    json_future_incompat: bool,
}

/// Report unused externs in event stream
#[derive(Copy, Clone)]
pub enum JsonUnusedExterns {
    /// Do not
    No,
    /// Report, but do not exit with failure status for deny/forbid
    Silent,
    /// Report, and also exit with failure status for deny/forbid
    Loud,
}

impl JsonUnusedExterns {
    pub fn is_enabled(&self) -> bool {
        match self {
            JsonUnusedExterns::No => false,
            JsonUnusedExterns::Loud | JsonUnusedExterns::Silent => true,
        }
    }

    pub fn is_loud(&self) -> bool {
        match self {
            JsonUnusedExterns::No | JsonUnusedExterns::Silent => false,
            JsonUnusedExterns::Loud => true,
        }
    }
}

/// Parse the `--json` flag.
///
/// The first value returned is how to render JSON diagnostics, and the second
/// is whether or not artifact notifications are enabled.
pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> JsonConfig {
    let mut json_rendered = HumanReadableErrorType { short: false, unicode: false };
    let mut json_color = ColorConfig::Never;
    let mut json_artifact_notifications = false;
    let mut json_unused_externs = JsonUnusedExterns::No;
    let mut json_future_incompat = false;
    let mut json_timings = false;
    for option in matches.opt_strs("json") {
        // For now conservatively forbid `--color` with `--json` since `--json`
        // won't actually be emitting any colors and anything colorized is
        // embedded in a diagnostic message anyway.
        if matches.opt_str("color").is_some() {
            early_dcx.early_fatal("cannot specify the `--color` option with `--json`");
        }

        for sub_option in option.split(',') {
            match sub_option {
                "diagnostic-short" => {
                    json_rendered = HumanReadableErrorType { short: true, unicode: false };
                }
                "diagnostic-unicode" => {
                    json_rendered = HumanReadableErrorType { short: false, unicode: true };
                }
                "diagnostic-rendered-ansi" => json_color = ColorConfig::Always,
                "artifacts" => json_artifact_notifications = true,
                "timings" => json_timings = true,
                "unused-externs" => json_unused_externs = JsonUnusedExterns::Loud,
                "unused-externs-silent" => json_unused_externs = JsonUnusedExterns::Silent,
                "future-incompat" => json_future_incompat = true,
                s => early_dcx.early_fatal(format!("unknown `--json` option `{s}`")),
            }
        }
    }

    JsonConfig {
        json_rendered,
        json_color,
        json_artifact_notifications,
        json_timings,
        json_unused_externs,
        json_future_incompat,
    }
}

/// Parses the `--error-format` flag.
pub fn parse_error_format(
    early_dcx: &mut EarlyDiagCtxt,
    matches: &getopts::Matches,
    color_config: ColorConfig,
    json_color: ColorConfig,
    json_rendered: HumanReadableErrorType,
) -> ErrorOutputType {
    let default_kind = HumanReadableErrorType { short: false, unicode: false };
    // We need the `opts_present` check because the driver will send us Matches
    // with only stable options if no unstable options are used. Since error-format
    // is unstable, it will not be present. We have to use `opts_present` not
    // `opt_present` because the latter will panic.
    let error_format = if matches.opts_present(&["error-format".to_owned()]) {
        match matches.opt_str("error-format").as_deref() {
            None | Some("human") => {
                ErrorOutputType::HumanReadable { color_config, kind: default_kind }
            }
            Some("json") => {
                ErrorOutputType::Json { pretty: false, json_rendered, color_config: json_color }
            }
            Some("pretty-json") => {
                ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color }
            }
            Some("short") => ErrorOutputType::HumanReadable {
                kind: HumanReadableErrorType { short: true, unicode: false },
                color_config,
            },
            Some("human-unicode") => ErrorOutputType::HumanReadable {
                kind: HumanReadableErrorType { short: false, unicode: true },
                color_config,
            },
            Some(arg) => {
                early_dcx.set_error_format(ErrorOutputType::HumanReadable {
                    color_config,
                    kind: default_kind,
                });
                early_dcx.early_fatal(format!(
                    "argument for `--error-format` must be `human`, `human-unicode`, \
                    `json`, `pretty-json` or `short` (instead was `{arg}`)"
                ))
            }
        }
    } else {
        ErrorOutputType::HumanReadable { color_config, kind: default_kind }
    };

    match error_format {
        ErrorOutputType::Json { .. } => {}

        // Conservatively require that the `--json` argument is coupled with
        // `--error-format=json`. This means that `--json` is specified we
        // should actually be emitting JSON blobs.
        _ if !matches.opt_strs("json").is_empty() => {
            early_dcx.early_fatal("using `--json` requires also using `--error-format=json`");
        }

        _ => {}
    }

    error_format
}

pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Edition {
    let edition = match matches.opt_str("edition") {
        Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| {
            early_dcx.early_fatal(format!(
                "argument for `--edition` must be one of: \
                     {EDITION_NAME_LIST}. (instead was `{arg}`)"
            ))
        }),
        None => DEFAULT_EDITION,
    };

    if !edition.is_stable() && !nightly_options::is_unstable_enabled(matches) {
        let is_nightly = nightly_options::match_is_nightly_build(matches);
        let msg = if !is_nightly {
            format!(
                "the crate requires edition {edition}, but the latest edition supported by this Rust version is {LATEST_STABLE_EDITION}"
            )
        } else {
            format!("edition {edition} is unstable and only available with -Z unstable-options")
        };
        early_dcx.early_fatal(msg)
    }

    edition
}

fn check_error_format_stability(
    early_dcx: &EarlyDiagCtxt,
    unstable_opts: &UnstableOptions,
    is_nightly_build: bool,
    format: ErrorOutputType,
) {
    if unstable_opts.unstable_options || is_nightly_build {
        return;
    }
    let format = match format {
        ErrorOutputType::Json { pretty: true, .. } => "pretty-json",
        ErrorOutputType::HumanReadable { kind, .. } => match kind {
            HumanReadableErrorType { unicode: true, .. } => "human-unicode",
            _ => return,
        },
        _ => return,
    };
    early_dcx.early_fatal(format!("`--error-format={format}` is unstable"))
}

fn parse_output_types(
    early_dcx: &EarlyDiagCtxt,
    unstable_opts: &UnstableOptions,
    matches: &getopts::Matches,
) -> OutputTypes {
    let mut output_types = BTreeMap::new();
    if !unstable_opts.parse_crate_root_only {
        for list in matches.opt_strs("emit") {
            for output_type in list.split(',') {
                let (shorthand, path) = split_out_file_name(output_type);
                let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
                    early_dcx.early_fatal(format!(
                        "unknown emission type: `{shorthand}` - expected one of: {display}",
                        display = OutputType::shorthands_display(),
                    ))
                });
                if output_type == OutputType::ThinLinkBitcode && !unstable_opts.unstable_options {
                    early_dcx.early_fatal(format!(
                        "{} requested but -Zunstable-options not specified",
                        OutputType::ThinLinkBitcode.shorthand()
                    ));
                }
                output_types.insert(output_type, path);
            }
        }
    };
    if output_types.is_empty() {
        output_types.insert(OutputType::Exe, None);
    }
    OutputTypes(output_types)
}

fn split_out_file_name(arg: &str) -> (&str, Option<OutFileName>) {
    match arg.split_once('=') {
        None => (arg, None),
        Some((kind, "-")) => (kind, Some(OutFileName::Stdout)),
        Some((kind, path)) => (kind, Some(OutFileName::Real(PathBuf::from(path)))),
    }
}

fn should_override_cgus_and_disable_thinlto(
    early_dcx: &EarlyDiagCtxt,
    output_types: &OutputTypes,
    matches: &getopts::Matches,
    mut codegen_units: Option<usize>,
) -> (bool, Option<usize>) {
    let mut disable_local_thinlto = false;
    // Issue #30063: if user requests LLVM-related output to one
    // particular path, disable codegen-units.
    let incompatible: Vec<_> = output_types
        .0
        .iter()
        .map(|ot_path| ot_path.0)
        .filter(|ot| !ot.is_compatible_with_codegen_units_and_single_output_file())
        .map(|ot| ot.shorthand())
        .collect();
    if !incompatible.is_empty() {
        match codegen_units {
            Some(n) if n > 1 => {
                if matches.opt_present("o") {
                    for ot in &incompatible {
                        early_dcx.early_warn(format!(
                            "`--emit={ot}` with `-o` incompatible with \
                                 `-C codegen-units=N` for N > 1",
                        ));
                    }
                    early_dcx.early_warn("resetting to default -C codegen-units=1");
                    codegen_units = Some(1);
                    disable_local_thinlto = true;
                }
            }
            _ => {
                codegen_units = Some(1);
                disable_local_thinlto = true;
            }
        }
    }

    if codegen_units == Some(0) {
        early_dcx.early_fatal("value for codegen units must be a positive non-zero integer");
    }

    (disable_local_thinlto, codegen_units)
}

pub fn parse_target_triple(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> TargetTuple {
    match matches.opt_str("target") {
        Some(target) if target.ends_with(".json") => {
            let path = Path::new(&target);
            TargetTuple::from_path(path).unwrap_or_else(|_| {
                early_dcx.early_fatal(format!("target file {path:?} does not exist"))
            })
        }
        Some(target) => TargetTuple::TargetTuple(target),
        _ => TargetTuple::from_tuple(host_tuple()),
    }
}

fn parse_opt_level(
    early_dcx: &EarlyDiagCtxt,
    matches: &getopts::Matches,
    cg: &CodegenOptions,
) -> OptLevel {
    // The `-O` and `-C opt-level` flags specify the same setting, so we want to be able
    // to use them interchangeably. However, because they're technically different flags,
    // we need to work out manually which should take precedence if both are supplied (i.e.
    // the rightmost flag). We do this by finding the (rightmost) position of both flags and
    // comparing them. Note that if a flag is not found, its position will be `None`, which
    // always compared less than `Some(_)`.
    let max_o = matches.opt_positions("O").into_iter().max();
    let max_c = matches
        .opt_strs_pos("C")
        .into_iter()
        .flat_map(|(i, s)| {
            // NB: This can match a string without `=`.
            if let Some("opt-level") = s.split('=').next() { Some(i) } else { None }
        })
        .max();
    if max_o > max_c {
        OptLevel::Aggressive
    } else {
        match cg.opt_level.as_ref() {
            "0" => OptLevel::No,
            "1" => OptLevel::Less,
            "2" => OptLevel::More,
            "3" => OptLevel::Aggressive,
            "s" => OptLevel::Size,
            "z" => OptLevel::SizeMin,
            arg => {
                early_dcx.early_fatal(format!(
                    "optimization level needs to be \
                            between 0-3, s or z (instead was `{arg}`)"
                ));
            }
        }
    }
}

fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInfo {
    let max_g = matches.opt_positions("g").into_iter().max();
    let max_c = matches
        .opt_strs_pos("C")
        .into_iter()
        .flat_map(|(i, s)| {
            // NB: This can match a string without `=`.
            if let Some("debuginfo") = s.split('=').next() { Some(i) } else { None }
        })
        .max();
    if max_g > max_c { DebugInfo::Full } else { cg.debuginfo }
}

fn parse_assert_incr_state(
    early_dcx: &EarlyDiagCtxt,
    opt_assertion: &Option<String>,
) -> Option<IncrementalStateAssertion> {
    match opt_assertion {
        Some(s) if s.as_str() == "loaded" => Some(IncrementalStateAssertion::Loaded),
        Some(s) if s.as_str() == "not-loaded" => Some(IncrementalStateAssertion::NotLoaded),
        Some(s) => {
            early_dcx.early_fatal(format!("unexpected incremental state assertion value: {s}"))
        }
        None => None,
    }
}

pub fn parse_externs(
    early_dcx: &EarlyDiagCtxt,
    matches: &getopts::Matches,
    unstable_opts: &UnstableOptions,
) -> Externs {
    let is_unstable_enabled = unstable_opts.unstable_options;
    let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
    for arg in matches.opt_strs("extern") {
        let ExternOpt { crate_name: name, path, options } =
            split_extern_opt(early_dcx, unstable_opts, &arg).unwrap_or_else(|e| e.emit());

        let entry = externs.entry(name.to_owned());

        use std::collections::btree_map::Entry;

        let entry = if let Some(path) = path {
            // --extern prelude_name=some_file.rlib
            let path = CanonicalizedPath::new(path);
            match entry {
                Entry::Vacant(vacant) => {
                    let files = BTreeSet::from_iter(iter::once(path));
                    vacant.insert(ExternEntry::new(ExternLocation::ExactPaths(files)))
                }
                Entry::Occupied(occupied) => {
                    let ext_ent = occupied.into_mut();
                    match ext_ent {
                        ExternEntry { location: ExternLocation::ExactPaths(files), .. } => {
                            files.insert(path);
                        }
                        ExternEntry {
                            location: location @ ExternLocation::FoundInLibrarySearchDirectories,
                            ..
                        } => {
                            // Exact paths take precedence over search directories.
                            let files = BTreeSet::from_iter(iter::once(path));
                            *location = ExternLocation::ExactPaths(files);
                        }
                    }
                    ext_ent
                }
            }
        } else {
            // --extern prelude_name
            match entry {
                Entry::Vacant(vacant) => {
                    vacant.insert(ExternEntry::new(ExternLocation::FoundInLibrarySearchDirectories))
                }
                Entry::Occupied(occupied) => {
                    // Ignore if already specified.
                    occupied.into_mut()
                }
            }
        };

        let mut is_private_dep = false;
        let mut add_prelude = true;
        let mut nounused_dep = false;
        let mut force = false;
        if let Some(opts) = options {
            if !is_unstable_enabled {
                early_dcx.early_fatal(
                    "the `-Z unstable-options` flag must also be passed to \
                     enable `--extern` options",
                );
            }
            for opt in opts.split(',') {
                match opt {
                    "priv" => is_private_dep = true,
                    "noprelude" => {
                        if let ExternLocation::ExactPaths(_) = &entry.location {
                            add_prelude = false;
                        } else {
                            early_dcx.early_fatal(
                                "the `noprelude` --extern option requires a file path",
                            );
                        }
                    }
                    "nounused" => nounused_dep = true,
                    "force" => force = true,
                    _ => early_dcx.early_fatal(format!("unknown --extern option `{opt}`")),
                }
            }
        }

        // Crates start out being not private, and go to being private `priv`
        // is specified.
        entry.is_private_dep |= is_private_dep;
        // likewise `nounused`
        entry.nounused_dep |= nounused_dep;
        // and `force`
        entry.force |= force;
        // If any flag is missing `noprelude`, then add to the prelude.
        entry.add_prelude |= add_prelude;
    }
    Externs(externs)
}

fn parse_remap_path_prefix(
    early_dcx: &EarlyDiagCtxt,
    matches: &getopts::Matches,
    unstable_opts: &UnstableOptions,
) -> Vec<(PathBuf, PathBuf)> {
    let mut mapping: Vec<(PathBuf, PathBuf)> = matches
        .opt_strs("remap-path-prefix")
        .into_iter()
        .map(|remap| match remap.rsplit_once('=') {
            None => {
                early_dcx.early_fatal("--remap-path-prefix must contain '=' between FROM and TO")
            }
            Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)),
        })
        .collect();
    match &unstable_opts.remap_cwd_prefix {
        Some(to) => match std::env::current_dir() {
            Ok(cwd) => mapping.push((cwd, to.clone())),
            Err(_) => (),
        },
        None => (),
    };
    mapping
}

fn parse_logical_env(
    early_dcx: &EarlyDiagCtxt,
    matches: &getopts::Matches,
) -> FxIndexMap<String, String> {
    let mut vars = FxIndexMap::default();

    for arg in matches.opt_strs("env-set") {
        if let Some((name, val)) = arg.split_once('=') {
            vars.insert(name.to_string(), val.to_string());
        } else {
            early_dcx.early_fatal(format!("`--env-set`: specify value for variable `{arg}`"));
        }
    }

    vars
}

// JUSTIFICATION: before wrapper fn is available
#[allow(rustc::bad_opt_access)]
pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::Matches) -> Options {
    let color = parse_color(early_dcx, matches);

    let edition = parse_crate_edition(early_dcx, matches);

    let crate_name = matches.opt_str("crate-name");
    let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
    let JsonConfig {
        json_rendered,
        json_color,
        json_artifact_notifications,
        json_timings,
        json_unused_externs,
        json_future_incompat,
    } = parse_json(early_dcx, matches);

    let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered);

    early_dcx.set_error_format(error_format);

    let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
        early_dcx.early_fatal("`--diagnostic-width` must be an positive integer");
    });

    let unparsed_crate_types = matches.opt_strs("crate-type");
    let crate_types = parse_crate_types_from_list(unparsed_crate_types)
        .unwrap_or_else(|e| early_dcx.early_fatal(e));

    let mut target_modifiers = BTreeMap::<OptionsTargetModifiers, String>::new();

    let mut unstable_opts = UnstableOptions::build(early_dcx, matches, &mut target_modifiers);
    let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches);

    if !unstable_opts.unstable_options && json_timings {
        early_dcx.early_fatal("--json=timings is unstable and requires using `-Zunstable-options`");
    }

    check_error_format_stability(
        early_dcx,
        &unstable_opts,
        unstable_features.is_nightly_build(),
        error_format,
    );

    let output_types = parse_output_types(early_dcx, &unstable_opts, matches);

    let mut cg = CodegenOptions::build(early_dcx, matches, &mut target_modifiers);
    let (disable_local_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto(
        early_dcx,
        &output_types,
        matches,
        cg.codegen_units,
    );

    if unstable_opts.threads == 0 {
        early_dcx.early_fatal("value for threads must be a positive non-zero integer");
    }

    if unstable_opts.threads == parse::MAX_THREADS_CAP {
        early_dcx.early_warn(format!("number of threads was capped at {}", parse::MAX_THREADS_CAP));
    }

    let incremental = cg.incremental.as_ref().map(PathBuf::from);

    let assert_incr_state = parse_assert_incr_state(early_dcx, &unstable_opts.assert_incr_state);

    if cg.profile_generate.enabled() && cg.profile_use.is_some() {
        early_dcx.early_fatal("options `-C profile-generate` and `-C profile-use` are exclusive");
    }

    if unstable_opts.profile_sample_use.is_some()
        && (cg.profile_generate.enabled() || cg.profile_use.is_some())
    {
        early_dcx.early_fatal(
            "option `-Z profile-sample-use` cannot be used with `-C profile-generate` or `-C profile-use`",
        );
    }

    // Check for unstable values of `-C symbol-mangling-version`.
    // This is what prevents them from being used on stable compilers.
    match cg.symbol_mangling_version {
        // Stable values:
        None | Some(SymbolManglingVersion::V0) => {}

        // Unstable values:
        Some(SymbolManglingVersion::Legacy) => {
            if !unstable_opts.unstable_options {
                early_dcx.early_fatal(
                    "`-C symbol-mangling-version=legacy` requires `-Z unstable-options`",
                );
            }
        }
        Some(SymbolManglingVersion::Hashed) => {
            if !unstable_opts.unstable_options {
                early_dcx.early_fatal(
                    "`-C symbol-mangling-version=hashed` requires `-Z unstable-options`",
                );
            }
        }
    }

    if cg.instrument_coverage != InstrumentCoverage::No {
        if cg.profile_generate.enabled() || cg.profile_use.is_some() {
            early_dcx.early_fatal(
                "option `-C instrument-coverage` is not compatible with either `-C profile-use` \
                or `-C profile-generate`",
            );
        }

        // `-C instrument-coverage` implies `-C symbol-mangling-version=v0` - to ensure consistent
        // and reversible name mangling. Note, LLVM coverage tools can analyze coverage over
        // multiple runs, including some changes to source code; so mangled names must be consistent
        // across compilations.
        match cg.symbol_mangling_version {
            None => cg.symbol_mangling_version = Some(SymbolManglingVersion::V0),
            Some(SymbolManglingVersion::Legacy) => {
                early_dcx.early_warn(
                    "-C instrument-coverage requires symbol mangling version `v0`, \
                    but `-C symbol-mangling-version=legacy` was specified",
                );
            }
            Some(SymbolManglingVersion::V0) => {}
            Some(SymbolManglingVersion::Hashed) => {
                early_dcx.early_warn(
                    "-C instrument-coverage requires symbol mangling version `v0`, \
                    but `-C symbol-mangling-version=hashed` was specified",
                );
            }
        }
    }

    if let Ok(graphviz_font) = std::env::var("RUSTC_GRAPHVIZ_FONT") {
        // FIXME: this is only mutation of UnstableOptions here, move into
        // UnstableOptions::build?
        unstable_opts.graphviz_font = graphviz_font;
    }

    if !cg.embed_bitcode {
        match cg.lto {
            LtoCli::No | LtoCli::Unspecified => {}
            LtoCli::Yes | LtoCli::NoParam | LtoCli::Thin | LtoCli::Fat => {
                early_dcx.early_fatal("options `-C embed-bitcode=no` and `-C lto` are incompatible")
            }
        }
    }

    let unstable_options_enabled = nightly_options::is_unstable_enabled(matches);
    if !unstable_options_enabled && cg.force_frame_pointers == FramePointer::NonLeaf {
        early_dcx.early_fatal(
            "`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \
                and a nightly compiler",
        )
    }

    if !nightly_options::is_unstable_enabled(matches) && !unstable_opts.offload.is_empty() {
        early_dcx.early_fatal(
            "`-Zoffload=Enable` also requires `-Zunstable-options` \
                and a nightly compiler",
        )
    }

    let target_triple = parse_target_triple(early_dcx, matches);

    // Ensure `-Z unstable-options` is required when using the unstable `-C link-self-contained` and
    // `-C linker-flavor` options.
    if !unstable_options_enabled {
        if let Err(error) = cg.link_self_contained.check_unstable_variants(&target_triple) {
            early_dcx.early_fatal(error);
        }

        if let Some(flavor) = cg.linker_flavor {
            if flavor.is_unstable() {
                early_dcx.early_fatal(format!(
                    "the linker flavor `{}` is unstable, the `-Z unstable-options` \
                        flag must also be passed to use the unstable values",
                    flavor.desc()
                ));
            }
        }
    }

    // Check `-C link-self-contained` for consistency: individual components cannot be both enabled
    // and disabled at the same time.
    if let Some(erroneous_components) = cg.link_self_contained.check_consistency() {
        let names: String = erroneous_components
            .into_iter()
            .map(|c| c.as_str().unwrap())
            .intersperse(", ")
            .collect();
        early_dcx.early_fatal(format!(
            "some `-C link-self-contained` components were both enabled and disabled: {names}"
        ));
    }

    let prints = print_request::collect_print_requests(early_dcx, &mut cg, &unstable_opts, matches);

    // -Zretpoline-external-thunk also requires -Zretpoline
    if unstable_opts.retpoline_external_thunk {
        unstable_opts.retpoline = true;
        target_modifiers.insert(
            OptionsTargetModifiers::UnstableOptions(UnstableOptionsTargetModifiers::retpoline),
            "true".to_string(),
        );
    }

    let cg = cg;

    let opt_level = parse_opt_level(early_dcx, matches, &cg);
    // The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
    // to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
    // for more details.
    let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
    let debuginfo = select_debuginfo(matches, &cg);

    if !unstable_options_enabled {
        if let Err(error) = cg.linker_features.check_unstable_variants(&target_triple) {
            early_dcx.early_fatal(error);
        }
    }

    if !unstable_options_enabled && cg.panic == Some(PanicStrategy::ImmediateAbort) {
        early_dcx.early_fatal(
            "`-Cpanic=immediate-abort` requires `-Zunstable-options` and a nightly compiler",
        )
    }

    // Parse any `-l` flags, which link to native libraries.
    let libs = parse_native_libs(early_dcx, &unstable_opts, unstable_features, matches);

    let test = matches.opt_present("test");

    if !cg.remark.is_empty() && debuginfo == DebugInfo::None {
        early_dcx.early_warn("-C remark requires \"-C debuginfo=n\" to show source locations");
    }

    if cg.remark.is_empty() && unstable_opts.remark_dir.is_some() {
        early_dcx
            .early_warn("using -Z remark-dir without enabling remarks using e.g. -C remark=all");
    }

    let externs = parse_externs(early_dcx, matches, &unstable_opts);

    let remap_path_prefix = parse_remap_path_prefix(early_dcx, matches, &unstable_opts);
    let remap_path_scope = parse_remap_path_scope(early_dcx, matches, &unstable_opts);

    let pretty = parse_pretty(early_dcx, &unstable_opts);

    // query-dep-graph is required if dump-dep-graph is given #106736
    if unstable_opts.dump_dep_graph && !unstable_opts.query_dep_graph {
        early_dcx.early_fatal("can't dump dependency graph without `-Z query-dep-graph`");
    }

    let logical_env = parse_logical_env(early_dcx, matches);

    let sysroot = Sysroot::new(matches.opt_str("sysroot").map(PathBuf::from));

    let real_source_base_dir = |suffix: &str, confirm: &str| {
        let mut candidate = sysroot.path().join(suffix);
        if let Ok(metadata) = candidate.symlink_metadata() {
            // Replace the symlink bootstrap creates, with its destination.
            // We could try to use `fs::canonicalize` instead, but that might
            // produce unnecessarily verbose path.
            if metadata.file_type().is_symlink() {
                if let Ok(symlink_dest) = std::fs::read_link(&candidate) {
                    candidate = symlink_dest;
                }
            }
        }

        // Only use this directory if it has a file we can expect to always find.
        candidate.join(confirm).is_file().then_some(candidate)
    };

    let real_rust_source_base_dir =
        // This is the location used by the `rust-src` `rustup` component.
        real_source_base_dir("lib/rustlib/src/rust", "library/std/src/lib.rs");

    let real_rustc_dev_source_base_dir =
        // This is the location used by the `rustc-dev` `rustup` component.
        real_source_base_dir("lib/rustlib/rustc-src/rust", "compiler/rustc/src/main.rs");

    // We eagerly scan all files in each passed -L path. If the same directory is passed multiple
    // times, and the directory contains a lot of files, this can take a lot of time.
    // So we remove -L paths that were passed multiple times, and keep only the first occurrence.
    // We still have to keep the original order of the -L arguments.
    let search_paths: Vec<SearchPath> = {
        let mut seen_search_paths = FxHashSet::default();
        let search_path_matches: Vec<String> = matches.opt_strs("L");
        search_path_matches
            .iter()
            .filter(|p| seen_search_paths.insert(*p))
            .map(|path| {
                SearchPath::from_cli_opt(
                    sysroot.path(),
                    &target_triple,
                    early_dcx,
                    &path,
                    unstable_opts.unstable_options,
                )
            })
            .collect()
    };

    // Ideally we would use `SourceMap::working_dir` instead, but we don't have access to it
    // so we manually create the potentially-remapped working directory
    let working_dir = {
        let working_dir = std::env::current_dir().unwrap_or_else(|e| {
            early_dcx.early_fatal(format!("Current directory is invalid: {e}"));
        });

        let file_mapping = file_path_mapping(remap_path_prefix.clone(), remap_path_scope);
        file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
    };

    let verbose = matches.opt_present("verbose") || unstable_opts.verbose_internals;

    Options {
        assert_incr_state,
        crate_types,
        optimize: opt_level,
        debuginfo,
        lint_opts,
        lint_cap,
        describe_lints,
        output_types,
        search_paths,
        sysroot,
        target_triple,
        test,
        incremental,
        untracked_state_hash: Default::default(),
        unstable_opts,
        prints,
        cg,
        error_format,
        diagnostic_width,
        externs,
        unstable_features,
        crate_name,
        libs,
        debug_assertions,
        actually_rustdoc: false,
        resolve_doc_links: ResolveDocLinks::ExportedMetadata,
        trimmed_def_paths: false,
        cli_forced_codegen_units: codegen_units,
        cli_forced_local_thinlto_off: disable_local_thinlto,
        remap_path_prefix,
        remap_path_scope,
        real_rust_source_base_dir,
        real_rustc_dev_source_base_dir,
        edition,
        json_artifact_notifications,
        json_timings,
        json_unused_externs,
        json_future_incompat,
        pretty,
        working_dir,
        color,
        logical_env,
        verbose,
        target_modifiers,
    }
}

fn parse_pretty(early_dcx: &EarlyDiagCtxt, unstable_opts: &UnstableOptions) -> Option<PpMode> {
    use PpMode::*;

    let first = match unstable_opts.unpretty.as_deref()? {
        "normal" => Source(PpSourceMode::Normal),
        "identified" => Source(PpSourceMode::Identified),
        "expanded" => Source(PpSourceMode::Expanded),
        "expanded,identified" => Source(PpSourceMode::ExpandedIdentified),
        "expanded,hygiene" => Source(PpSourceMode::ExpandedHygiene),
        "ast-tree" => AstTree,
        "ast-tree,expanded" => AstTreeExpanded,
        "hir" => Hir(PpHirMode::Normal),
        "hir,identified" => Hir(PpHirMode::Identified),
        "hir,typed" => Hir(PpHirMode::Typed),
        "hir-tree" => HirTree,
        "thir-tree" => ThirTree,
        "thir-flat" => ThirFlat,
        "mir" => Mir,
        "stable-mir" => StableMir,
        "mir-cfg" => MirCFG,
        name => early_dcx.early_fatal(format!(
            "argument to `unpretty` must be one of `normal`, `identified`, \
                            `expanded`, `expanded,identified`, `expanded,hygiene`, \
                            `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
                            `hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir`, `stable-mir`, or \
                            `mir-cfg`; got {name}"
        )),
    };
    debug!("got unpretty option: {first:?}");
    Some(first)
}

pub fn make_crate_type_option() -> RustcOptGroup {
    make_opt(
        OptionStability::Stable,
        OptionKind::Multi,
        "",
        "crate-type",
        "Comma separated list of types of crates
                                for the compiler to emit",
        "<bin|lib|rlib|dylib|cdylib|staticlib|proc-macro>",
    )
}

pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> {
    let mut crate_types: Vec<CrateType> = Vec::new();
    for unparsed_crate_type in &list_list {
        for part in unparsed_crate_type.split(',') {
            let new_part = match part {
                "lib" => CrateType::default(),
                "rlib" => CrateType::Rlib,
                "staticlib" => CrateType::StaticLib,
                "dylib" => CrateType::Dylib,
                "cdylib" => CrateType::Cdylib,
                "bin" => CrateType::Executable,
                "proc-macro" => CrateType::ProcMacro,
                "sdylib" => CrateType::Sdylib,
                _ => {
                    return Err(format!(
                        "unknown crate type: `{part}`, expected one of: \
                        `lib`, `rlib`, `staticlib`, `dylib`, `cdylib`, `bin`, `proc-macro`",
                    ));
                }
            };
            if !crate_types.contains(&new_part) {
                crate_types.push(new_part)
            }
        }
    }

    Ok(crate_types)
}

pub mod nightly_options {
    use rustc_feature::UnstableFeatures;

    use super::{OptionStability, RustcOptGroup};
    use crate::EarlyDiagCtxt;

    pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
        match_is_nightly_build(matches)
            && matches.opt_strs("Z").iter().any(|x| *x == "unstable-options")
    }

    pub fn match_is_nightly_build(matches: &getopts::Matches) -> bool {
        is_nightly_build(matches.opt_str("crate-name").as_deref())
    }

    fn is_nightly_build(krate: Option<&str>) -> bool {
        UnstableFeatures::from_environment(krate).is_nightly_build()
    }

    pub fn check_nightly_options(
        early_dcx: &EarlyDiagCtxt,
        matches: &getopts::Matches,
        flags: &[RustcOptGroup],
    ) {
        let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options");
        let really_allows_unstable_options = match_is_nightly_build(matches);
        let mut nightly_options_on_stable = 0;

        for opt in flags.iter() {
            if opt.stability == OptionStability::Stable {
                continue;
            }
            if !matches.opt_present(opt.name) {
                continue;
            }
            if opt.name != "Z" && !has_z_unstable_option {
                early_dcx.early_fatal(format!(
                    "the `-Z unstable-options` flag must also be passed to enable \
                         the flag `{}`",
                    opt.name
                ));
            }
            if really_allows_unstable_options {
                continue;
            }
            match opt.stability {
                OptionStability::Unstable => {
                    nightly_options_on_stable += 1;
                    let msg = format!(
                        "the option `{}` is only accepted on the nightly compiler",
                        opt.name
                    );
                    // The non-zero nightly_options_on_stable will force an early_fatal eventually.
                    let _ = early_dcx.early_err(msg);
                }
                OptionStability::Stable => {}
            }
        }
        if nightly_options_on_stable > 0 {
            early_dcx
                .early_help("consider switching to a nightly toolchain: `rustup default nightly`");
            early_dcx.early_note("selecting a toolchain with `+toolchain` arguments require a rustup proxy; see <https://rust-lang.github.io/rustup/concepts/index.html>");
            early_dcx.early_note("for more information about Rust's stability policy, see <https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#unstable-features>");
            early_dcx.early_fatal(format!(
                "{} nightly option{} were parsed",
                nightly_options_on_stable,
                if nightly_options_on_stable > 1 { "s" } else { "" }
            ));
        }
    }
}

#[derive(Copy, Clone, PartialEq, Debug)]
pub enum PpSourceMode {
    /// `-Zunpretty=normal`
    Normal,
    /// `-Zunpretty=expanded`
    Expanded,
    /// `-Zunpretty=identified`
    Identified,
    /// `-Zunpretty=expanded,identified`
    ExpandedIdentified,
    /// `-Zunpretty=expanded,hygiene`
    ExpandedHygiene,
}

#[derive(Copy, Clone, PartialEq, Debug)]
pub enum PpHirMode {
    /// `-Zunpretty=hir`
    Normal,
    /// `-Zunpretty=hir,identified`
    Identified,
    /// `-Zunpretty=hir,typed`
    Typed,
}

#[derive(Copy, Clone, PartialEq, Debug)]
/// Pretty print mode
pub enum PpMode {
    /// Options that print the source code, i.e.
    /// `-Zunpretty=normal` and `-Zunpretty=expanded`
    Source(PpSourceMode),
    /// `-Zunpretty=ast-tree`
    AstTree,
    /// `-Zunpretty=ast-tree,expanded`
    AstTreeExpanded,
    /// Options that print the HIR, i.e. `-Zunpretty=hir`
    Hir(PpHirMode),
    /// `-Zunpretty=hir-tree`
    HirTree,
    /// `-Zunpretty=thir-tree`
    ThirTree,
    /// `-Zunpretty=thir-flat`
    ThirFlat,
    /// `-Zunpretty=mir`
    Mir,
    /// `-Zunpretty=mir-cfg`
    MirCFG,
    /// `-Zunpretty=stable-mir`
    StableMir,
}

impl PpMode {
    pub fn needs_ast_map(&self) -> bool {
        use PpMode::*;
        use PpSourceMode::*;
        match *self {
            Source(Normal | Identified) | AstTree => false,

            Source(Expanded | ExpandedIdentified | ExpandedHygiene)
            | AstTreeExpanded
            | Hir(_)
            | HirTree
            | ThirTree
            | ThirFlat
            | Mir
            | MirCFG
            | StableMir => true,
        }
    }

    pub fn needs_analysis(&self) -> bool {
        use PpMode::*;
        matches!(*self, Hir(PpHirMode::Typed) | Mir | StableMir | MirCFG | ThirTree | ThirFlat)
    }
}

#[derive(Clone, Hash, PartialEq, Eq, Debug)]
pub enum WasiExecModel {
    Command,
    Reactor,
}

/// Command-line arguments passed to the compiler have to be incorporated with
/// the dependency tracking system for incremental compilation. This module
/// provides some utilities to make this more convenient.
///
/// The values of all command-line arguments that are relevant for dependency
/// tracking are hashed into a single value that determines whether the
/// incremental compilation cache can be re-used or not. This hashing is done
/// via the `DepTrackingHash` trait defined below, since the standard `Hash`
/// implementation might not be suitable (e.g., arguments are stored in a `Vec`,
/// the hash of which is order dependent, but we might not want the order of
/// arguments to make a difference for the hash).
///
/// However, since the value provided by `Hash::hash` often *is* suitable,
/// especially for primitive types, there is the
/// `impl_dep_tracking_hash_via_hash!()` macro that allows to simply reuse the
/// `Hash` implementation for `DepTrackingHash`. It's important though that
/// we have an opt-in scheme here, so one is hopefully forced to think about
/// how the hash should be calculated when adding a new command-line argument.
pub(crate) mod dep_tracking {
    use std::collections::BTreeMap;
    use std::hash::Hash;
    use std::num::NonZero;
    use std::path::PathBuf;

    use rustc_abi::Align;
    use rustc_data_structures::fx::FxIndexMap;
    use rustc_data_structures::stable_hasher::StableHasher;
    use rustc_errors::LanguageIdentifier;
    use rustc_feature::UnstableFeatures;
    use rustc_hashes::Hash64;
    use rustc_hir::attrs::CollapseMacroDebuginfo;
    use rustc_span::edition::Edition;
    use rustc_span::{RealFileName, RemapPathScopeComponents};
    use rustc_target::spec::{
        CodeModel, FramePointer, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel,
        RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility, TargetTuple,
        TlsModel,
    };

    use super::{
        AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CoverageOptions,
        CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn,
        InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
        LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, OutFileName, OutputType,
        OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks, SourceFileHashAlgorithm,
        SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
    };
    use crate::lint;
    use crate::utils::NativeLib;

    pub(crate) trait DepTrackingHash {
        fn hash(
            &self,
            hasher: &mut StableHasher,
            error_format: ErrorOutputType,
            for_crate_hash: bool,
        );
    }

    macro_rules! impl_dep_tracking_hash_via_hash {
        ($($t:ty),+ $(,)?) => {$(
            impl DepTrackingHash for $t {
                fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType, _for_crate_hash: bool) {
                    Hash::hash(self, hasher);
                }
            }
        )+};
    }

    impl<T: DepTrackingHash> DepTrackingHash for Option<T> {
        fn hash(
            &self,
            hasher: &mut StableHasher,
            error_format: ErrorOutputType,
            for_crate_hash: bool,
        ) {
            match self {
                Some(x) => {
                    Hash::hash(&1, hasher);
                    DepTrackingHash::hash(x, hasher, error_format, for_crate_hash);
                }
                None => Hash::hash(&0, hasher),
            }
        }
    }

    impl_dep_tracking_hash_via_hash!(
        (),
        AnnotateMoves,
        AutoDiff,
        Offload,
        bool,
        usize,
        NonZero<usize>,
        u64,
        Hash64,
        String,
        PathBuf,
        lint::Level,
        WasiExecModel,
        u32,
        FramePointer,
        RelocModel,
        CodeModel,
        TlsModel,
        InstrumentCoverage,
        CoverageOptions,
        InstrumentXRay,
        CrateType,
        MergeFunctions,
        OnBrokenPipe,
        PanicStrategy,
        RelroLevel,
        OptLevel,
        LtoCli,
        DebugInfo,
        DebugInfoCompression,
        MirStripDebugInfo,
        CollapseMacroDebuginfo,
        UnstableFeatures,
        NativeLib,
        SanitizerSet,
        CFGuard,
        CFProtection,
        TargetTuple,
        Edition,
        LinkerPluginLto,
        ResolveDocLinks,
        SplitDebuginfo,
        SplitDwarfKind,
        StackProtector,
        SwitchWithOptPath,
        SymbolManglingVersion,
        SymbolVisibility,
        RemapPathScopeComponents,
        SourceFileHashAlgorithm,
        OutFileName,
        OutputType,
        RealFileName,
        LocationDetail,
        FmtDebug,
        BranchProtection,
        LanguageIdentifier,
        NextSolverConfig,
        PatchableFunctionEntry,
        Polonius,
        InliningThreshold,
        FunctionReturn,
        Align,
    );

    impl<T1, T2> DepTrackingHash for (T1, T2)
    where
        T1: DepTrackingHash,
        T2: DepTrackingHash,
    {
        fn hash(
            &self,
            hasher: &mut StableHasher,
            error_format: ErrorOutputType,
            for_crate_hash: bool,
        ) {
            Hash::hash(&0, hasher);
            DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash);
            Hash::hash(&1, hasher);
            DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash);
        }
    }

    impl<T1, T2, T3> DepTrackingHash for (T1, T2, T3)
    where
        T1: DepTrackingHash,
        T2: DepTrackingHash,
        T3: DepTrackingHash,
    {
        fn hash(
            &self,
            hasher: &mut StableHasher,
            error_format: ErrorOutputType,
            for_crate_hash: bool,
        ) {
            Hash::hash(&0, hasher);
            DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash);
            Hash::hash(&1, hasher);
            DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash);
            Hash::hash(&2, hasher);
            DepTrackingHash::hash(&self.2, hasher, error_format, for_crate_hash);
        }
    }

    impl<T: DepTrackingHash> DepTrackingHash for Vec<T> {
        fn hash(
            &self,
            hasher: &mut StableHasher,
            error_format: ErrorOutputType,
            for_crate_hash: bool,
        ) {
            Hash::hash(&self.len(), hasher);
            for (index, elem) in self.iter().enumerate() {
                Hash::hash(&index, hasher);
                DepTrackingHash::hash(elem, hasher, error_format, for_crate_hash);
            }
        }
    }

    impl<T: DepTrackingHash, V: DepTrackingHash> DepTrackingHash for FxIndexMap<T, V> {
        fn hash(
            &self,
            hasher: &mut StableHasher,
            error_format: ErrorOutputType,
            for_crate_hash: bool,
        ) {
            Hash::hash(&self.len(), hasher);
            for (key, value) in self.iter() {
                DepTrackingHash::hash(key, hasher, error_format, for_crate_hash);
                DepTrackingHash::hash(value, hasher, error_format, for_crate_hash);
            }
        }
    }

    impl DepTrackingHash for OutputTypes {
        fn hash(
            &self,
            hasher: &mut StableHasher,
            error_format: ErrorOutputType,
            for_crate_hash: bool,
        ) {
            Hash::hash(&self.0.len(), hasher);
            for (key, val) in &self.0 {
                DepTrackingHash::hash(key, hasher, error_format, for_crate_hash);
                if !for_crate_hash {
                    DepTrackingHash::hash(val, hasher, error_format, for_crate_hash);
                }
            }
        }
    }

    // This is a stable hash because BTreeMap is a sorted container
    pub(crate) fn stable_hash(
        sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>,
        hasher: &mut StableHasher,
        error_format: ErrorOutputType,
        for_crate_hash: bool,
    ) {
        for (key, sub_hash) in sub_hashes {
            // Using Hash::hash() instead of DepTrackingHash::hash() is fine for
            // the keys, as they are just plain strings
            Hash::hash(&key.len(), hasher);
            Hash::hash(key, hasher);
            sub_hash.hash(hasher, error_format, for_crate_hash);
        }
    }
}

/// How to run proc-macro code when building this crate
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum ProcMacroExecutionStrategy {
    /// Run the proc-macro code on the same thread as the server.
    SameThread,

    /// Run the proc-macro code on a different thread.
    CrossThread,
}

/// Which format to use for `-Z dump-mono-stats`
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum DumpMonoStatsFormat {
    /// Pretty-print a markdown table
    Markdown,
    /// Emit structured JSON
    Json,
}

impl DumpMonoStatsFormat {
    pub fn extension(self) -> &'static str {
        match self {
            Self::Markdown => "md",
            Self::Json => "json",
        }
    }
}

/// `-Z patchable-function-entry` representation - how many nops to put before and after function
/// entry.
#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
pub struct PatchableFunctionEntry {
    /// Nops before the entry
    prefix: u8,
    /// Nops after the entry
    entry: u8,
}

impl PatchableFunctionEntry {
    pub fn from_total_and_prefix_nops(
        total_nops: u8,
        prefix_nops: u8,
    ) -> Option<PatchableFunctionEntry> {
        if total_nops < prefix_nops {
            None
        } else {
            Some(Self { prefix: prefix_nops, entry: total_nops - prefix_nops })
        }
    }
    pub fn prefix(&self) -> u8 {
        self.prefix
    }
    pub fn entry(&self) -> u8 {
        self.entry
    }
}

/// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy,
/// or future prototype.
#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
pub enum Polonius {
    /// The default value: disabled.
    #[default]
    Off,

    /// Legacy version, using datalog and the `polonius-engine` crate. Historical value for `-Zpolonius`.
    Legacy,

    /// In-tree prototype, extending the NLL infrastructure.
    Next,
}

impl Polonius {
    /// Returns whether the legacy version of polonius is enabled
    pub fn is_legacy_enabled(&self) -> bool {
        matches!(self, Polonius::Legacy)
    }

    /// Returns whether the "next" version of polonius is enabled
    pub fn is_next_enabled(&self) -> bool {
        matches!(self, Polonius::Next)
    }
}

#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum InliningThreshold {
    Always,
    Sometimes(usize),
    Never,
}

impl Default for InliningThreshold {
    fn default() -> Self {
        Self::Sometimes(100)
    }
}

/// The different settings that the `-Zfunction-return` flag can have.
#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
pub enum FunctionReturn {
    /// Keep the function return unmodified.
    #[default]
    Keep,

    /// Replace returns with jumps to thunk, without emitting the thunk.
    ThunkExtern,
}

/// Whether extra span comments are included when dumping MIR, via the `-Z mir-include-spans` flag.
/// By default, only enabled in the NLL MIR dumps, and disabled in all other passes.
#[derive(Clone, Copy, Default, PartialEq, Debug)]
pub enum MirIncludeSpans {
    Off,
    On,
    /// Default: include extra comments in NLL MIR dumps only. Can be ignored and considered as
    /// `Off` in all other cases.
    #[default]
    Nll,
}

impl MirIncludeSpans {
    /// Unless opting into extra comments for all passes, they can be considered disabled.
    /// The cases where a distinction between on/off and a per-pass value can exist will be handled
    /// in the passes themselves: i.e. the `Nll` value is considered off for all intents and
    /// purposes, except for the NLL MIR dump pass.
    pub fn is_enabled(self) -> bool {
        self == MirIncludeSpans::On
    }
}
