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

pub use crate::options::*;

use crate::search_paths::SearchPath;
use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
use crate::{early_error, early_warn, Session};
use crate::{lint, HashStableContext};

use rustc_data_structures::fx::{FxHashMap, FxHashSet};

use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
use rustc_target::abi::Align;
use rustc_target::spec::{PanicStrategy, SanitizerSet, SplitDebuginfo};
use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS};

use crate::parse::{CrateCheckConfig, CrateConfig};
use rustc_feature::UnstableFeatures;
use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION};
use rustc_span::source_map::{FileName, FilePathMapping};
use rustc_span::symbol::{sym, Symbol};
use rustc_span::RealFileName;
use rustc_span::SourceFileHashAlgorithm;

use rustc_errors::emitter::HumanReadableErrorType;
use rustc_errors::{ColorConfig, DiagnosticArgValue, HandlerFlags, IntoDiagnosticArg};

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

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)]
pub enum OptLevel {
    No,         // -O0
    Less,       // -O1
    Default,    // -O2
    Aggressive, // -O3
    Size,       // -Os
    SizeMin,    // -Oz
}

/// 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)]
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 `-Z dump_mir_spanview` flag can have. `Statement` generates a
/// document highlighting each span of every statement (including terminators). `Terminator` and
/// `Block` highlight a single span per `BasicBlock`: the span of the block's `Terminator`, or a
/// computed span for the block, representing the entire range, covering the block's terminator and
/// all of its statements.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum MirSpanview {
    /// Default `-Z dump_mir_spanview` or `-Z dump_mir_spanview=statement`
    Statement,
    /// `-Z dump_mir_spanview=terminator`
    Terminator,
    /// `-Z dump_mir_spanview=block`
    Block,
}

/// The different settings that the `-C instrument-coverage` flag can have.
///
/// Coverage instrumentation now supports combining `-C instrument-coverage`
/// with compiler and linker optimization (enabled with `-O` or `-C opt-level=1`
/// and higher). Nevertheless, there are many variables, depending on options
/// selected, code structure, and enabled attributes. If errors are encountered,
/// either while compiling or when generating `llvm-cov show` reports, consider
/// lowering the optimization level, including or excluding `-C link-dead-code`,
/// or using `-Zunstable-options -C instrument-coverage=except-unused-functions`
/// or `-Zunstable-options -C instrument-coverage=except-unused-generics`.
///
/// Note that `ExceptUnusedFunctions` means: When `mapgen.rs` generates the
/// coverage map, it will not attempt to generate synthetic functions for unused
/// (and not code-generated) functions (whether they are generic or not). As a
/// result, non-codegenned functions will not be included in the coverage map,
/// and will not appear, as covered or uncovered, in coverage reports.
///
/// `ExceptUnusedGenerics` will add synthetic functions to the coverage map,
/// unless the function has type parameters.
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum InstrumentCoverage {
    /// Default `-C instrument-coverage` or `-C instrument-coverage=statement`
    All,
    /// `-Zunstable-options -C instrument-coverage=except-unused-generics`
    ExceptUnusedGenerics,
    /// `-Zunstable-options -C instrument-coverage=except-unused-functions`
    ExceptUnusedFunctions,
    /// `-C instrument-coverage=off` (or `no`, etc.)
    Off,
}

/// 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,
}

/// 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,
}

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

/// 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 fn all() -> Self {
        Self { file: true, line: true, column: true }
    }
}

#[derive(Clone, PartialEq, Hash, Debug)]
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, Decodable)]
pub enum SymbolManglingVersion {
    Legacy,
    V0,
}

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

/// 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)]
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(()),
        })
    }
}

#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, HashStable_Generic)]
#[derive(Encodable, Decodable)]
pub enum OutputType {
    Bitcode,
    Assembly,
    LlvmAssembly,
    Mir,
    Metadata,
    Object,
    Exe,
    DepInfo,
}

// Safety: Trivial C-Style enums have a stable sort order across compilation sessions.
unsafe impl StableOrd for OutputType {}

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

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

impl OutputType {
    fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool {
        match *self {
            OutputType::Exe | OutputType::DepInfo | OutputType::Metadata => true,
            OutputType::Bitcode
            | OutputType::Assembly
            | OutputType::LlvmAssembly
            | OutputType::Mir
            | OutputType::Object => false,
        }
    }

    fn shorthand(&self) -> &'static str {
        match *self {
            OutputType::Bitcode => "llvm-bc",
            OutputType::Assembly => "asm",
            OutputType::LlvmAssembly => "llvm-ir",
            OutputType::Mir => "mir",
            OutputType::Object => "obj",
            OutputType::Metadata => "metadata",
            OutputType::Exe => "link",
            OutputType::DepInfo => "dep-info",
        }
    }

    fn from_shorthand(shorthand: &str) -> Option<Self> {
        Some(match shorthand {
            "asm" => OutputType::Assembly,
            "llvm-ir" => OutputType::LlvmAssembly,
            "mir" => OutputType::Mir,
            "llvm-bc" => OutputType::Bitcode,
            "obj" => OutputType::Object,
            "metadata" => OutputType::Metadata,
            "link" => OutputType::Exe,
            "dep-info" => OutputType::DepInfo,
            _ => return None,
        })
    }

    fn shorthands_display() -> String {
        format!(
            "`{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`",
            OutputType::Bitcode.shorthand(),
            OutputType::Assembly.shorthand(),
            OutputType::LlvmAssembly.shorthand(),
            OutputType::Mir.shorthand(),
            OutputType::Object.shorthand(),
            OutputType::Metadata.shorthand(),
            OutputType::Exe.shorthand(),
            OutputType::DepInfo.shorthand(),
        )
    }

    pub fn extension(&self) -> &'static str {
        match *self {
            OutputType::Bitcode => "bc",
            OutputType::Assembly => "s",
            OutputType::LlvmAssembly => "ll",
            OutputType::Mir => "mir",
            OutputType::Object => "o",
            OutputType::Metadata => "rmeta",
            OutputType::DepInfo => "d",
            OutputType::Exe => "",
        }
    }
}

/// The type of diagnostics output to generate.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ErrorOutputType {
    /// Output meant for the consumption of humans.
    HumanReadable(HumanReadableErrorType),
    /// 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,
    },
}

impl Default for ErrorOutputType {
    fn default() -> Self {
        Self::HumanReadable(HumanReadableErrorType::Default(ColorConfig::Auto))
    }
}

/// Parameter to control path trimming.
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum TrimmedDefPaths {
    /// `try_print_trimmed_def_path` never prints a trimmed path and never calls the expensive query
    #[default]
    Never,
    /// `try_print_trimmed_def_path` calls the expensive query, the query doesn't call `delay_good_path_bug`
    Always,
    /// `try_print_trimmed_def_path` calls the expensive query, the query calls `delay_good_path_bug`
    GoodPath,
}

#[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)]
pub struct OutputTypes(BTreeMap<OutputType, Option<PathBuf>>);

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

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

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

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

    pub fn values(&self) -> BTreeMapValuesIter<'_, OutputType, Option<PathBuf>> {
        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::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::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()
    }

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

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(Copy, Clone, PartialEq, Eq, Debug)]
pub enum PrintRequest {
    FileNames,
    Sysroot,
    TargetLibdir,
    CrateName,
    Cfg,
    CallingConventions,
    TargetList,
    TargetCPUs,
    TargetFeatures,
    RelocationModels,
    CodeModels,
    TlsModels,
    TargetSpec,
    AllTargetSpecs,
    NativeStaticLibs,
    StackProtectorStrategies,
    LinkArgs,
    SplitDebuginfo,
    DeploymentTarget,
}

#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
pub enum TraitSolver {
    /// Classic trait solver in `rustc_trait_selection::traits::select`
    Classic,
    /// Chalk trait solver
    Chalk,
    /// Experimental trait solver in `rustc_trait_selection::solve`
    Next,
}

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 {
        match *self {
            Input::File(ref ifile) => ifile.file_stem().unwrap().to_str().unwrap(),
            Input::Str { .. } => "rust_out",
        }
    }

    pub fn source_name(&self) -> FileName {
        match *self {
            Input::File(ref ifile) => ifile.clone().into(),
            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::QuoteExpansion(_) => None,
                FileName::Anon(_) => None,
                FileName::MacroExpansion(_) => None,
                FileName::ProcMacroSourceCode(_) => None,
                FileName::CfgSpec(_) => None,
                FileName::CliCrateAttr(_) => None,
                FileName::Custom(_) => None,
                FileName::DocTest(path, _) => Some(path),
                FileName::InlineAsm(_) => None,
            },
        }
    }
}

#[derive(Clone, Hash, Debug, HashStable_Generic)]
pub struct OutputFilenames {
    pub out_directory: PathBuf,
    filestem: String,
    pub single_output_file: Option<PathBuf>,
    pub temps_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";

impl OutputFilenames {
    pub fn new(
        out_directory: PathBuf,
        out_filestem: String,
        single_output_file: Option<PathBuf>,
        temps_directory: Option<PathBuf>,
        extra: String,
        outputs: OutputTypes,
    ) -> Self {
        OutputFilenames {
            out_directory,
            single_output_file,
            temps_directory,
            outputs,
            filestem: format!("{out_filestem}{extra}"),
        }
    }

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

    /// Gets the output path where a compilation artifact of the given type
    /// should be placed on disk.
    pub fn output_path(&self, flavor: OutputType) -> PathBuf {
        let extension = flavor.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(&self, flavor: OutputType, codegen_unit_name: Option<&str>) -> PathBuf {
        let extension = flavor.extension();
        self.temp_path_ext(extension, codegen_unit_name)
    }

    /// Like `temp_path`, but specifically for dwarf objects.
    pub fn temp_path_dwo(&self, codegen_unit_name: Option<&str>) -> PathBuf {
        self.temp_path_ext(DWARF_OBJECT_EXT, codegen_unit_name)
    }

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

        if let Some(codegen_unit_name) = codegen_unit_name {
            extension.push_str(codegen_unit_name);
        }

        if !ext.is_empty() {
            if !extension.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);

        self.with_directory_and_extension(temps_directory, &extension)
    }

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

    fn with_directory_and_extension(&self, directory: &PathBuf, 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: Option<&str>,
    ) -> Option<PathBuf> {
        let obj_out = self.temp_path(OutputType::Object, cgu_name);
        let dwo_out = self.temp_path_dwo(cgu_name);
        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 fn host_triple() -> &'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")
}

impl Default for Options {
    fn default() -> Options {
        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![],
            maybe_sysroot: None,
            target_triple: TargetTriple::from_triple(host_triple()),
            test: false,
            incremental: None,
            unstable_opts: Default::default(),
            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: TrimmedDefPaths::default(),
            cli_forced_codegen_units: None,
            cli_forced_local_thinlto_off: false,
            remap_path_prefix: Vec::new(),
            real_rust_source_base_dir: None,
            edition: DEFAULT_EDITION,
            json_artifact_notifications: false,
            json_unused_externs: JsonUnusedExterns::No,
            json_future_incompat: false,
            pretty: None,
            working_dir: RealFileName::LocalPath(std::env::current_dir().unwrap()),
        }
    }
}

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 {
        FilePathMapping::new(self.remap_path_prefix.clone())
    }

    /// Returns `true` if there will be an output file generated.
    pub fn will_create_output_file(&self) -> bool {
        !self.unstable_opts.parse_only && // The file is just being parsed
            !self.unstable_opts.ls // 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::Default | OptLevel::Aggressive => false,
            },
        }
    }

    pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
        self.cg.symbol_mangling_version.unwrap_or(SymbolManglingVersion::Legacy)
    }

    #[allow(rustc::bad_opt_access)]
    pub fn incremental_relative_spans(&self) -> bool {
        self.unstable_opts.incremental_relative_spans
            || (self.unstable_features.is_nightly_build() && self.incremental.is_some())
    }
}

impl UnstableOptions {
    pub fn diagnostic_handler_flags(&self, can_emit_warnings: bool) -> HandlerFlags {
        HandlerFlags {
            can_emit_warnings,
            treat_err_as_bug: self.treat_err_as_bug,
            dont_buffer_diagnostics: self.dont_buffer_diagnostics,
            report_delayed_bugs: self.report_delayed_bugs,
            macro_backtrace: self.macro_backtrace,
            deduplicate_diagnostics: self.deduplicate_diagnostics,
            track_diagnostics: self.track_diagnostics,
        }
    }
}

// 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,
    },
    Start,
}

#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, Encodable, Decodable)]
#[derive(HashStable_Generic)]
pub enum CrateType {
    Executable,
    Dylib,
    Rlib,
    Staticlib,
    Cdylib,
    ProcMacro,
}

impl CrateType {
    pub fn has_metadata(self) -> bool {
        match self {
            CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
            CrateType::Executable | CrateType::Cdylib | CrateType::Staticlib => false,
        }
    }
}

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

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

    pub 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 key: PAuthKey,
}

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

pub const fn default_lib_output() -> CrateType {
    CrateType::Rlib
}

fn default_configuration(sess: &Session) -> CrateConfig {
    // NOTE: This should be kept in sync with `CrateCheckConfig::fill_well_known` below.
    let end = &sess.target.endian;
    let arch = &sess.target.arch;
    let wordsz = sess.target.pointer_width.to_string();
    let os = &sess.target.os;
    let env = &sess.target.env;
    let abi = &sess.target.abi;
    let vendor = &sess.target.vendor;
    let min_atomic_width = sess.target.min_atomic_width();
    let max_atomic_width = sess.target.max_atomic_width();
    let atomic_cas = sess.target.atomic_cas;
    let layout = sess.target.parse_data_layout().unwrap_or_else(|err| {
        sess.emit_fatal(err);
    });

    let mut ret = CrateConfig::default();
    ret.reserve(7); // the minimum number of insertions
    // Target bindings.
    ret.insert((sym::target_os, Some(Symbol::intern(os))));
    for fam in sess.target.families.as_ref() {
        ret.insert((sym::target_family, Some(Symbol::intern(fam))));
        if fam == "windows" {
            ret.insert((sym::windows, None));
        } else if fam == "unix" {
            ret.insert((sym::unix, None));
        }
    }
    ret.insert((sym::target_arch, Some(Symbol::intern(arch))));
    ret.insert((sym::target_endian, Some(Symbol::intern(end.as_str()))));
    ret.insert((sym::target_pointer_width, Some(Symbol::intern(&wordsz))));
    ret.insert((sym::target_env, Some(Symbol::intern(env))));
    ret.insert((sym::target_abi, Some(Symbol::intern(abi))));
    ret.insert((sym::target_vendor, Some(Symbol::intern(vendor))));
    if sess.target.has_thread_local {
        ret.insert((sym::target_thread_local, None));
    }
    let mut has_atomic = false;
    for (i, align) in [
        (8, layout.i8_align.abi),
        (16, layout.i16_align.abi),
        (32, layout.i32_align.abi),
        (64, layout.i64_align.abi),
        (128, layout.i128_align.abi),
    ] {
        if i >= min_atomic_width && i <= max_atomic_width {
            has_atomic = true;
            let mut insert_atomic = |s, align: Align| {
                ret.insert((sym::target_has_atomic_load_store, Some(Symbol::intern(s))));
                if atomic_cas {
                    ret.insert((sym::target_has_atomic, Some(Symbol::intern(s))));
                }
                if align.bits() == i {
                    ret.insert((sym::target_has_atomic_equal_alignment, Some(Symbol::intern(s))));
                }
            };
            let s = i.to_string();
            insert_atomic(&s, align);
            if s == wordsz {
                insert_atomic("ptr", layout.pointer_align.abi);
            }
        }
    }
    if sess.is_nightly_build() && has_atomic {
        ret.insert((sym::target_has_atomic_load_store, None));
        if atomic_cas {
            ret.insert((sym::target_has_atomic, None));
        }
    }

    let panic_strategy = sess.panic_strategy();
    ret.insert((sym::panic, Some(panic_strategy.desc_symbol())));

    for mut s in sess.opts.unstable_opts.sanitizer {
        // KASAN should use the same attribute name as ASAN, as it's still ASAN
        // under the hood
        if s == SanitizerSet::KERNELADDRESS {
            s = SanitizerSet::ADDRESS;
        }

        let symbol = Symbol::intern(&s.to_string());
        ret.insert((sym::sanitize, Some(symbol)));
    }

    if sess.is_sanitizer_cfi_generalize_pointers_enabled() {
        ret.insert((sym::sanitizer_cfi_generalize_pointers, None));
    }

    if sess.is_sanitizer_cfi_normalize_integers_enabled() {
        ret.insert((sym::sanitizer_cfi_normalize_integers, None));
    }

    if sess.opts.debug_assertions {
        ret.insert((sym::debug_assertions, None));
    }
    if sess.overflow_checks() {
        ret.insert((sym::overflow_checks, None));
    }
    // JUSTIFICATION: before wrapper fn is available
    #[allow(rustc::bad_opt_access)]
    if sess.opts.crate_types.contains(&CrateType::ProcMacro) {
        ret.insert((sym::proc_macro, None));
    }
    ret
}

/// Converts the crate `cfg!` configuration from `String` to `Symbol`.
/// `rustc_interface::interface::Config` accepts this in the compiler configuration,
/// but the symbol interner is not yet set up then, so we must convert it later.
pub fn to_crate_config(cfg: FxHashSet<(String, Option<String>)>) -> CrateConfig {
    cfg.into_iter().map(|(a, b)| (Symbol::intern(&a), b.map(|b| Symbol::intern(&b)))).collect()
}

/// The parsed `--check-cfg` options
pub struct CheckCfg<T = String> {
    /// Is well known names activated
    pub exhaustive_names: bool,
    /// Is well known values activated
    pub exhaustive_values: bool,
    /// All the expected values for a config name
    pub expecteds: FxHashMap<T, ExpectedValues<T>>,
}

impl<T> Default for CheckCfg<T> {
    fn default() -> Self {
        CheckCfg {
            exhaustive_names: false,
            exhaustive_values: false,
            expecteds: FxHashMap::default(),
        }
    }
}

impl<T> CheckCfg<T> {
    fn map_data<O: Eq + Hash>(self, f: impl Fn(T) -> O) -> CheckCfg<O> {
        CheckCfg {
            exhaustive_names: self.exhaustive_names,
            exhaustive_values: self.exhaustive_values,
            expecteds: self
                .expecteds
                .into_iter()
                .map(|(name, values)| {
                    (
                        f(name),
                        match values {
                            ExpectedValues::Some(values) => ExpectedValues::Some(
                                values.into_iter().map(|b| b.map(|b| f(b))).collect(),
                            ),
                            ExpectedValues::Any => ExpectedValues::Any,
                        },
                    )
                })
                .collect(),
        }
    }
}

pub enum ExpectedValues<T> {
    Some(FxHashSet<Option<T>>),
    Any,
}

impl<T: Eq + Hash> ExpectedValues<T> {
    fn insert(&mut self, value: T) -> bool {
        match self {
            ExpectedValues::Some(expecteds) => expecteds.insert(Some(value)),
            ExpectedValues::Any => false,
        }
    }
}

impl<T: Eq + Hash> Extend<T> for ExpectedValues<T> {
    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
        match self {
            ExpectedValues::Some(expecteds) => expecteds.extend(iter.into_iter().map(Some)),
            ExpectedValues::Any => {}
        }
    }
}

impl<'a, T: Eq + Hash + Copy + 'a> Extend<&'a T> for ExpectedValues<T> {
    fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
        match self {
            ExpectedValues::Some(expecteds) => expecteds.extend(iter.into_iter().map(|a| Some(*a))),
            ExpectedValues::Any => {}
        }
    }
}

/// Converts the crate `--check-cfg` options from `String` to `Symbol`.
/// `rustc_interface::interface::Config` accepts this in the compiler configuration,
/// but the symbol interner is not yet set up then, so we must convert it later.
pub fn to_crate_check_config(cfg: CheckCfg) -> CrateCheckConfig {
    cfg.map_data(|s| Symbol::intern(&s))
}

impl CrateCheckConfig {
    pub fn fill_well_known(&mut self, current_target: &Target) {
        if !self.exhaustive_values && !self.exhaustive_names {
            return;
        }

        let no_values = || {
            let mut values = FxHashSet::default();
            values.insert(None);
            ExpectedValues::Some(values)
        };

        let empty_values = || {
            let values = FxHashSet::default();
            ExpectedValues::Some(values)
        };

        // NOTE: This should be kept in sync with `default_configuration`

        let panic_values = &PanicStrategy::all();

        let atomic_values = &[
            sym::ptr,
            sym::integer(8usize),
            sym::integer(16usize),
            sym::integer(32usize),
            sym::integer(64usize),
            sym::integer(128usize),
        ];

        let sanitize_values = SanitizerSet::all()
            .into_iter()
            .map(|sanitizer| Symbol::intern(sanitizer.as_str().unwrap()));

        // Unknown possible values:
        //  - `feature`
        //  - `target_feature`
        for name in [sym::feature, sym::target_feature] {
            self.expecteds.entry(name).or_insert(ExpectedValues::Any);
        }

        // No-values
        for name in [
            sym::doc,
            sym::miri,
            sym::unix,
            sym::test,
            sym::doctest,
            sym::windows,
            sym::proc_macro,
            sym::debug_assertions,
            sym::overflow_checks,
            sym::target_thread_local,
        ] {
            self.expecteds.entry(name).or_insert_with(no_values);
        }

        // Pre-defined values
        self.expecteds.entry(sym::panic).or_insert_with(empty_values).extend(panic_values);
        self.expecteds.entry(sym::sanitize).or_insert_with(empty_values).extend(sanitize_values);
        self.expecteds
            .entry(sym::target_has_atomic)
            .or_insert_with(no_values)
            .extend(atomic_values);
        self.expecteds
            .entry(sym::target_has_atomic_load_store)
            .or_insert_with(no_values)
            .extend(atomic_values);
        self.expecteds
            .entry(sym::target_has_atomic_equal_alignment)
            .or_insert_with(no_values)
            .extend(atomic_values);

        // Target specific values
        {
            const VALUES: [&Symbol; 8] = [
                &sym::target_os,
                &sym::target_family,
                &sym::target_arch,
                &sym::target_endian,
                &sym::target_env,
                &sym::target_abi,
                &sym::target_vendor,
                &sym::target_pointer_width,
            ];

            // Initialize (if not already initialized)
            for &e in VALUES {
                let entry = self.expecteds.entry(e);
                if !self.exhaustive_values {
                    entry.or_insert(ExpectedValues::Any);
                } else {
                    entry.or_insert_with(empty_values);
                }
            }

            if self.exhaustive_values {
                // Get all values map at once otherwise it would be costly.
                // (8 values * 220 targets ~= 1760 times, at the time of writing this comment).
                let [
                    values_target_os,
                    values_target_family,
                    values_target_arch,
                    values_target_endian,
                    values_target_env,
                    values_target_abi,
                    values_target_vendor,
                    values_target_pointer_width,
                ] = self
                    .expecteds
                    .get_many_mut(VALUES)
                    .expect("unable to get all the check-cfg values buckets");

                for target in TARGETS
                    .iter()
                    .map(|target| Target::expect_builtin(&TargetTriple::from_triple(target)))
                    .chain(iter::once(current_target.clone()))
                {
                    values_target_os.insert(Symbol::intern(&target.options.os));
                    values_target_family.extend(
                        target.options.families.iter().map(|family| Symbol::intern(family)),
                    );
                    values_target_arch.insert(Symbol::intern(&target.arch));
                    values_target_endian.insert(Symbol::intern(target.options.endian.as_str()));
                    values_target_env.insert(Symbol::intern(&target.options.env));
                    values_target_abi.insert(Symbol::intern(&target.options.abi));
                    values_target_vendor.insert(Symbol::intern(&target.options.vendor));
                    values_target_pointer_width.insert(sym::integer(target.pointer_width));
                }
            }
        }
    }
}

pub fn build_configuration(sess: &Session, mut user_cfg: CrateConfig) -> CrateConfig {
    // Combine the configuration requested by the session (command line) with
    // some default and generated configuration items.
    let default_cfg = default_configuration(sess);
    // If the user wants a test runner, then add the test cfg.
    if sess.is_test_crate() {
        user_cfg.insert((sym::test, None));
    }
    user_cfg.extend(default_cfg.iter().cloned());
    user_cfg
}

pub(super) fn build_target_config(
    opts: &Options,
    target_override: Option<Target>,
    sysroot: &Path,
) -> Target {
    let target_result = target_override.map_or_else(
        || Target::search(&opts.target_triple, sysroot),
        |t| Ok((t, TargetWarnings::empty())),
    );
    let (target, target_warnings) = target_result.unwrap_or_else(|e| {
        early_error(
            opts.error_format,
            format!(
                "Error loading target specification: {}. \
                 Run `rustc --print target-list` for a list of built-in targets",
                e
            ),
        )
    });
    for warning in target_warnings.warning_messages() {
        early_warn(opts.error_format, warning)
    }

    if !matches!(target.pointer_width, 16 | 32 | 64) {
        early_error(
            opts.error_format,
            format!(
                "target specification was invalid: unrecognized target-pointer-width {}",
                target.pointer_width
            ),
        )
    }

    target
}

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

pub struct RustcOptGroup {
    pub apply: Box<dyn Fn(&mut getopts::Options) -> &mut getopts::Options>,
    pub name: &'static str,
    pub stability: OptionStability,
}

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

    pub fn stable<F>(name: &'static str, f: F) -> RustcOptGroup
    where
        F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
    {
        RustcOptGroup { name, apply: Box::new(f), stability: OptionStability::Stable }
    }

    pub fn unstable<F>(name: &'static str, f: F) -> RustcOptGroup
    where
        F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
    {
        RustcOptGroup { name, apply: Box::new(f), stability: OptionStability::Unstable }
    }
}

// The `opt` local module holds wrappers around the `getopts` API that
// adds extra rustc-specific metadata to each option; such metadata
// is exposed by . The public
// functions below ending with `_u` are the functions that return
// *unstable* options, i.e., options that are only enabled when the
// user also passes the `-Z unstable-options` debugging flag.
mod opt {
    // The `fn flag*` etc below are written so that we can use them
    // in the future; do not warn about them not being used right now.
    #![allow(dead_code)]

    use super::RustcOptGroup;

    pub type R = RustcOptGroup;
    pub type S = &'static str;

    fn stable<F>(name: S, f: F) -> R
    where
        F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
    {
        RustcOptGroup::stable(name, f)
    }

    fn unstable<F>(name: S, f: F) -> R
    where
        F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
    {
        RustcOptGroup::unstable(name, f)
    }

    fn longer(a: S, b: S) -> S {
        if a.len() > b.len() { a } else { b }
    }

    pub fn opt_s(a: S, b: S, c: S, d: S) -> R {
        stable(longer(a, b), move |opts| opts.optopt(a, b, c, d))
    }
    pub fn multi_s(a: S, b: S, c: S, d: S) -> R {
        stable(longer(a, b), move |opts| opts.optmulti(a, b, c, d))
    }
    pub fn flag_s(a: S, b: S, c: S) -> R {
        stable(longer(a, b), move |opts| opts.optflag(a, b, c))
    }
    pub fn flagmulti_s(a: S, b: S, c: S) -> R {
        stable(longer(a, b), move |opts| opts.optflagmulti(a, b, c))
    }

    pub fn opt(a: S, b: S, c: S, d: S) -> R {
        unstable(longer(a, b), move |opts| opts.optopt(a, b, c, d))
    }
    pub fn multi(a: S, b: S, c: S, d: S) -> R {
        unstable(longer(a, b), move |opts| opts.optmulti(a, b, c, d))
    }
}
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}."
    )
});
/// Returns the "short" subset of the rustc command line options,
/// including metadata for each option, such as whether the option is
/// part of the stable long-term interface for rustc.
pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
    vec![
        opt::flag_s("h", "help", "Display this message"),
        opt::multi_s("", "cfg", "Configure the compilation environment.
                             SPEC supports the syntax `NAME[=\"VALUE\"]`.", "SPEC"),
        opt::multi("", "check-cfg", "Provide list of valid cfg options for checking", "SPEC"),
        opt::multi_s(
            "L",
            "",
            "Add a directory to the library search path. The
                             optional KIND can be one of dependency, crate, native,
                             framework, or all (the default).",
            "[KIND=]PATH",
        ),
        opt::multi_s(
            "l",
            "",
            "Link the generated crate(s) to the specified native
                             library NAME. The optional KIND can be one of
                             static, framework, or dylib (the default).
                             Optional comma separated MODIFIERS (bundle|verbatim|whole-archive|as-needed)
                             may be specified each with a prefix of either '+' to
                             enable or '-' to disable.",
            "[KIND[:MODIFIERS]=]NAME[:RENAME]",
        ),
        make_crate_type_option(),
        opt::opt_s("", "crate-name", "Specify the name of the crate being built", "NAME"),
        opt::opt_s(
            "",
            "edition",
            &EDITION_STRING,
            EDITION_NAME_LIST,
        ),
        opt::multi_s(
            "",
            "emit",
            "Comma separated list of types of output for \
             the compiler to emit",
            "[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]",
        ),
        opt::multi_s(
            "",
            "print",
            "Compiler information to print on stdout",
            "[crate-name|file-names|sysroot|target-libdir|cfg|calling-conventions|\
             target-list|target-cpus|target-features|relocation-models|code-models|\
             tls-models|target-spec-json|all-target-specs-json|native-static-libs|\
             stack-protector-strategies|link-args|deployment-target]",
        ),
        opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"),
        opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"),
        opt::opt_s("o", "", "Write output to <filename>", "FILENAME"),
        opt::opt_s(
            "",
            "out-dir",
            "Write output to compiler-chosen filename \
             in <dir>",
            "DIR",
        ),
        opt::opt_s(
            "",
            "explain",
            "Provide a detailed explanation of an error \
             message",
            "OPT",
        ),
        opt::flag_s("", "test", "Build a test harness"),
        opt::opt_s("", "target", "Target triple for which the code is compiled", "TARGET"),
        opt::multi_s("A", "allow", "Set lint allowed", "LINT"),
        opt::multi_s("W", "warn", "Set lint warnings", "LINT"),
        opt::multi_s("", "force-warn", "Set lint force-warn", "LINT"),
        opt::multi_s("D", "deny", "Set lint denied", "LINT"),
        opt::multi_s("F", "forbid", "Set lint forbidden", "LINT"),
        opt::multi_s(
            "",
            "cap-lints",
            "Set the most restrictive lint level. \
             More restrictive lints are capped at this \
             level",
            "LEVEL",
        ),
        opt::multi_s("C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
        opt::flag_s("V", "version", "Print version info and exit"),
        opt::flag_s("v", "verbose", "Use verbose output"),
    ]
}

/// Returns all rustc command line options, including metadata for
/// each option, such as whether the option is part of the stable
/// long-term interface for rustc.
pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
    let mut opts = rustc_short_optgroups();
    // FIXME: none of these descriptions are actually used
    opts.extend(vec![
        opt::multi_s(
            "",
            "extern",
            "Specify where an external rust library is located",
            "NAME[=PATH]",
        ),
        opt::opt_s("", "sysroot", "Override the system root", "PATH"),
        opt::multi("Z", "", "Set unstable / perma-unstable options", "FLAG"),
        opt::opt_s(
            "",
            "error-format",
            "How errors and other messages are produced",
            "human|json|short",
        ),
        opt::multi_s("", "json", "Configure the JSON output of the compiler", "CONFIG"),
        opt::opt_s(
            "",
            "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::opt_s(
            "",
            "diagnostic-width",
            "Inform rustc of the width of the output so that diagnostics can be truncated to fit",
            "WIDTH",
        ),
        opt::multi_s(
            "",
            "remap-path-prefix",
            "Remap source names in all output (compiler messages and output files)",
            "FROM=TO",
        ),
    ]);
    opts
}

pub fn get_cmd_lint_options(
    matches: &getopts::Matches,
    error_format: ErrorOutputType,
) -> (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(None), 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_error(error_format, format!("unknown lint level: `{cap}`")))
    });

    (lint_opts, describe_lints, lint_cap)
}

/// Parses the `--color` flag.
pub fn parse_color(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_error(
            ErrorOutputType::default(),
            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_artifact_notifications: bool,
    pub json_unused_externs: JsonUnusedExterns,
    pub 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(matches: &getopts::Matches) -> JsonConfig {
    let mut json_rendered: fn(ColorConfig) -> HumanReadableErrorType =
        HumanReadableErrorType::Default;
    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;
    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_error(
                ErrorOutputType::default(),
                "cannot specify the `--color` option with `--json`",
            );
        }

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

    JsonConfig {
        json_rendered: json_rendered(json_color),
        json_artifact_notifications,
        json_unused_externs,
        json_future_incompat,
    }
}

/// Parses the `--error-format` flag.
pub fn parse_error_format(
    matches: &getopts::Matches,
    color: ColorConfig,
    json_rendered: HumanReadableErrorType,
) -> ErrorOutputType {
    // 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(HumanReadableErrorType::Default(color))
            }
            Some("human-annotate-rs") => {
                ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet(color))
            }
            Some("json") => ErrorOutputType::Json { pretty: false, json_rendered },
            Some("pretty-json") => ErrorOutputType::Json { pretty: true, json_rendered },
            Some("short") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Short(color)),

            Some(arg) => early_error(
                ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)),
                format!(
                    "argument for `--error-format` must be `human`, `json` or \
                     `short` (instead was `{arg}`)"
                ),
            ),
        }
    } else {
        ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color))
    };

    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_error(
                ErrorOutputType::default(),
                "using `--json` requires also using `--error-format=json`",
            );
        }

        _ => {}
    }

    error_format
}

pub fn parse_crate_edition(matches: &getopts::Matches) -> Edition {
    let edition = match matches.opt_str("edition") {
        Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| {
            early_error(
                ErrorOutputType::default(),
                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 {}, but the latest edition supported by this Rust version is {}",
                edition, LATEST_STABLE_EDITION
            )
        } else {
            format!("edition {edition} is unstable and only available with -Z unstable-options")
        };
        early_error(ErrorOutputType::default(), msg)
    }

    edition
}

fn check_error_format_stability(
    unstable_opts: &UnstableOptions,
    error_format: ErrorOutputType,
    json_rendered: HumanReadableErrorType,
) {
    if !unstable_opts.unstable_options {
        if let ErrorOutputType::Json { pretty: true, json_rendered } = error_format {
            early_error(
                ErrorOutputType::Json { pretty: false, json_rendered },
                "`--error-format=pretty-json` is unstable",
            );
        }
        if let ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet(_)) =
            error_format
        {
            early_error(
                ErrorOutputType::Json { pretty: false, json_rendered },
                "`--error-format=human-annotate-rs` is unstable",
            );
        }
    }
}

fn parse_output_types(
    unstable_opts: &UnstableOptions,
    matches: &getopts::Matches,
    error_format: ErrorOutputType,
) -> OutputTypes {
    let mut output_types = BTreeMap::new();
    if !unstable_opts.parse_only {
        for list in matches.opt_strs("emit") {
            for output_type in list.split(',') {
                let (shorthand, path) = match output_type.split_once('=') {
                    None => (output_type, None),
                    Some((shorthand, path)) => (shorthand, Some(PathBuf::from(path))),
                };
                let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
                    early_error(
                        error_format,
                        format!(
                            "unknown emission type: `{shorthand}` - expected one of: {display}",
                            display = OutputType::shorthands_display(),
                        ),
                    )
                });
                output_types.insert(output_type, path);
            }
        }
    };
    if output_types.is_empty() {
        output_types.insert(OutputType::Exe, None);
    }
    OutputTypes(output_types)
}

fn should_override_cgus_and_disable_thinlto(
    output_types: &OutputTypes,
    matches: &getopts::Matches,
    error_format: ErrorOutputType,
    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_warn(
                            error_format,
                            format!(
                                "`--emit={ot}` with `-o` incompatible with \
                                 `-C codegen-units=N` for N > 1",
                            ),
                        );
                    }
                    early_warn(error_format, "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_error(error_format, "value for codegen units must be a positive non-zero integer");
    }

    (disable_local_thinlto, codegen_units)
}

fn check_thread_count(unstable_opts: &UnstableOptions, error_format: ErrorOutputType) {
    if unstable_opts.threads == 0 {
        early_error(error_format, "value for threads must be a positive non-zero integer");
    }

    if unstable_opts.threads > 1 && unstable_opts.fuel.is_some() {
        early_error(error_format, "optimization fuel is incompatible with multiple threads");
    }
}

fn collect_print_requests(
    cg: &mut CodegenOptions,
    unstable_opts: &mut UnstableOptions,
    matches: &getopts::Matches,
    error_format: ErrorOutputType,
) -> Vec<PrintRequest> {
    let mut prints = Vec::<PrintRequest>::new();
    if cg.target_cpu.as_ref().is_some_and(|s| s == "help") {
        prints.push(PrintRequest::TargetCPUs);
        cg.target_cpu = None;
    };
    if cg.target_feature == "help" {
        prints.push(PrintRequest::TargetFeatures);
        cg.target_feature = String::new();
    }

    const PRINT_REQUESTS: &[(&str, PrintRequest)] = &[
        ("crate-name", PrintRequest::CrateName),
        ("file-names", PrintRequest::FileNames),
        ("sysroot", PrintRequest::Sysroot),
        ("target-libdir", PrintRequest::TargetLibdir),
        ("cfg", PrintRequest::Cfg),
        ("calling-conventions", PrintRequest::CallingConventions),
        ("target-list", PrintRequest::TargetList),
        ("target-cpus", PrintRequest::TargetCPUs),
        ("target-features", PrintRequest::TargetFeatures),
        ("relocation-models", PrintRequest::RelocationModels),
        ("code-models", PrintRequest::CodeModels),
        ("tls-models", PrintRequest::TlsModels),
        ("native-static-libs", PrintRequest::NativeStaticLibs),
        ("stack-protector-strategies", PrintRequest::StackProtectorStrategies),
        ("target-spec-json", PrintRequest::TargetSpec),
        ("all-target-specs-json", PrintRequest::AllTargetSpecs),
        ("link-args", PrintRequest::LinkArgs),
        ("split-debuginfo", PrintRequest::SplitDebuginfo),
        ("deployment-target", PrintRequest::DeploymentTarget),
    ];

    prints.extend(matches.opt_strs("print").into_iter().map(|req| {
        match PRINT_REQUESTS.iter().find(|&&(name, _)| name == req) {
            Some((_, PrintRequest::TargetSpec)) => {
                if unstable_opts.unstable_options {
                    PrintRequest::TargetSpec
                } else {
                    early_error(
                        error_format,
                        "the `-Z unstable-options` flag must also be passed to \
                         enable the target-spec-json print option",
                    );
                }
            }
            Some((_, PrintRequest::AllTargetSpecs)) => {
                if unstable_opts.unstable_options {
                    PrintRequest::AllTargetSpecs
                } else {
                    early_error(
                        error_format,
                        "the `-Z unstable-options` flag must also be passed to \
                         enable the all-target-specs-json print option",
                    );
                }
            }
            Some(&(_, print_request)) => print_request,
            None => {
                let prints =
                    PRINT_REQUESTS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>();
                let prints = prints.join(", ");
                early_error(
                    error_format,
                    format!("unknown print request `{req}`. Valid print requests are: {prints}"),
                );
            }
        }
    }));

    prints
}

pub fn parse_target_triple(
    matches: &getopts::Matches,
    error_format: ErrorOutputType,
) -> TargetTriple {
    match matches.opt_str("target") {
        Some(target) if target.ends_with(".json") => {
            let path = Path::new(&target);
            TargetTriple::from_path(path).unwrap_or_else(|_| {
                early_error(error_format, format!("target file {path:?} does not exist"))
            })
        }
        Some(target) => TargetTriple::TargetTriple(target),
        _ => TargetTriple::from_triple(host_triple()),
    }
}

fn parse_opt_level(
    matches: &getopts::Matches,
    cg: &CodegenOptions,
    error_format: ErrorOutputType,
) -> 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::Default
    } else {
        match cg.opt_level.as_ref() {
            "0" => OptLevel::No,
            "1" => OptLevel::Less,
            "2" => OptLevel::Default,
            "3" => OptLevel::Aggressive,
            "s" => OptLevel::Size,
            "z" => OptLevel::SizeMin,
            arg => {
                early_error(
                    error_format,
                    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 }
}

pub(crate) fn parse_assert_incr_state(
    opt_assertion: &Option<String>,
    error_format: ErrorOutputType,
) -> 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_error(error_format, format!("unexpected incremental state assertion value: {s}"))
        }
        None => None,
    }
}

fn parse_native_lib_kind(
    matches: &getopts::Matches,
    kind: &str,
    error_format: ErrorOutputType,
) -> (NativeLibKind, Option<bool>) {
    let (kind, modifiers) = match kind.split_once(':') {
        None => (kind, None),
        Some((kind, modifiers)) => (kind, Some(modifiers)),
    };

    let kind = match kind {
        "static" => NativeLibKind::Static { bundle: None, whole_archive: None },
        "dylib" => NativeLibKind::Dylib { as_needed: None },
        "framework" => NativeLibKind::Framework { as_needed: None },
        "link-arg" => {
            if !nightly_options::is_unstable_enabled(matches) {
                let why = if nightly_options::match_is_nightly_build(matches) {
                    " and only accepted on the nightly compiler"
                } else {
                    ", the `-Z unstable-options` flag must also be passed to use it"
                };
                early_error(error_format, format!("library kind `link-arg` is unstable{why}"))
            }
            NativeLibKind::LinkArg
        }
        _ => early_error(
            error_format,
            format!(
                "unknown library kind `{kind}`, expected one of: static, dylib, framework, link-arg"
            ),
        ),
    };
    match modifiers {
        None => (kind, None),
        Some(modifiers) => parse_native_lib_modifiers(kind, modifiers, error_format, matches),
    }
}

fn parse_native_lib_modifiers(
    mut kind: NativeLibKind,
    modifiers: &str,
    error_format: ErrorOutputType,
    matches: &getopts::Matches,
) -> (NativeLibKind, Option<bool>) {
    let mut verbatim = None;
    for modifier in modifiers.split(',') {
        let (modifier, value) = match modifier.strip_prefix(['+', '-']) {
            Some(m) => (m, modifier.starts_with('+')),
            None => early_error(
                error_format,
                "invalid linking modifier syntax, expected '+' or '-' prefix \
                 before one of: bundle, verbatim, whole-archive, as-needed",
            ),
        };

        let report_unstable_modifier = || {
            if !nightly_options::is_unstable_enabled(matches) {
                let why = if nightly_options::match_is_nightly_build(matches) {
                    " and only accepted on the nightly compiler"
                } else {
                    ", the `-Z unstable-options` flag must also be passed to use it"
                };
                early_error(error_format, format!("linking modifier `{modifier}` is unstable{why}"))
            }
        };
        let assign_modifier = |dst: &mut Option<bool>| {
            if dst.is_some() {
                let msg = format!("multiple `{modifier}` modifiers in a single `-l` option");
                early_error(error_format, msg)
            } else {
                *dst = Some(value);
            }
        };
        match (modifier, &mut kind) {
            ("bundle", NativeLibKind::Static { bundle, .. }) => assign_modifier(bundle),
            ("bundle", _) => early_error(
                error_format,
                "linking modifier `bundle` is only compatible with `static` linking kind",
            ),

            ("verbatim", _) => assign_modifier(&mut verbatim),

            ("whole-archive", NativeLibKind::Static { whole_archive, .. }) => {
                assign_modifier(whole_archive)
            }
            ("whole-archive", _) => early_error(
                error_format,
                "linking modifier `whole-archive` is only compatible with `static` linking kind",
            ),

            ("as-needed", NativeLibKind::Dylib { as_needed })
            | ("as-needed", NativeLibKind::Framework { as_needed }) => {
                report_unstable_modifier();
                assign_modifier(as_needed)
            }
            ("as-needed", _) => early_error(
                error_format,
                "linking modifier `as-needed` is only compatible with \
                 `dylib` and `framework` linking kinds",
            ),

            // Note: this error also excludes the case with empty modifier
            // string, like `modifiers = ""`.
            _ => early_error(
                error_format,
                format!(
                    "unknown linking modifier `{modifier}`, expected one \
                     of: bundle, verbatim, whole-archive, as-needed"
                ),
            ),
        }
    }

    (kind, verbatim)
}

fn parse_libs(matches: &getopts::Matches, error_format: ErrorOutputType) -> Vec<NativeLib> {
    matches
        .opt_strs("l")
        .into_iter()
        .map(|s| {
            // Parse string of the form "[KIND[:MODIFIERS]=]lib[:new_name]",
            // where KIND is one of "dylib", "framework", "static", "link-arg" and
            // where MODIFIERS are a comma separated list of supported modifiers
            // (bundle, verbatim, whole-archive, as-needed). Each modifier is prefixed
            // with either + or - to indicate whether it is enabled or disabled.
            // The last value specified for a given modifier wins.
            let (name, kind, verbatim) = match s.split_once('=') {
                None => (s, NativeLibKind::Unspecified, None),
                Some((kind, name)) => {
                    let (kind, verbatim) = parse_native_lib_kind(matches, kind, error_format);
                    (name.to_string(), kind, verbatim)
                }
            };

            let (name, new_name) = match name.split_once(':') {
                None => (name, None),
                Some((name, new_name)) => (name.to_string(), Some(new_name.to_owned())),
            };
            if name.is_empty() {
                early_error(error_format, "library name must not be empty");
            }
            NativeLib { name, new_name, kind, verbatim }
        })
        .collect()
}

pub fn parse_externs(
    matches: &getopts::Matches,
    unstable_opts: &UnstableOptions,
    error_format: ErrorOutputType,
) -> 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 (name, path) = match arg.split_once('=') {
            None => (arg, None),
            Some((name, path)) => (name.to_string(), Some(Path::new(path))),
        };
        let (options, name) = match name.split_once(':') {
            None => (None, name),
            Some((opts, name)) => (Some(opts), name.to_string()),
        };

        let path = path.map(|p| CanonicalizedPath::new(p));

        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
            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_error(
                    error_format,
                    "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_error(
                                error_format,
                                "the `noprelude` --extern option requires a file path",
                            );
                        }
                    }
                    "nounused" => nounused_dep = true,
                    "force" => force = true,
                    _ => early_error(error_format, 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(
    matches: &getopts::Matches,
    unstable_opts: &UnstableOptions,
    error_format: ErrorOutputType,
) -> 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_error(
                error_format,
                "--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
}

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

    let edition = parse_crate_edition(matches);

    let JsonConfig {
        json_rendered,
        json_artifact_notifications,
        json_unused_externs,
        json_future_incompat,
    } = parse_json(matches);

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

    let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
        early_error(error_format, "`--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_error(error_format, e));

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

    check_error_format_stability(&unstable_opts, error_format, json_rendered);

    if !unstable_opts.unstable_options && json_unused_externs.is_enabled() {
        early_error(
            error_format,
            "the `-Z unstable-options` flag must also be passed to enable \
            the flag `--json=unused-externs`",
        );
    }

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

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

    check_thread_count(&unstable_opts, error_format);

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

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

    if unstable_opts.profile && incremental.is_some() {
        early_error(
            error_format,
            "can't instrument with gcov profiling when compiling incrementally",
        );
    }
    if unstable_opts.profile {
        match codegen_units {
            Some(1) => {}
            None => codegen_units = Some(1),
            Some(_) => early_error(
                error_format,
                "can't instrument with gcov profiling with multiple codegen units",
            ),
        }
    }

    if cg.profile_generate.enabled() && cg.profile_use.is_some() {
        early_error(
            error_format,
            "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_error(
            error_format,
            "option `-Z profile-sample-use` cannot be used with `-C profile-generate` or `-C profile-use`",
        );
    }

    // Handle both `-Z symbol-mangling-version` and `-C symbol-mangling-version`; the latter takes
    // precedence.
    match (cg.symbol_mangling_version, unstable_opts.symbol_mangling_version) {
        (Some(smv_c), Some(smv_z)) if smv_c != smv_z => {
            early_error(
                error_format,
                "incompatible values passed for `-C symbol-mangling-version` \
                and `-Z symbol-mangling-version`",
            );
        }
        (Some(SymbolManglingVersion::V0), _) => {}
        (Some(_), _) if !unstable_opts.unstable_options => {
            early_error(
                error_format,
                "`-C symbol-mangling-version=legacy` requires `-Z unstable-options`",
            );
        }
        (None, None) => {}
        (None, smv) => {
            early_warn(
                error_format,
                "`-Z symbol-mangling-version` is deprecated; use `-C symbol-mangling-version`",
            );
            cg.symbol_mangling_version = smv;
        }
        _ => {}
    }

    // Handle both `-Z instrument-coverage` and `-C instrument-coverage`; the latter takes
    // precedence.
    match (cg.instrument_coverage, unstable_opts.instrument_coverage) {
        (Some(ic_c), Some(ic_z)) if ic_c != ic_z => {
            early_error(
                error_format,
                "incompatible values passed for `-C instrument-coverage` \
                and `-Z instrument-coverage`",
            );
        }
        (Some(InstrumentCoverage::Off | InstrumentCoverage::All), _) => {}
        (Some(_), _) if !unstable_opts.unstable_options => {
            early_error(
                error_format,
                "`-C instrument-coverage=except-*` requires `-Z unstable-options`",
            );
        }
        (None, None) => {}
        (None, ic) => {
            early_warn(
                error_format,
                "`-Z instrument-coverage` is deprecated; use `-C instrument-coverage`",
            );
            cg.instrument_coverage = ic;
        }
        _ => {}
    }

    if cg.instrument_coverage.is_some() && cg.instrument_coverage != Some(InstrumentCoverage::Off) {
        if cg.profile_generate.enabled() || cg.profile_use.is_some() {
            early_error(
                error_format,
                "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_warn(
                    error_format,
                    "-C instrument-coverage requires symbol mangling version `v0`, \
                    but `-C symbol-mangling-version=legacy` was specified",
                );
            }
            Some(SymbolManglingVersion::V0) => {}
        }
    }

    if let Ok(graphviz_font) = std::env::var("RUSTC_GRAPHVIZ_FONT") {
        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_error(
                error_format,
                "options `-C embed-bitcode=no` and `-C lto` are incompatible",
            ),
        }
    }

    let prints = collect_print_requests(&mut cg, &mut unstable_opts, matches, error_format);

    let cg = cg;

    let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
    let target_triple = parse_target_triple(matches, error_format);
    let opt_level = parse_opt_level(matches, &cg, error_format);
    // 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);

    let mut search_paths = vec![];
    for s in &matches.opt_strs("L") {
        search_paths.push(SearchPath::from_cli_opt(s, error_format));
    }

    let libs = parse_libs(matches, error_format);

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

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

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

    let crate_name = matches.opt_str("crate-name");

    let remap_path_prefix = parse_remap_path_prefix(matches, &unstable_opts, error_format);

    let pretty = parse_pretty(&unstable_opts, error_format);

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

    // Try to find a directory containing the Rust `src`, for more details see
    // the doc comment on the `real_rust_source_base_dir` field.
    let tmp_buf;
    let sysroot = match &sysroot_opt {
        Some(s) => s,
        None => {
            tmp_buf = crate::filesearch::get_or_default_sysroot().expect("Failed finding sysroot");
            &tmp_buf
        }
    };
    let real_rust_source_base_dir = {
        // This is the location used by the `rust-src` `rustup` component.
        let mut candidate = sysroot.join("lib/rustlib/src/rust");
        if let Ok(metadata) = candidate.symlink_metadata() {
            // Replace the symlink rustbuild 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("library/std/src/lib.rs").is_file().then_some(candidate)
    };

    let working_dir = std::env::current_dir().unwrap_or_else(|e| {
        early_error(error_format, format!("Current directory is invalid: {e}"));
    });

    let remap = FilePathMapping::new(remap_path_prefix.clone());
    let (path, remapped) = remap.map_prefix(&working_dir);
    let working_dir = if remapped {
        RealFileName::Remapped { virtual_name: path.into_owned(), local_path: Some(working_dir) }
    } else {
        RealFileName::LocalPath(path.into_owned())
    };

    Options {
        assert_incr_state,
        crate_types,
        optimize: opt_level,
        debuginfo,
        lint_opts,
        lint_cap,
        describe_lints,
        output_types,
        search_paths,
        maybe_sysroot: sysroot_opt,
        target_triple,
        test,
        incremental,
        unstable_opts,
        prints,
        cg,
        error_format,
        diagnostic_width,
        externs,
        unstable_features: UnstableFeatures::from_environment(crate_name.as_deref()),
        crate_name,
        libs,
        debug_assertions,
        actually_rustdoc: false,
        resolve_doc_links: ResolveDocLinks::ExportedMetadata,
        trimmed_def_paths: TrimmedDefPaths::default(),
        cli_forced_codegen_units: codegen_units,
        cli_forced_local_thinlto_off: disable_local_thinlto,
        remap_path_prefix,
        real_rust_source_base_dir,
        edition,
        json_artifact_notifications,
        json_unused_externs,
        json_future_incompat,
        pretty,
        working_dir,
    }
}

fn parse_pretty(unstable_opts: &UnstableOptions, efmt: ErrorOutputType) -> 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(PpAstTreeMode::Normal),
        "ast-tree,expanded" => AstTree(PpAstTreeMode::Expanded),
        "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,
        "mir-cfg" => MirCFG,
        name => early_error(
            efmt,
            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` or \
                            `mir-cfg`; got {name}"
            ),
        ),
    };
    debug!("got unpretty option: {first:?}");
    Some(first)
}

pub fn make_crate_type_option() -> RustcOptGroup {
    opt::multi_s(
        "",
        "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" => default_lib_output(),
                "rlib" => CrateType::Rlib,
                "staticlib" => CrateType::Staticlib,
                "dylib" => CrateType::Dylib,
                "cdylib" => CrateType::Cdylib,
                "bin" => CrateType::Executable,
                "proc-macro" => CrateType::ProcMacro,
                _ => return Err(format!("unknown crate type: `{part}`")),
            };
            if !crate_types.contains(&new_part) {
                crate_types.push(new_part)
            }
        }
    }

    Ok(crate_types)
}

pub mod nightly_options {
    use super::{ErrorOutputType, OptionStability, RustcOptGroup};
    use crate::early_error;
    use rustc_feature::UnstableFeatures;

    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())
    }

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

    pub fn check_nightly_options(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);

        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_error(
                    ErrorOutputType::default(),
                    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 => {
                    let msg = format!(
                        "the option `{}` is only accepted on the nightly compiler",
                        opt.name
                    );
                    early_error(ErrorOutputType::default(), msg);
                }
                OptionStability::Stable => {}
            }
        }
    }
}

impl fmt::Display for CrateType {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match *self {
            CrateType::Executable => "bin".fmt(f),
            CrateType::Dylib => "dylib".fmt(f),
            CrateType::Rlib => "rlib".fmt(f),
            CrateType::Staticlib => "staticlib".fmt(f),
            CrateType::Cdylib => "cdylib".fmt(f),
            CrateType::ProcMacro => "proc-macro".fmt(f),
        }
    }
}

impl IntoDiagnosticArg for CrateType {
    fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
        self.to_string().into_diagnostic_arg()
    }
}

#[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 PpAstTreeMode {
    /// `-Zunpretty=ast`
    Normal,
    /// `-Zunpretty=ast,expanded`
    Expanded,
}

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

#[derive(Copy, Clone, PartialEq, Debug)]
pub enum PpMode {
    /// Options that print the source code, i.e.
    /// `-Zunpretty=normal` and `-Zunpretty=expanded`
    Source(PpSourceMode),
    AstTree(PpAstTreeMode),
    /// 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,
}

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

            Source(Expanded | ExpandedIdentified | ExpandedHygiene)
            | AstTree(PpAstTreeMode::Expanded)
            | Hir(_)
            | HirTree
            | ThirTree
            | ThirFlat
            | Mir
            | MirCFG => true,
        }
    }
    pub fn needs_hir(&self) -> bool {
        use PpMode::*;
        match *self {
            Source(_) | AstTree(_) => false,

            Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG => true,
        }
    }

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

/// 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 super::{
        BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, ErrorOutputType,
        InstrumentCoverage, InstrumentXRay, LdImpl, LinkerPluginLto, LocationDetail, LtoCli,
        OomStrategy, OptLevel, OutputType, OutputTypes, Passes, ResolveDocLinks,
        SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
        TraitSolver, TrimmedDefPaths,
    };
    use crate::lint;
    use crate::options::WasiExecModel;
    use crate::utils::{NativeLib, NativeLibKind};
    use rustc_errors::LanguageIdentifier;
    use rustc_feature::UnstableFeatures;
    use rustc_span::edition::Edition;
    use rustc_span::RealFileName;
    use rustc_target::spec::{CodeModel, MergeFunctions, PanicStrategy, RelocModel};
    use rustc_target::spec::{
        RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TargetTriple, TlsModel,
    };
    use std::collections::hash_map::DefaultHasher;
    use std::collections::BTreeMap;
    use std::hash::Hash;
    use std::num::NonZeroUsize;
    use std::path::PathBuf;

    pub trait DepTrackingHash {
        fn hash(
            &self,
            hasher: &mut DefaultHasher,
            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 DefaultHasher, _: ErrorOutputType, _for_crate_hash: bool) {
                    Hash::hash(self, hasher);
                }
            }
        )+};
    }

    impl<T: DepTrackingHash> DepTrackingHash for Option<T> {
        fn hash(
            &self,
            hasher: &mut DefaultHasher,
            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!(
        bool,
        usize,
        NonZeroUsize,
        u64,
        String,
        PathBuf,
        lint::Level,
        WasiExecModel,
        u32,
        RelocModel,
        CodeModel,
        TlsModel,
        InstrumentCoverage,
        InstrumentXRay,
        CrateType,
        MergeFunctions,
        PanicStrategy,
        RelroLevel,
        Passes,
        OptLevel,
        LtoCli,
        DebugInfo,
        UnstableFeatures,
        NativeLib,
        NativeLibKind,
        SanitizerSet,
        CFGuard,
        CFProtection,
        TargetTriple,
        Edition,
        LinkerPluginLto,
        ResolveDocLinks,
        SplitDebuginfo,
        SplitDwarfKind,
        StackProtector,
        SwitchWithOptPath,
        SymbolManglingVersion,
        SourceFileHashAlgorithm,
        TrimmedDefPaths,
        Option<LdImpl>,
        OutputType,
        RealFileName,
        LocationDetail,
        BranchProtection,
        OomStrategy,
        LanguageIdentifier,
        TraitSolver,
    );

    impl<T1, T2> DepTrackingHash for (T1, T2)
    where
        T1: DepTrackingHash,
        T2: DepTrackingHash,
    {
        fn hash(
            &self,
            hasher: &mut DefaultHasher,
            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 DefaultHasher,
            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 DefaultHasher,
            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 DepTrackingHash for OutputTypes {
        fn hash(
            &self,
            hasher: &mut DefaultHasher,
            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 DefaultHasher,
        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);
        }
    }
}

/// Default behavior to use in out-of-memory situations.
#[derive(Clone, Copy, PartialEq, Hash, Debug, Encodable, Decodable, HashStable_Generic)]
pub enum OomStrategy {
    /// Generate a panic that can be caught by `catch_unwind`.
    Panic,

    /// Abort the process immediately.
    Abort,
}

impl OomStrategy {
    pub const SYMBOL: &'static str = "__rust_alloc_error_handler_should_panic";

    pub fn should_panic(self) -> u8 {
        match self {
            OomStrategy::Panic => 1,
            OomStrategy::Abort => 0,
        }
    }
}

/// 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",
        }
    }
}
