Skip to main content

rustc_session/
config.rs

1//! Contains infrastructure for configuring the compiler, including parsing
2//! command-line options.
3
4use std::collections::btree_map::{
5    Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
6};
7use std::collections::{BTreeMap, BTreeSet};
8use std::ffi::OsStr;
9use std::hash::Hash;
10use std::path::{Path, PathBuf};
11use std::str::{self, FromStr};
12use std::sync::LazyLock;
13use std::{cmp, fs, iter};
14
15use externs::{ExternOpt, split_extern_opt};
16use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
17use rustc_data_structures::stable_hash::{StableHasher, StableOrd};
18use rustc_errors::emitter::HumanReadableErrorType;
19use rustc_errors::{ColorConfig, DiagCtxtFlags};
20use rustc_feature::UnstableFeatures;
21use rustc_hashes::Hash64;
22use rustc_macros::{BlobDecodable, Decodable, Encodable, StableHash};
23use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION};
24use rustc_span::source_map::FilePathMapping;
25use rustc_span::{
26    FileName, RealFileName, RemapPathScopeComponents, SourceFileHashAlgorithm, Symbol, sym,
27};
28use rustc_target::spec::{
29    FramePointer, LinkSelfContainedComponents, LinkerFeatures, PanicStrategy, SplitDebuginfo,
30    Target, TargetTuple,
31};
32use tracing::debug;
33
34pub use crate::config::cfg::{Cfg, CheckCfg, ExpectedValues};
35use crate::config::native_libs::parse_native_libs;
36pub use crate::config::print_request::{PrintKind, PrintRequest};
37use crate::errors::FileWriteFail;
38pub use crate::options::*;
39use crate::search_paths::SearchPath;
40use crate::utils::CanonicalizedPath;
41use crate::{EarlyDiagCtxt, Session, filesearch, lint};
42
43mod cfg;
44mod externs;
45mod native_libs;
46mod print_request;
47pub mod sigpipe;
48
49/// The different settings that the `-C strip` flag can have.
50#[derive(#[automatically_derived]
impl ::core::clone::Clone for Strip {
    #[inline]
    fn clone(&self) -> Strip { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Strip { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for Strip {
    #[inline]
    fn eq(&self, other: &Strip) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for Strip {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Strip {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                Strip::None => "None",
                Strip::Debuginfo => "Debuginfo",
                Strip::Symbols => "Symbols",
            })
    }
}Debug)]
51pub enum Strip {
52    /// Do not strip at all.
53    None,
54
55    /// Strip debuginfo.
56    Debuginfo,
57
58    /// Strip all symbols.
59    Symbols,
60}
61
62/// The different settings that the `-C control-flow-guard` flag can have.
63#[derive(#[automatically_derived]
impl ::core::clone::Clone for CFGuard {
    #[inline]
    fn clone(&self) -> CFGuard { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CFGuard { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for CFGuard {
    #[inline]
    fn eq(&self, other: &CFGuard) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for CFGuard {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for CFGuard {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                CFGuard::Disabled => "Disabled",
                CFGuard::NoChecks => "NoChecks",
                CFGuard::Checks => "Checks",
            })
    }
}Debug)]
64pub enum CFGuard {
65    /// Do not emit Control Flow Guard metadata or checks.
66    Disabled,
67
68    /// Emit Control Flow Guard metadata but no checks.
69    NoChecks,
70
71    /// Emit Control Flow Guard metadata and checks.
72    Checks,
73}
74
75/// The different settings that the `-Z cf-protection` flag can have.
76#[derive(#[automatically_derived]
impl ::core::clone::Clone for CFProtection {
    #[inline]
    fn clone(&self) -> CFProtection { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CFProtection { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for CFProtection {
    #[inline]
    fn eq(&self, other: &CFProtection) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for CFProtection {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for CFProtection {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                CFProtection::None => "None",
                CFProtection::Branch => "Branch",
                CFProtection::Return => "Return",
                CFProtection::Full => "Full",
            })
    }
}Debug)]
77pub enum CFProtection {
78    /// Do not enable control-flow protection
79    None,
80
81    /// Emit control-flow protection for branches (enables indirect branch tracking).
82    Branch,
83
84    /// Emit control-flow protection for returns.
85    Return,
86
87    /// Emit control-flow protection for both branches and returns.
88    Full,
89}
90
91#[derive(#[automatically_derived]
impl ::core::clone::Clone for OptLevel {
    #[inline]
    fn clone(&self) -> OptLevel { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for OptLevel { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for OptLevel {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                OptLevel::No => "No",
                OptLevel::Less => "Less",
                OptLevel::More => "More",
                OptLevel::Aggressive => "Aggressive",
                OptLevel::Size => "Size",
                OptLevel::SizeMin => "SizeMin",
            })
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for OptLevel {
    #[inline]
    fn eq(&self, other: &OptLevel) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for OptLevel {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for OptLevel {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    OptLevel::No => {}
                    OptLevel::Less => {}
                    OptLevel::More => {}
                    OptLevel::Aggressive => {}
                    OptLevel::Size => {}
                    OptLevel::SizeMin => {}
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for OptLevel {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        OptLevel::No => { 0usize }
                        OptLevel::Less => { 1usize }
                        OptLevel::More => { 2usize }
                        OptLevel::Aggressive => { 3usize }
                        OptLevel::Size => { 4usize }
                        OptLevel::SizeMin => { 5usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    OptLevel::No => {}
                    OptLevel::Less => {}
                    OptLevel::More => {}
                    OptLevel::Aggressive => {}
                    OptLevel::Size => {}
                    OptLevel::SizeMin => {}
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for OptLevel {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { OptLevel::No }
                    1usize => { OptLevel::Less }
                    2usize => { OptLevel::More }
                    3usize => { OptLevel::Aggressive }
                    4usize => { OptLevel::Size }
                    5usize => { OptLevel::SizeMin }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `OptLevel`, expected 0..6, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable)]
92pub enum OptLevel {
93    /// `-Copt-level=0`
94    No,
95    /// `-Copt-level=1`
96    Less,
97    /// `-Copt-level=2`
98    More,
99    /// `-Copt-level=3` / `-O`
100    Aggressive,
101    /// `-Copt-level=s`
102    Size,
103    /// `-Copt-level=z`
104    SizeMin,
105}
106
107/// This is what the `LtoCli` values get mapped to after resolving defaults and
108/// and taking other command line options into account.
109///
110/// Note that linker plugin-based LTO is a different mechanism entirely.
111#[derive(#[automatically_derived]
impl ::core::clone::Clone for Lto {
    #[inline]
    fn clone(&self) -> Lto {
        match self {
            Lto::No => Lto::No,
            Lto::Thin => Lto::Thin,
            Lto::ThinLocal => Lto::ThinLocal,
            Lto::Fat => Lto::Fat,
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Lto {
    #[inline]
    fn eq(&self, other: &Lto) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for Lto {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        Lto::No => { 0usize }
                        Lto::Thin => { 1usize }
                        Lto::ThinLocal => { 2usize }
                        Lto::Fat => { 3usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    Lto::No => {}
                    Lto::Thin => {}
                    Lto::ThinLocal => {}
                    Lto::Fat => {}
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for Lto {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { Lto::No }
                    1usize => { Lto::Thin }
                    2usize => { Lto::ThinLocal }
                    3usize => { Lto::Fat }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Lto`, expected 0..4, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable)]
112pub enum Lto {
113    /// Don't do any LTO whatsoever.
114    No,
115
116    /// Do a full-crate-graph (inter-crate) LTO with ThinLTO.
117    Thin,
118
119    /// Do a local ThinLTO (intra-crate, over the CodeGen Units of the local crate only). This is
120    /// only relevant if multiple CGUs are used.
121    ThinLocal,
122
123    /// Do a full-crate-graph (inter-crate) LTO with "fat" LTO.
124    Fat,
125}
126
127/// The different settings that the `-C lto` flag can have.
128#[derive(#[automatically_derived]
impl ::core::clone::Clone for LtoCli {
    #[inline]
    fn clone(&self) -> LtoCli { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for LtoCli { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for LtoCli {
    #[inline]
    fn eq(&self, other: &LtoCli) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for LtoCli {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for LtoCli {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                LtoCli::No => "No",
                LtoCli::Yes => "Yes",
                LtoCli::NoParam => "NoParam",
                LtoCli::Thin => "Thin",
                LtoCli::Fat => "Fat",
                LtoCli::Unspecified => "Unspecified",
            })
    }
}Debug)]
129pub enum LtoCli {
130    /// `-C lto=no`
131    No,
132    /// `-C lto=yes`
133    Yes,
134    /// `-C lto`
135    NoParam,
136    /// `-C lto=thin`
137    Thin,
138    /// `-C lto=fat`
139    Fat,
140    /// No `-C lto` flag passed
141    Unspecified,
142}
143
144/// The different settings that the `-C instrument-coverage` flag can have.
145#[derive(#[automatically_derived]
impl ::core::clone::Clone for InstrumentCoverage {
    #[inline]
    fn clone(&self) -> InstrumentCoverage { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for InstrumentCoverage { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for InstrumentCoverage {
    #[inline]
    fn eq(&self, other: &InstrumentCoverage) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for InstrumentCoverage {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for InstrumentCoverage {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                InstrumentCoverage::No => "No",
                InstrumentCoverage::Yes => "Yes",
            })
    }
}Debug)]
146pub enum InstrumentCoverage {
147    /// `-C instrument-coverage=no` (or `off`, `false` etc.)
148    No,
149    /// `-C instrument-coverage` or `-C instrument-coverage=yes`
150    Yes,
151}
152
153/// Individual flag values controlled by `-Zcoverage-options`.
154#[derive(#[automatically_derived]
impl ::core::clone::Clone for CoverageOptions {
    #[inline]
    fn clone(&self) -> CoverageOptions {
        let _: ::core::clone::AssertParamIsClone<CoverageLevel>;
        let _: ::core::clone::AssertParamIsClone<bool>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CoverageOptions { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for CoverageOptions {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "CoverageOptions", "level", &self.level,
            "discard_all_spans_in_codegen",
            &&self.discard_all_spans_in_codegen)
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for CoverageOptions {
    #[inline]
    fn eq(&self, other: &CoverageOptions) -> bool {
        self.discard_all_spans_in_codegen ==
                other.discard_all_spans_in_codegen &&
            self.level == other.level
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for CoverageOptions {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<CoverageLevel>;
        let _: ::core::cmp::AssertParamIsEq<bool>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for CoverageOptions {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.level, state);
        ::core::hash::Hash::hash(&self.discard_all_spans_in_codegen, state)
    }
}Hash, #[automatically_derived]
impl ::core::default::Default for CoverageOptions {
    #[inline]
    fn default() -> CoverageOptions {
        CoverageOptions {
            level: ::core::default::Default::default(),
            discard_all_spans_in_codegen: ::core::default::Default::default(),
        }
    }
}Default)]
155pub struct CoverageOptions {
156    pub level: CoverageLevel,
157
158    /// **(internal test-only flag)**
159    /// `-Zcoverage-options=discard-all-spans-in-codegen`: During codegen,
160    /// discard all coverage spans as though they were invalid. Needed by
161    /// regression tests for #133606, because we don't have an easy way to
162    /// reproduce it from actual source code.
163    pub discard_all_spans_in_codegen: bool,
164}
165
166/// Controls whether branch coverage is enabled.
167#[derive(#[automatically_derived]
impl ::core::clone::Clone for CoverageLevel {
    #[inline]
    fn clone(&self) -> CoverageLevel { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CoverageLevel { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for CoverageLevel {
    #[inline]
    fn eq(&self, other: &CoverageLevel) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for CoverageLevel {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for CoverageLevel {
    #[inline]
    fn partial_cmp(&self, other: &CoverageLevel)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for CoverageLevel {
    #[inline]
    fn cmp(&self, other: &CoverageLevel) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for CoverageLevel {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for CoverageLevel {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                CoverageLevel::Block => "Block",
                CoverageLevel::Branch => "Branch",
                CoverageLevel::Condition => "Condition",
            })
    }
}Debug, #[automatically_derived]
impl ::core::default::Default for CoverageLevel {
    #[inline]
    fn default() -> CoverageLevel { Self::Block }
}Default)]
168pub enum CoverageLevel {
169    /// Instrument for coverage at the MIR block level.
170    #[default]
171    Block,
172    /// Also instrument branch points (includes block coverage).
173    Branch,
174    /// Same as branch coverage, but also adds branch instrumentation for
175    /// certain boolean expressions that are not directly used for branching.
176    ///
177    /// For example, in the following code, `b` does not directly participate
178    /// in a branch, but condition coverage will instrument it as its own
179    /// artificial branch:
180    /// ```
181    /// # let (a, b) = (false, true);
182    /// let x = a && b;
183    /// //           ^ last operand
184    /// ```
185    ///
186    /// This level is mainly intended to be a stepping-stone towards full MC/DC
187    /// instrumentation, so it might be removed in the future when MC/DC is
188    /// sufficiently complete, or if it is making MC/DC changes difficult.
189    Condition,
190}
191
192// The different settings that the `-Z offload` flag can have.
193#[derive(#[automatically_derived]
impl ::core::clone::Clone for Offload {
    #[inline]
    fn clone(&self) -> Offload {
        match self {
            Offload::Device => Offload::Device,
            Offload::Host(__self_0) =>
                Offload::Host(::core::clone::Clone::clone(__self_0)),
            Offload::Test => Offload::Test,
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Offload {
    #[inline]
    fn eq(&self, other: &Offload) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (Offload::Host(__self_0), Offload::Host(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for Offload {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            Offload::Host(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Offload {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Offload::Device => ::core::fmt::Formatter::write_str(f, "Device"),
            Offload::Host(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Host",
                    &__self_0),
            Offload::Test => ::core::fmt::Formatter::write_str(f, "Test"),
        }
    }
}Debug, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for Offload {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        Offload::Device => { 0usize }
                        Offload::Host(ref __binding_0) => { 1usize }
                        Offload::Test => { 2usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    Offload::Device => {}
                    Offload::Host(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    Offload::Test => {}
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for Offload {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { Offload::Device }
                    1usize => {
                        Offload::Host(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    2usize => { Offload::Test }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Offload`, expected 0..3, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable)]
194pub enum Offload {
195    /// Entry point for `std::offload`, enables kernel compilation for a gpu device
196    Device,
197    /// Second step in the offload pipeline, generates the host code to call kernels.
198    Host(String),
199    /// Test is similar to Host, but allows testing without a device artifact.
200    Test,
201}
202
203/// The different settings that the `-Z codegen-emit-retag` flag can have.
204#[derive(#[automatically_derived]
impl ::core::marker::Copy for CodegenRetagOptions { }Copy, #[automatically_derived]
impl ::core::clone::Clone for CodegenRetagOptions {
    #[inline]
    fn clone(&self) -> CodegenRetagOptions {
        let _: ::core::clone::AssertParamIsClone<bool>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for CodegenRetagOptions {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "CodegenRetagOptions", "no_precise_im", &self.no_precise_im,
            "no_precise_pin", &&self.no_precise_pin)
    }
}Debug, #[automatically_derived]
impl ::core::default::Default for CodegenRetagOptions {
    #[inline]
    fn default() -> CodegenRetagOptions {
        CodegenRetagOptions {
            no_precise_im: ::core::default::Default::default(),
            no_precise_pin: ::core::default::Default::default(),
        }
    }
}Default, #[automatically_derived]
impl ::core::cmp::PartialEq for CodegenRetagOptions {
    #[inline]
    fn eq(&self, other: &CodegenRetagOptions) -> bool {
        self.no_precise_im == other.no_precise_im &&
            self.no_precise_pin == other.no_precise_pin
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for CodegenRetagOptions {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.no_precise_im, state);
        ::core::hash::Hash::hash(&self.no_precise_pin, state)
    }
}Hash, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for CodegenRetagOptions {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    CodegenRetagOptions {
                        no_precise_im: ref __binding_0,
                        no_precise_pin: ref __binding_1 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for CodegenRetagOptions {
            fn decode(__decoder: &mut __D) -> Self {
                CodegenRetagOptions {
                    no_precise_im: ::rustc_serialize::Decodable::decode(__decoder),
                    no_precise_pin: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable)]
205pub struct CodegenRetagOptions {
206    /// Track interior mutable data on the level of references, instead of on the byte level.
207    pub no_precise_im: bool,
208    /// Track `UnsafePinned` data on the level of references, instead of on the byte level.
209    pub no_precise_pin: bool,
210}
211
212/// The different settings that the `-Z autodiff` flag can have.
213#[derive(#[automatically_derived]
impl ::core::clone::Clone for AutoDiff {
    #[inline]
    fn clone(&self) -> AutoDiff {
        match self {
            AutoDiff::Enable => AutoDiff::Enable,
            AutoDiff::PrintTA => AutoDiff::PrintTA,
            AutoDiff::PrintTAFn(__self_0) =>
                AutoDiff::PrintTAFn(::core::clone::Clone::clone(__self_0)),
            AutoDiff::PrintAA => AutoDiff::PrintAA,
            AutoDiff::PrintPerf => AutoDiff::PrintPerf,
            AutoDiff::PrintSteps => AutoDiff::PrintSteps,
            AutoDiff::PrintModBefore => AutoDiff::PrintModBefore,
            AutoDiff::PrintModAfter => AutoDiff::PrintModAfter,
            AutoDiff::PrintModFinal => AutoDiff::PrintModFinal,
            AutoDiff::PrintPasses => AutoDiff::PrintPasses,
            AutoDiff::NoPostopt => AutoDiff::NoPostopt,
            AutoDiff::LooseTypes => AutoDiff::LooseTypes,
            AutoDiff::Inline => AutoDiff::Inline,
            AutoDiff::NoTT => AutoDiff::NoTT,
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for AutoDiff {
    #[inline]
    fn eq(&self, other: &AutoDiff) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (AutoDiff::PrintTAFn(__self_0), AutoDiff::PrintTAFn(__arg1_0))
                    => __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for AutoDiff {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            AutoDiff::PrintTAFn(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for AutoDiff {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            AutoDiff::Enable =>
                ::core::fmt::Formatter::write_str(f, "Enable"),
            AutoDiff::PrintTA =>
                ::core::fmt::Formatter::write_str(f, "PrintTA"),
            AutoDiff::PrintTAFn(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "PrintTAFn", &__self_0),
            AutoDiff::PrintAA =>
                ::core::fmt::Formatter::write_str(f, "PrintAA"),
            AutoDiff::PrintPerf =>
                ::core::fmt::Formatter::write_str(f, "PrintPerf"),
            AutoDiff::PrintSteps =>
                ::core::fmt::Formatter::write_str(f, "PrintSteps"),
            AutoDiff::PrintModBefore =>
                ::core::fmt::Formatter::write_str(f, "PrintModBefore"),
            AutoDiff::PrintModAfter =>
                ::core::fmt::Formatter::write_str(f, "PrintModAfter"),
            AutoDiff::PrintModFinal =>
                ::core::fmt::Formatter::write_str(f, "PrintModFinal"),
            AutoDiff::PrintPasses =>
                ::core::fmt::Formatter::write_str(f, "PrintPasses"),
            AutoDiff::NoPostopt =>
                ::core::fmt::Formatter::write_str(f, "NoPostopt"),
            AutoDiff::LooseTypes =>
                ::core::fmt::Formatter::write_str(f, "LooseTypes"),
            AutoDiff::Inline =>
                ::core::fmt::Formatter::write_str(f, "Inline"),
            AutoDiff::NoTT => ::core::fmt::Formatter::write_str(f, "NoTT"),
        }
    }
}Debug, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for AutoDiff {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        AutoDiff::Enable => { 0usize }
                        AutoDiff::PrintTA => { 1usize }
                        AutoDiff::PrintTAFn(ref __binding_0) => { 2usize }
                        AutoDiff::PrintAA => { 3usize }
                        AutoDiff::PrintPerf => { 4usize }
                        AutoDiff::PrintSteps => { 5usize }
                        AutoDiff::PrintModBefore => { 6usize }
                        AutoDiff::PrintModAfter => { 7usize }
                        AutoDiff::PrintModFinal => { 8usize }
                        AutoDiff::PrintPasses => { 9usize }
                        AutoDiff::NoPostopt => { 10usize }
                        AutoDiff::LooseTypes => { 11usize }
                        AutoDiff::Inline => { 12usize }
                        AutoDiff::NoTT => { 13usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    AutoDiff::Enable => {}
                    AutoDiff::PrintTA => {}
                    AutoDiff::PrintTAFn(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    AutoDiff::PrintAA => {}
                    AutoDiff::PrintPerf => {}
                    AutoDiff::PrintSteps => {}
                    AutoDiff::PrintModBefore => {}
                    AutoDiff::PrintModAfter => {}
                    AutoDiff::PrintModFinal => {}
                    AutoDiff::PrintPasses => {}
                    AutoDiff::NoPostopt => {}
                    AutoDiff::LooseTypes => {}
                    AutoDiff::Inline => {}
                    AutoDiff::NoTT => {}
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for AutoDiff {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { AutoDiff::Enable }
                    1usize => { AutoDiff::PrintTA }
                    2usize => {
                        AutoDiff::PrintTAFn(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    3usize => { AutoDiff::PrintAA }
                    4usize => { AutoDiff::PrintPerf }
                    5usize => { AutoDiff::PrintSteps }
                    6usize => { AutoDiff::PrintModBefore }
                    7usize => { AutoDiff::PrintModAfter }
                    8usize => { AutoDiff::PrintModFinal }
                    9usize => { AutoDiff::PrintPasses }
                    10usize => { AutoDiff::NoPostopt }
                    11usize => { AutoDiff::LooseTypes }
                    12usize => { AutoDiff::Inline }
                    13usize => { AutoDiff::NoTT }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `AutoDiff`, expected 0..14, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable)]
214pub enum AutoDiff {
215    /// Enable the autodiff opt pipeline
216    Enable,
217
218    /// Print TypeAnalysis information
219    PrintTA,
220    /// Print TypeAnalysis information for a specific function
221    PrintTAFn(String),
222    /// Print ActivityAnalysis Information
223    PrintAA,
224    /// Print Performance Warnings from Enzyme
225    PrintPerf,
226    /// Print intermediate IR generation steps
227    PrintSteps,
228    /// Print the module, before running autodiff.
229    PrintModBefore,
230    /// Print the module after running autodiff.
231    PrintModAfter,
232    /// Print the module after running autodiff and optimizations.
233    PrintModFinal,
234
235    /// Print all passes scheduled by LLVM
236    PrintPasses,
237    /// Disable extra opt run after running autodiff
238    NoPostopt,
239    /// Enzyme's loose type debug helper (can cause incorrect gradients!!)
240    /// Usable in cases where Enzyme errors with `can not deduce type of X`.
241    LooseTypes,
242    /// Runs Enzyme's aggressive inlining
243    Inline,
244    /// Disable Type Tree
245    NoTT,
246}
247
248/// The different settings that the `-Z annotate-moves` flag can have.
249#[derive(#[automatically_derived]
impl ::core::clone::Clone for AnnotateMoves {
    #[inline]
    fn clone(&self) -> AnnotateMoves {
        let _: ::core::clone::AssertParamIsClone<Option<u64>>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for AnnotateMoves { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for AnnotateMoves {
    #[inline]
    fn eq(&self, other: &AnnotateMoves) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (AnnotateMoves::Enabled(__self_0),
                    AnnotateMoves::Enabled(__arg1_0)) => __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for AnnotateMoves {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            AnnotateMoves::Enabled(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for AnnotateMoves {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            AnnotateMoves::Disabled =>
                ::core::fmt::Formatter::write_str(f, "Disabled"),
            AnnotateMoves::Enabled(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Enabled", &__self_0),
        }
    }
}Debug)]
250pub enum AnnotateMoves {
251    /// `-Z annotate-moves=no` (or `off`, `false` etc.)
252    Disabled,
253    /// `-Z annotate-moves` or `-Z annotate-moves=yes` (use default size limit)
254    /// `-Z annotate-moves=SIZE` (use specified size limit)
255    Enabled(Option<u64>),
256}
257
258/// Settings for `-Z instrument-xray` flag.
259#[derive(#[automatically_derived]
impl ::core::clone::Clone for InstrumentXRay {
    #[inline]
    fn clone(&self) -> InstrumentXRay {
        let _: ::core::clone::AssertParamIsClone<bool>;
        let _: ::core::clone::AssertParamIsClone<Option<usize>>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for InstrumentXRay { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for InstrumentXRay {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["always", "never", "ignore_loops", "instruction_threshold",
                        "skip_entry", "skip_exit"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.always, &self.never, &self.ignore_loops,
                        &self.instruction_threshold, &self.skip_entry,
                        &&self.skip_exit];
        ::core::fmt::Formatter::debug_struct_fields_finish(f,
            "InstrumentXRay", names, values)
    }
}Debug, #[automatically_derived]
impl ::core::default::Default for InstrumentXRay {
    #[inline]
    fn default() -> InstrumentXRay {
        InstrumentXRay {
            always: ::core::default::Default::default(),
            never: ::core::default::Default::default(),
            ignore_loops: ::core::default::Default::default(),
            instruction_threshold: ::core::default::Default::default(),
            skip_entry: ::core::default::Default::default(),
            skip_exit: ::core::default::Default::default(),
        }
    }
}Default, #[automatically_derived]
impl ::core::cmp::PartialEq for InstrumentXRay {
    #[inline]
    fn eq(&self, other: &InstrumentXRay) -> bool {
        self.always == other.always && self.never == other.never &&
                        self.ignore_loops == other.ignore_loops &&
                    self.skip_entry == other.skip_entry &&
                self.skip_exit == other.skip_exit &&
            self.instruction_threshold == other.instruction_threshold
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for InstrumentXRay {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<bool>;
        let _: ::core::cmp::AssertParamIsEq<Option<usize>>;
    }
}Eq, #[automatically_derived]
impl ::core::hash::Hash for InstrumentXRay {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.always, state);
        ::core::hash::Hash::hash(&self.never, state);
        ::core::hash::Hash::hash(&self.ignore_loops, state);
        ::core::hash::Hash::hash(&self.instruction_threshold, state);
        ::core::hash::Hash::hash(&self.skip_entry, state);
        ::core::hash::Hash::hash(&self.skip_exit, state)
    }
}Hash)]
260pub struct InstrumentXRay {
261    /// `-Z instrument-xray=always`, force instrumentation
262    pub always: bool,
263    /// `-Z instrument-xray=never`, disable instrumentation
264    pub never: bool,
265    /// `-Z instrument-xray=ignore-loops`, ignore presence of loops,
266    /// instrument functions based only on instruction count
267    pub ignore_loops: bool,
268    /// `-Z instrument-xray=instruction-threshold=N`, explicitly set instruction threshold
269    /// for instrumentation, or `None` to use compiler's default
270    pub instruction_threshold: Option<usize>,
271    /// `-Z instrument-xray=skip-entry`, do not instrument function entry
272    pub skip_entry: bool,
273    /// `-Z instrument-xray=skip-exit`, do not instrument function exit
274    pub skip_exit: bool,
275}
276
277#[derive(#[automatically_derived]
impl ::core::clone::Clone for LinkerPluginLto {
    #[inline]
    fn clone(&self) -> LinkerPluginLto {
        match self {
            LinkerPluginLto::LinkerPlugin(__self_0) =>
                LinkerPluginLto::LinkerPlugin(::core::clone::Clone::clone(__self_0)),
            LinkerPluginLto::LinkerPluginAuto =>
                LinkerPluginLto::LinkerPluginAuto,
            LinkerPluginLto::Disabled => LinkerPluginLto::Disabled,
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for LinkerPluginLto {
    #[inline]
    fn eq(&self, other: &LinkerPluginLto) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (LinkerPluginLto::LinkerPlugin(__self_0),
                    LinkerPluginLto::LinkerPlugin(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for LinkerPluginLto {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            LinkerPluginLto::LinkerPlugin(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for LinkerPluginLto {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            LinkerPluginLto::LinkerPlugin(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "LinkerPlugin", &__self_0),
            LinkerPluginLto::LinkerPluginAuto =>
                ::core::fmt::Formatter::write_str(f, "LinkerPluginAuto"),
            LinkerPluginLto::Disabled =>
                ::core::fmt::Formatter::write_str(f, "Disabled"),
        }
    }
}Debug)]
278pub enum LinkerPluginLto {
279    LinkerPlugin(PathBuf),
280    LinkerPluginAuto,
281    Disabled,
282}
283
284impl LinkerPluginLto {
285    pub fn enabled(&self) -> bool {
286        match *self {
287            LinkerPluginLto::LinkerPlugin(_) | LinkerPluginLto::LinkerPluginAuto => true,
288            LinkerPluginLto::Disabled => false,
289        }
290    }
291}
292
293/// The different values `-C link-self-contained` can take: a list of individually enabled or
294/// disabled components used during linking, coming from the rustc distribution, instead of being
295/// found somewhere on the host system.
296///
297/// They can be set in bulk via `-C link-self-contained=yes|y|on` or `-C
298/// link-self-contained=no|n|off`, and those boolean values are the historical defaults.
299///
300/// But each component is fine-grained, and can be unstably targeted, to use:
301/// - some CRT objects
302/// - the libc static library
303/// - libgcc/libunwind libraries
304/// - a linker we distribute
305/// - some sanitizer runtime libraries
306/// - all other MinGW libraries and Windows import libs
307///
308#[derive(#[automatically_derived]
impl ::core::default::Default for LinkSelfContained {
    #[inline]
    fn default() -> LinkSelfContained {
        LinkSelfContained {
            explicitly_set: ::core::default::Default::default(),
            enabled_components: ::core::default::Default::default(),
            disabled_components: ::core::default::Default::default(),
        }
    }
}Default, #[automatically_derived]
impl ::core::clone::Clone for LinkSelfContained {
    #[inline]
    fn clone(&self) -> LinkSelfContained {
        LinkSelfContained {
            explicitly_set: ::core::clone::Clone::clone(&self.explicitly_set),
            enabled_components: ::core::clone::Clone::clone(&self.enabled_components),
            disabled_components: ::core::clone::Clone::clone(&self.disabled_components),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for LinkSelfContained {
    #[inline]
    fn eq(&self, other: &LinkSelfContained) -> bool {
        self.explicitly_set == other.explicitly_set &&
                self.enabled_components == other.enabled_components &&
            self.disabled_components == other.disabled_components
    }
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for LinkSelfContained {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "LinkSelfContained", "explicitly_set", &self.explicitly_set,
            "enabled_components", &self.enabled_components,
            "disabled_components", &&self.disabled_components)
    }
}Debug)]
309pub struct LinkSelfContained {
310    /// Whether the user explicitly set `-C link-self-contained` on or off, the historical values.
311    /// Used for compatibility with the existing opt-in and target inference.
312    pub explicitly_set: Option<bool>,
313
314    /// The components that are enabled on the CLI, using the `+component` syntax or one of the
315    /// `true` shortcuts.
316    enabled_components: LinkSelfContainedComponents,
317
318    /// The components that are disabled on the CLI, using the `-component` syntax or one of the
319    /// `false` shortcuts.
320    disabled_components: LinkSelfContainedComponents,
321}
322
323impl LinkSelfContained {
324    /// Incorporates an enabled or disabled component as specified on the CLI, if possible.
325    /// For example: `+linker`, and `-crto`.
326    pub(crate) fn handle_cli_component(&mut self, component: &str) -> Option<()> {
327        // Note that for example `-Cself-contained=y -Cself-contained=-linker` is not an explicit
328        // set of all values like `y` or `n` used to be. Therefore, if this flag had previously been
329        // set in bulk with its historical values, then manually setting a component clears that
330        // `explicitly_set` state.
331        if let Some(component_to_enable) = component.strip_prefix('+') {
332            self.explicitly_set = None;
333            self.enabled_components
334                .insert(LinkSelfContainedComponents::from_str(component_to_enable).ok()?);
335            Some(())
336        } else if let Some(component_to_disable) = component.strip_prefix('-') {
337            self.explicitly_set = None;
338            self.disabled_components
339                .insert(LinkSelfContainedComponents::from_str(component_to_disable).ok()?);
340            Some(())
341        } else {
342            None
343        }
344    }
345
346    /// Turns all components on or off and records that this was done explicitly for compatibility
347    /// purposes.
348    pub(crate) fn set_all_explicitly(&mut self, enabled: bool) {
349        self.explicitly_set = Some(enabled);
350
351        if enabled {
352            self.enabled_components = LinkSelfContainedComponents::all();
353            self.disabled_components = LinkSelfContainedComponents::empty();
354        } else {
355            self.enabled_components = LinkSelfContainedComponents::empty();
356            self.disabled_components = LinkSelfContainedComponents::all();
357        }
358    }
359
360    /// Helper creating a fully enabled `LinkSelfContained` instance. Used in tests.
361    pub fn on() -> Self {
362        let mut on = LinkSelfContained::default();
363        on.set_all_explicitly(true);
364        on
365    }
366
367    /// To help checking CLI usage while some of the values are unstable: returns whether one of the
368    /// unstable components was set individually, for the given `TargetTuple`. This would also
369    /// require the `-Zunstable-options` flag, to be allowed.
370    fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
371        if self.explicitly_set.is_some() {
372            return Ok(());
373        }
374
375        // `-C link-self-contained=-linker` is only stable on x64 linux.
376        let has_minus_linker = self.disabled_components.is_linker_enabled();
377        if has_minus_linker && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
378            return Err(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`-C link-self-contained=-linker` is unstable on the `{0}` target. The `-Z unstable-options` flag must also be passed to use it on this target",
                target_tuple))
    })format!(
379                "`-C link-self-contained=-linker` is unstable on the `{target_tuple}` \
380                    target. The `-Z unstable-options` flag must also be passed to use it on this target",
381            ));
382        }
383
384        // Any `+linker` or other component used is unstable, and that's an error.
385        let unstable_enabled = self.enabled_components;
386        let unstable_disabled = self.disabled_components - LinkSelfContainedComponents::LINKER;
387        if !unstable_enabled.union(unstable_disabled).is_empty() {
388            return Err(String::from(
389                "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` \
390                are stable, the `-Z unstable-options` flag must also be passed to use \
391                the unstable values",
392            ));
393        }
394
395        Ok(())
396    }
397
398    /// Returns whether the self-contained linker component was enabled on the CLI, using the
399    /// `-C link-self-contained=+linker` syntax, or one of the `true` shortcuts.
400    pub fn is_linker_enabled(&self) -> bool {
401        self.enabled_components.contains(LinkSelfContainedComponents::LINKER)
402    }
403
404    /// Returns whether the self-contained linker component was disabled on the CLI, using the
405    /// `-C link-self-contained=-linker` syntax, or one of the `false` shortcuts.
406    pub fn is_linker_disabled(&self) -> bool {
407        self.disabled_components.contains(LinkSelfContainedComponents::LINKER)
408    }
409
410    /// Returns CLI inconsistencies to emit errors: individual components were both enabled and
411    /// disabled.
412    fn check_consistency(&self) -> Option<LinkSelfContainedComponents> {
413        if self.explicitly_set.is_some() {
414            None
415        } else {
416            let common = self.enabled_components.intersection(self.disabled_components);
417            if common.is_empty() { None } else { Some(common) }
418        }
419    }
420}
421
422/// The different values that `-C linker-features` can take on the CLI: a list of individually
423/// enabled or disabled features used during linking.
424///
425/// There is no need to enable or disable them in bulk. Each feature is fine-grained, and can be
426/// used to turn `LinkerFeatures` on or off, without needing to change the linker flavor:
427/// - using the system lld, or the self-contained `rust-lld` linker
428/// - using a C/C++ compiler to drive the linker (not yet exposed on the CLI)
429/// - etc.
430#[derive(#[automatically_derived]
impl ::core::default::Default for LinkerFeaturesCli {
    #[inline]
    fn default() -> LinkerFeaturesCli {
        LinkerFeaturesCli {
            enabled: ::core::default::Default::default(),
            disabled: ::core::default::Default::default(),
        }
    }
}Default, #[automatically_derived]
impl ::core::marker::Copy for LinkerFeaturesCli { }Copy, #[automatically_derived]
impl ::core::clone::Clone for LinkerFeaturesCli {
    #[inline]
    fn clone(&self) -> LinkerFeaturesCli {
        let _: ::core::clone::AssertParamIsClone<LinkerFeatures>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for LinkerFeaturesCli {
    #[inline]
    fn eq(&self, other: &LinkerFeaturesCli) -> bool {
        self.enabled == other.enabled && self.disabled == other.disabled
    }
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for LinkerFeaturesCli {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "LinkerFeaturesCli", "enabled", &self.enabled, "disabled",
            &&self.disabled)
    }
}Debug)]
431pub struct LinkerFeaturesCli {
432    /// The linker features that are enabled on the CLI, using the `+feature` syntax.
433    pub enabled: LinkerFeatures,
434
435    /// The linker features that are disabled on the CLI, using the `-feature` syntax.
436    pub disabled: LinkerFeatures,
437}
438
439impl LinkerFeaturesCli {
440    /// Accumulates an enabled or disabled feature as specified on the CLI, if possible.
441    /// For example: `+lld`, and `-lld`.
442    pub(crate) fn handle_cli_feature(&mut self, feature: &str) -> Option<()> {
443        // Duplicate flags are reduced as we go, the last occurrence wins:
444        // `+feature,-feature,+feature` only enables the feature, and does not record it as both
445        // enabled and disabled on the CLI.
446        // We also only expose `+/-lld` at the moment, as it's currently the only implemented linker
447        // feature and toggling `LinkerFeatures::CC` would be a noop.
448        match feature {
449            "+lld" => {
450                self.enabled.insert(LinkerFeatures::LLD);
451                self.disabled.remove(LinkerFeatures::LLD);
452                Some(())
453            }
454            "-lld" => {
455                self.disabled.insert(LinkerFeatures::LLD);
456                self.enabled.remove(LinkerFeatures::LLD);
457                Some(())
458            }
459            _ => None,
460        }
461    }
462
463    /// When *not* using `-Z unstable-options` on the CLI, ensure only stable linker features are
464    /// used, for the given `TargetTuple`. Returns `Ok` if no unstable variants are used.
465    /// The caller should ensure that e.g. `nightly_options::is_unstable_enabled()`
466    /// returns false.
467    pub(crate) fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
468        // `-C linker-features=-lld` is only stable on x64 linux.
469        let has_minus_lld = self.disabled.is_lld_enabled();
470        if has_minus_lld && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
471            return Err(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`-C linker-features=-lld` is unstable on the `{0}` target. The `-Z unstable-options` flag must also be passed to use it on this target",
                target_tuple))
    })format!(
472                "`-C linker-features=-lld` is unstable on the `{target_tuple}` \
473                    target. The `-Z unstable-options` flag must also be passed to use it on this target",
474            ));
475        }
476
477        // Any `+lld` or non-lld feature used is unstable, and that's an error.
478        let unstable_enabled = self.enabled;
479        let unstable_disabled = self.disabled - LinkerFeatures::LLD;
480        if !unstable_enabled.union(unstable_disabled).is_empty() {
481            let unstable_features: Vec<_> = unstable_enabled
482                .iter()
483                .map(|f| ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("+{0}", f.as_str().unwrap()))
    })format!("+{}", f.as_str().unwrap()))
484                .chain(unstable_disabled.iter().map(|f| ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("-{0}", f.as_str().unwrap()))
    })format!("-{}", f.as_str().unwrap())))
485                .collect();
486            return Err(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`-C linker-features={0}` is unstable, and also requires the `-Z unstable-options` flag to be used",
                unstable_features.join(",")))
    })format!(
487                "`-C linker-features={}` is unstable, and also requires the \
488                `-Z unstable-options` flag to be used",
489                unstable_features.join(","),
490            ));
491        }
492
493        Ok(())
494    }
495}
496
497/// Used with `-Z assert-incr-state`.
498#[derive(#[automatically_derived]
impl ::core::clone::Clone for IncrementalStateAssertion {
    #[inline]
    fn clone(&self) -> IncrementalStateAssertion { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for IncrementalStateAssertion { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for IncrementalStateAssertion {
    #[inline]
    fn eq(&self, other: &IncrementalStateAssertion) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for IncrementalStateAssertion {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for IncrementalStateAssertion {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                IncrementalStateAssertion::Loaded => "Loaded",
                IncrementalStateAssertion::NotLoaded => "NotLoaded",
            })
    }
}Debug)]
499pub enum IncrementalStateAssertion {
500    /// Found and loaded an existing session directory.
501    ///
502    /// Note that this says nothing about whether any particular query
503    /// will be found to be red or green.
504    Loaded,
505    /// Did not load an existing session directory.
506    NotLoaded,
507}
508
509/// The different settings that can be enabled via the `-Z location-detail` flag.
510#[derive(#[automatically_derived]
impl ::core::marker::Copy for LocationDetail { }Copy, #[automatically_derived]
impl ::core::clone::Clone for LocationDetail {
    #[inline]
    fn clone(&self) -> LocationDetail {
        let _: ::core::clone::AssertParamIsClone<bool>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for LocationDetail {
    #[inline]
    fn eq(&self, other: &LocationDetail) -> bool {
        self.file == other.file && self.line == other.line &&
            self.column == other.column
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for LocationDetail {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.file, state);
        ::core::hash::Hash::hash(&self.line, state);
        ::core::hash::Hash::hash(&self.column, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for LocationDetail {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "LocationDetail", "file", &self.file, "line", &self.line,
            "column", &&self.column)
    }
}Debug)]
511pub struct LocationDetail {
512    pub file: bool,
513    pub line: bool,
514    pub column: bool,
515}
516
517impl LocationDetail {
518    pub(crate) fn all() -> Self {
519        Self { file: true, line: true, column: true }
520    }
521}
522
523/// Values for the `-Z fmt-debug` flag.
524#[derive(#[automatically_derived]
impl ::core::marker::Copy for FmtDebug { }Copy, #[automatically_derived]
impl ::core::clone::Clone for FmtDebug {
    #[inline]
    fn clone(&self) -> FmtDebug { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for FmtDebug {
    #[inline]
    fn eq(&self, other: &FmtDebug) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for FmtDebug {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for FmtDebug {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                FmtDebug::Full => "Full",
                FmtDebug::Shallow => "Shallow",
                FmtDebug::None => "None",
            })
    }
}Debug)]
525pub enum FmtDebug {
526    /// Derive fully-featured implementation
527    Full,
528    /// Print only type name, without fields
529    Shallow,
530    /// `#[derive(Debug)]` and `{:?}` are no-ops
531    None,
532}
533
534impl FmtDebug {
535    pub(crate) fn all() -> [Symbol; 3] {
536        [sym::full, sym::none, sym::shallow]
537    }
538}
539
540#[derive(#[automatically_derived]
impl ::core::clone::Clone for SwitchWithOptPath {
    #[inline]
    fn clone(&self) -> SwitchWithOptPath {
        match self {
            SwitchWithOptPath::Enabled(__self_0) =>
                SwitchWithOptPath::Enabled(::core::clone::Clone::clone(__self_0)),
            SwitchWithOptPath::Disabled => SwitchWithOptPath::Disabled,
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for SwitchWithOptPath {
    #[inline]
    fn eq(&self, other: &SwitchWithOptPath) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (SwitchWithOptPath::Enabled(__self_0),
                    SwitchWithOptPath::Enabled(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for SwitchWithOptPath {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            SwitchWithOptPath::Enabled(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for SwitchWithOptPath {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            SwitchWithOptPath::Enabled(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Enabled", &__self_0),
            SwitchWithOptPath::Disabled =>
                ::core::fmt::Formatter::write_str(f, "Disabled"),
        }
    }
}Debug, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for SwitchWithOptPath {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        SwitchWithOptPath::Enabled(ref __binding_0) => { 0usize }
                        SwitchWithOptPath::Disabled => { 1usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    SwitchWithOptPath::Enabled(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    SwitchWithOptPath::Disabled => {}
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for SwitchWithOptPath {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        SwitchWithOptPath::Enabled(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => { SwitchWithOptPath::Disabled }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `SwitchWithOptPath`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable)]
541pub enum SwitchWithOptPath {
542    Enabled(Option<PathBuf>),
543    Disabled,
544}
545
546impl SwitchWithOptPath {
547    pub fn enabled(&self) -> bool {
548        match *self {
549            SwitchWithOptPath::Enabled(_) => true,
550            SwitchWithOptPath::Disabled => false,
551        }
552    }
553}
554
555#[derive(#[automatically_derived]
impl ::core::marker::Copy for SymbolManglingVersion { }Copy, #[automatically_derived]
impl ::core::clone::Clone for SymbolManglingVersion {
    #[inline]
    fn clone(&self) -> SymbolManglingVersion { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for SymbolManglingVersion {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                SymbolManglingVersion::Legacy => "Legacy",
                SymbolManglingVersion::V0 => "V0",
                SymbolManglingVersion::Hashed => "Hashed",
            })
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for SymbolManglingVersion {
    #[inline]
    fn eq(&self, other: &SymbolManglingVersion) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for SymbolManglingVersion {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for SymbolManglingVersion {
    #[inline]
    fn partial_cmp(&self, other: &SymbolManglingVersion)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for SymbolManglingVersion {
    #[inline]
    fn cmp(&self, other: &SymbolManglingVersion) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
    }
}Ord, #[automatically_derived]
impl ::core::hash::Hash for SymbolManglingVersion {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            SymbolManglingVersion {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    SymbolManglingVersion::Legacy => {}
                    SymbolManglingVersion::V0 => {}
                    SymbolManglingVersion::Hashed => {}
                }
            }
        }
    };StableHash)]
556#[derive(const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for SymbolManglingVersion {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        SymbolManglingVersion::Legacy => { 0usize }
                        SymbolManglingVersion::V0 => { 1usize }
                        SymbolManglingVersion::Hashed => { 2usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    SymbolManglingVersion::Legacy => {}
                    SymbolManglingVersion::V0 => {}
                    SymbolManglingVersion::Hashed => {}
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::BlobDecoder> ::rustc_serialize::Decodable<__D>
            for SymbolManglingVersion {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { SymbolManglingVersion::Legacy }
                    1usize => { SymbolManglingVersion::V0 }
                    2usize => { SymbolManglingVersion::Hashed }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `SymbolManglingVersion`, expected 0..3, actual {0}",
                                n));
                    }
                }
            }
        }
    };BlobDecodable)]
557pub enum SymbolManglingVersion {
558    Legacy,
559    V0,
560    Hashed,
561}
562
563#[derive(#[automatically_derived]
impl ::core::clone::Clone for DebugInfo {
    #[inline]
    fn clone(&self) -> DebugInfo { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for DebugInfo { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for DebugInfo {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                DebugInfo::None => "None",
                DebugInfo::LineDirectivesOnly => "LineDirectivesOnly",
                DebugInfo::LineTablesOnly => "LineTablesOnly",
                DebugInfo::Limited => "Limited",
                DebugInfo::Full => "Full",
            })
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for DebugInfo {
    #[inline]
    fn eq(&self, other: &DebugInfo) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for DebugInfo {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash)]
564pub enum DebugInfo {
565    None,
566    LineDirectivesOnly,
567    LineTablesOnly,
568    Limited,
569    Full,
570}
571
572#[derive(#[automatically_derived]
impl ::core::clone::Clone for DebugInfoCompression {
    #[inline]
    fn clone(&self) -> DebugInfoCompression { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for DebugInfoCompression { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for DebugInfoCompression {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                DebugInfoCompression::None => "None",
                DebugInfoCompression::Zlib => "Zlib",
                DebugInfoCompression::Zstd => "Zstd",
            })
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for DebugInfoCompression {
    #[inline]
    fn eq(&self, other: &DebugInfoCompression) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for DebugInfoCompression {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash)]
573pub enum DebugInfoCompression {
574    None,
575    Zlib,
576    Zstd,
577}
578
579#[derive(#[automatically_derived]
impl ::core::clone::Clone for MirStripDebugInfo {
    #[inline]
    fn clone(&self) -> MirStripDebugInfo { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for MirStripDebugInfo { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for MirStripDebugInfo {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                MirStripDebugInfo::None => "None",
                MirStripDebugInfo::LocalsInTinyFunctions =>
                    "LocalsInTinyFunctions",
                MirStripDebugInfo::AllLocals => "AllLocals",
            })
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for MirStripDebugInfo {
    #[inline]
    fn eq(&self, other: &MirStripDebugInfo) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for MirStripDebugInfo {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash)]
580pub enum MirStripDebugInfo {
581    None,
582    LocalsInTinyFunctions,
583    AllLocals,
584}
585
586/// Split debug-information is enabled by `-C split-debuginfo`, this enum is only used if split
587/// debug-information is enabled (in either `Packed` or `Unpacked` modes), and the platform
588/// uses DWARF for debug-information.
589///
590/// Some debug-information requires link-time relocation and some does not. LLVM can partition
591/// the debuginfo into sections depending on whether or not it requires link-time relocation. Split
592/// DWARF provides a mechanism which allows the linker to skip the sections which don't require
593/// link-time relocation - either by putting those sections in DWARF object files, or by keeping
594/// them in the object file in such a way that the linker will skip them.
595#[derive(#[automatically_derived]
impl ::core::clone::Clone for SplitDwarfKind {
    #[inline]
    fn clone(&self) -> SplitDwarfKind { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for SplitDwarfKind { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for SplitDwarfKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                SplitDwarfKind::Single => "Single",
                SplitDwarfKind::Split => "Split",
            })
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for SplitDwarfKind {
    #[inline]
    fn eq(&self, other: &SplitDwarfKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for SplitDwarfKind {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for SplitDwarfKind {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        SplitDwarfKind::Single => { 0usize }
                        SplitDwarfKind::Split => { 1usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    SplitDwarfKind::Single => {}
                    SplitDwarfKind::Split => {}
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for SplitDwarfKind {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { SplitDwarfKind::Single }
                    1usize => { SplitDwarfKind::Split }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `SplitDwarfKind`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable)]
596pub enum SplitDwarfKind {
597    /// Sections which do not require relocation are written into object file but ignored by the
598    /// linker.
599    Single,
600    /// Sections which do not require relocation are written into a DWARF object (`.dwo`) file
601    /// which is ignored by the linker.
602    Split,
603}
604
605impl FromStr for SplitDwarfKind {
606    type Err = ();
607
608    fn from_str(s: &str) -> Result<Self, ()> {
609        Ok(match s {
610            "single" => SplitDwarfKind::Single,
611            "split" => SplitDwarfKind::Split,
612            _ => return Err(()),
613        })
614    }
615}
616
617macro_rules! define_output_types {
618    (
619        $(
620            $(#[doc = $doc:expr])*
621            $Variant:ident => {
622                shorthand: $shorthand:expr,
623                extension: $extension:expr,
624                description: $description:expr,
625                default_filename: $default_filename:expr,
626                is_text: $is_text:expr,
627                compatible_with_cgus_and_single_output: $compatible:expr
628            }
629        ),* $(,)?
630    ) => {
631        #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, StableHash)]
632        #[derive(Encodable, Decodable)]
633        pub enum OutputType {
634            $(
635                $(#[doc = $doc])*
636                $Variant,
637            )*
638        }
639
640        impl StableOrd for OutputType {
641            const CAN_USE_UNSTABLE_SORT: bool = true;
642
643            // Trivial C-Style enums have a stable sort order across compilation sessions.
644            const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
645        }
646
647        impl OutputType {
648            pub fn iter_all() -> impl Iterator<Item = OutputType> {
649                static ALL_VARIANTS: &[OutputType] = &[
650                    $(
651                        OutputType::$Variant,
652                    )*
653                ];
654                ALL_VARIANTS.iter().copied()
655            }
656
657            fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool {
658                match *self {
659                    $(
660                        OutputType::$Variant => $compatible,
661                    )*
662                }
663            }
664
665            pub fn shorthand(&self) -> &'static str {
666                match *self {
667                    $(
668                        OutputType::$Variant => $shorthand,
669                    )*
670                }
671            }
672
673            fn from_shorthand(shorthand: &str) -> Option<Self> {
674                match shorthand {
675                    $(
676                        s if s == $shorthand => Some(OutputType::$Variant),
677                    )*
678                    _ => None,
679                }
680            }
681
682            fn shorthands_display() -> String {
683                let shorthands = vec![
684                    $(
685                        format!("`{}`", $shorthand),
686                    )*
687                ];
688                shorthands.join(", ")
689            }
690
691            pub fn extension(&self) -> &'static str {
692                match *self {
693                    $(
694                        OutputType::$Variant => $extension,
695                    )*
696                }
697            }
698
699            pub fn is_text_output(&self) -> bool {
700                match *self {
701                    $(
702                        OutputType::$Variant => $is_text,
703                    )*
704                }
705            }
706
707            pub fn description(&self) -> &'static str {
708                match *self {
709                    $(
710                        OutputType::$Variant => $description,
711                    )*
712                }
713            }
714
715            pub fn default_filename(&self) -> &'static str {
716                match *self {
717                    $(
718                        OutputType::$Variant => $default_filename,
719                    )*
720                }
721            }
722
723
724        }
725    }
726}
727
728#[automatically_derived]
impl ::core::clone::Clone for OutputType {
    #[inline]
    fn clone(&self) -> OutputType { *self }
}
#[automatically_derived]
impl ::core::marker::Copy for OutputType { }
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for OutputType { }
#[automatically_derived]
impl ::core::cmp::PartialEq for OutputType {
    #[inline]
    fn eq(&self, other: &OutputType) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}
#[automatically_derived]
impl ::core::cmp::Eq for OutputType {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}
#[automatically_derived]
impl ::core::hash::Hash for OutputType {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}
#[automatically_derived]
impl ::core::fmt::Debug for OutputType {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                OutputType::Assembly => "Assembly",
                OutputType::Bitcode => "Bitcode",
                OutputType::DepInfo => "DepInfo",
                OutputType::Exe => "Exe",
                OutputType::LlvmAssembly => "LlvmAssembly",
                OutputType::Metadata => "Metadata",
                OutputType::Mir => "Mir",
                OutputType::Object => "Object",
                OutputType::ThinLinkBitcode => "ThinLinkBitcode",
            })
    }
}
#[automatically_derived]
impl ::core::cmp::PartialOrd for OutputType {
    #[inline]
    fn partial_cmp(&self, other: &OutputType)
        -> ::core::option::Option<::core::cmp::Ordering> {
        ::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
    }
}
#[automatically_derived]
impl ::core::cmp::Ord for OutputType {
    #[inline]
    fn cmp(&self, other: &OutputType) -> ::core::cmp::Ordering {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        ::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
    }
}
const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for OutputType {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    OutputType::Assembly => {}
                    OutputType::Bitcode => {}
                    OutputType::DepInfo => {}
                    OutputType::Exe => {}
                    OutputType::LlvmAssembly => {}
                    OutputType::Metadata => {}
                    OutputType::Mir => {}
                    OutputType::Object => {}
                    OutputType::ThinLinkBitcode => {}
                }
            }
        }
    };
impl StableOrd for OutputType {
    const CAN_USE_UNSTABLE_SORT: bool = true;
    const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}
impl OutputType {
    pub fn iter_all() -> impl Iterator<Item = OutputType> {
        static ALL_VARIANTS: &[OutputType] =
            &[OutputType::Assembly, OutputType::Bitcode, OutputType::DepInfo,
                        OutputType::Exe, OutputType::LlvmAssembly,
                        OutputType::Metadata, OutputType::Mir, OutputType::Object,
                        OutputType::ThinLinkBitcode];
        ALL_VARIANTS.iter().copied()
    }
    fn is_compatible_with_codegen_units_and_single_output_file(&self)
        -> bool {
        match *self {
            OutputType::Assembly => false,
            OutputType::Bitcode => false,
            OutputType::DepInfo => true,
            OutputType::Exe => true,
            OutputType::LlvmAssembly => false,
            OutputType::Metadata => true,
            OutputType::Mir => false,
            OutputType::Object => false,
            OutputType::ThinLinkBitcode => false,
        }
    }
    pub fn shorthand(&self) -> &'static str {
        match *self {
            OutputType::Assembly => "asm",
            OutputType::Bitcode => "llvm-bc",
            OutputType::DepInfo => "dep-info",
            OutputType::Exe => "link",
            OutputType::LlvmAssembly => "llvm-ir",
            OutputType::Metadata => "metadata",
            OutputType::Mir => "mir",
            OutputType::Object => "obj",
            OutputType::ThinLinkBitcode => "thin-link-bitcode",
        }
    }
    fn from_shorthand(shorthand: &str) -> Option<Self> {
        match shorthand {
            s if s == "asm" => Some(OutputType::Assembly),
            s if s == "llvm-bc" => Some(OutputType::Bitcode),
            s if s == "dep-info" => Some(OutputType::DepInfo),
            s if s == "link" => Some(OutputType::Exe),
            s if s == "llvm-ir" => Some(OutputType::LlvmAssembly),
            s if s == "metadata" => Some(OutputType::Metadata),
            s if s == "mir" => Some(OutputType::Mir),
            s if s == "obj" => Some(OutputType::Object),
            s if s == "thin-link-bitcode" =>
                Some(OutputType::ThinLinkBitcode),
            _ => None,
        }
    }
    fn shorthands_display() -> String {
        let shorthands =
            ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
                    [::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("`{0}`", "asm"))
                                }),
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("`{0}`", "llvm-bc"))
                                }),
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("`{0}`", "dep-info"))
                                }),
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("`{0}`", "link"))
                                }),
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("`{0}`", "llvm-ir"))
                                }),
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("`{0}`", "metadata"))
                                }),
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("`{0}`", "mir"))
                                }),
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("`{0}`", "obj"))
                                }),
                            ::alloc::__export::must_use({
                                    ::alloc::fmt::format(format_args!("`{0}`",
                                            "thin-link-bitcode"))
                                })]));
        shorthands.join(", ")
    }
    pub fn extension(&self) -> &'static str {
        match *self {
            OutputType::Assembly => "s",
            OutputType::Bitcode => "bc",
            OutputType::DepInfo => "d",
            OutputType::Exe => "",
            OutputType::LlvmAssembly => "ll",
            OutputType::Metadata => "rmeta",
            OutputType::Mir => "mir",
            OutputType::Object => "o",
            OutputType::ThinLinkBitcode => "indexing.o",
        }
    }
    pub fn is_text_output(&self) -> bool {
        match *self {
            OutputType::Assembly => true,
            OutputType::Bitcode => false,
            OutputType::DepInfo => true,
            OutputType::Exe => false,
            OutputType::LlvmAssembly => true,
            OutputType::Metadata => false,
            OutputType::Mir => true,
            OutputType::Object => false,
            OutputType::ThinLinkBitcode => false,
        }
    }
    pub fn description(&self) -> &'static str {
        match *self {
            OutputType::Assembly =>
                "Generates a file with the crate's assembly code",
            OutputType::Bitcode =>
                "Generates a binary file containing the LLVM bitcode",
            OutputType::DepInfo =>
                "Generates a file with Makefile syntax that indicates all the source files that were loaded to generate the crate",
            OutputType::Exe =>
                "Generates the crates specified by --crate-type. This is the default if --emit is not specified",
            OutputType::LlvmAssembly => "Generates a file containing LLVM IR",
            OutputType::Metadata =>
                "Generates a file containing metadata about the crate",
            OutputType::Mir =>
                "Generates a file containing rustc's mid-level intermediate representation",
            OutputType::Object => "Generates a native object file",
            OutputType::ThinLinkBitcode =>
                "Generates the ThinLTO summary as bitcode",
        }
    }
    pub fn default_filename(&self) -> &'static str {
        match *self {
            OutputType::Assembly => "CRATE_NAME.s",
            OutputType::Bitcode => "CRATE_NAME.bc",
            OutputType::DepInfo => "CRATE_NAME.d",
            OutputType::Exe => "(platform and crate-type dependent)",
            OutputType::LlvmAssembly => "CRATE_NAME.ll",
            OutputType::Metadata => "libCRATE_NAME.rmeta",
            OutputType::Mir => "CRATE_NAME.mir",
            OutputType::Object => "CRATE_NAME.o",
            OutputType::ThinLinkBitcode => "CRATE_NAME.indexing.o",
        }
    }
}define_output_types! {
729    Assembly => {
730        shorthand: "asm",
731        extension: "s",
732        description: "Generates a file with the crate's assembly code",
733        default_filename: "CRATE_NAME.s",
734        is_text: true,
735        compatible_with_cgus_and_single_output: false
736    },
737    #[doc = "This is the optimized bitcode, which could be either pre-LTO or non-LTO bitcode,"]
738    #[doc = "depending on the specific request type."]
739    Bitcode => {
740        shorthand: "llvm-bc",
741        extension: "bc",
742        description: "Generates a binary file containing the LLVM bitcode",
743        default_filename: "CRATE_NAME.bc",
744        is_text: false,
745        compatible_with_cgus_and_single_output: false
746    },
747    DepInfo => {
748        shorthand: "dep-info",
749        extension: "d",
750        description: "Generates a file with Makefile syntax that indicates all the source files that were loaded to generate the crate",
751        default_filename: "CRATE_NAME.d",
752        is_text: true,
753        compatible_with_cgus_and_single_output: true
754    },
755    Exe => {
756        shorthand: "link",
757        extension: "",
758        description: "Generates the crates specified by --crate-type. This is the default if --emit is not specified",
759        default_filename: "(platform and crate-type dependent)",
760        is_text: false,
761        compatible_with_cgus_and_single_output: true
762    },
763    LlvmAssembly => {
764        shorthand: "llvm-ir",
765        extension: "ll",
766        description: "Generates a file containing LLVM IR",
767        default_filename: "CRATE_NAME.ll",
768        is_text: true,
769        compatible_with_cgus_and_single_output: false
770    },
771    Metadata => {
772        shorthand: "metadata",
773        extension: "rmeta",
774        description: "Generates a file containing metadata about the crate",
775        default_filename: "libCRATE_NAME.rmeta",
776        is_text: false,
777        compatible_with_cgus_and_single_output: true
778    },
779    Mir => {
780        shorthand: "mir",
781        extension: "mir",
782        description: "Generates a file containing rustc's mid-level intermediate representation",
783        default_filename: "CRATE_NAME.mir",
784        is_text: true,
785        compatible_with_cgus_and_single_output: false
786    },
787    Object => {
788        shorthand: "obj",
789        extension: "o",
790        description: "Generates a native object file",
791        default_filename: "CRATE_NAME.o",
792        is_text: false,
793        compatible_with_cgus_and_single_output: false
794    },
795    #[doc = "This is the summary or index data part of the ThinLTO bitcode."]
796    ThinLinkBitcode => {
797        shorthand: "thin-link-bitcode",
798        extension: "indexing.o",
799        description: "Generates the ThinLTO summary as bitcode",
800        default_filename: "CRATE_NAME.indexing.o",
801        is_text: false,
802        compatible_with_cgus_and_single_output: false
803    },
804}
805
806/// The type of diagnostics output to generate.
807#[derive(#[automatically_derived]
impl ::core::clone::Clone for ErrorOutputType {
    #[inline]
    fn clone(&self) -> ErrorOutputType {
        let _: ::core::clone::AssertParamIsClone<HumanReadableErrorType>;
        let _: ::core::clone::AssertParamIsClone<ColorConfig>;
        let _: ::core::clone::AssertParamIsClone<bool>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for ErrorOutputType { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for ErrorOutputType {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            ErrorOutputType::HumanReadable {
                kind: __self_0, color_config: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f,
                    "HumanReadable", "kind", __self_0, "color_config",
                    &__self_1),
            ErrorOutputType::Json {
                pretty: __self_0,
                json_rendered: __self_1,
                color_config: __self_2 } =>
                ::core::fmt::Formatter::debug_struct_field3_finish(f, "Json",
                    "pretty", __self_0, "json_rendered", __self_1,
                    "color_config", &__self_2),
        }
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for ErrorOutputType {
    #[inline]
    fn eq(&self, other: &ErrorOutputType) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (ErrorOutputType::HumanReadable {
                    kind: __self_0, color_config: __self_1 },
                    ErrorOutputType::HumanReadable {
                    kind: __arg1_0, color_config: __arg1_1 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1,
                (ErrorOutputType::Json {
                    pretty: __self_0,
                    json_rendered: __self_1,
                    color_config: __self_2 }, ErrorOutputType::Json {
                    pretty: __arg1_0,
                    json_rendered: __arg1_1,
                    color_config: __arg1_2 }) =>
                    __self_0 == __arg1_0 && __self_1 == __arg1_1 &&
                        __self_2 == __arg1_2,
                _ => unsafe { ::core::intrinsics::unreachable() }
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ErrorOutputType {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<HumanReadableErrorType>;
        let _: ::core::cmp::AssertParamIsEq<ColorConfig>;
        let _: ::core::cmp::AssertParamIsEq<bool>;
    }
}Eq, #[automatically_derived]
impl ::core::default::Default for ErrorOutputType {
    #[inline]
    fn default() -> ErrorOutputType {
        Self::HumanReadable {
            kind: const HumanReadableErrorType {
                        short: false,
                        unicode: false,
                    },
            color_config: const ColorConfig::Auto,
        }
    }
}Default)]
808pub enum ErrorOutputType {
809    /// Output meant for the consumption of humans.
810    #[default]
811    HumanReadable {
812        kind: HumanReadableErrorType = HumanReadableErrorType { short: false, unicode: false },
813        color_config: ColorConfig = ColorConfig::Auto,
814    },
815    /// Output that's consumed by other tools such as `rustfix` or the `RLS`.
816    Json {
817        /// Render the JSON in a human readable way (with indents and newlines).
818        pretty: bool,
819        /// The JSON output includes a `rendered` field that includes the rendered
820        /// human output.
821        json_rendered: HumanReadableErrorType,
822        color_config: ColorConfig,
823    },
824}
825
826#[derive(#[automatically_derived]
impl ::core::clone::Clone for ResolveDocLinks {
    #[inline]
    fn clone(&self) -> ResolveDocLinks {
        match self {
            ResolveDocLinks::None => ResolveDocLinks::None,
            ResolveDocLinks::ExportedMetadata =>
                ResolveDocLinks::ExportedMetadata,
            ResolveDocLinks::Exported => ResolveDocLinks::Exported,
            ResolveDocLinks::All => ResolveDocLinks::All,
        }
    }
}Clone, #[automatically_derived]
impl ::core::hash::Hash for ResolveDocLinks {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for ResolveDocLinks {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                ResolveDocLinks::None => "None",
                ResolveDocLinks::ExportedMetadata => "ExportedMetadata",
                ResolveDocLinks::Exported => "Exported",
                ResolveDocLinks::All => "All",
            })
    }
}Debug)]
827pub enum ResolveDocLinks {
828    /// Do not resolve doc links.
829    None,
830    /// Resolve doc links on exported items only for crate types that have metadata.
831    ExportedMetadata,
832    /// Resolve doc links on exported items.
833    Exported,
834    /// Resolve doc links on all items.
835    All,
836}
837
838/// Use tree-based collections to cheaply get a deterministic `Hash` implementation.
839/// *Do not* switch `BTreeMap` out for an unsorted container type! That would break
840/// dependency tracking for command-line arguments. Also only hash keys, since tracking
841/// should only depend on the output types, not the paths they're written to.
842#[derive(#[automatically_derived]
impl ::core::clone::Clone for OutputTypes {
    #[inline]
    fn clone(&self) -> OutputTypes {
        OutputTypes(::core::clone::Clone::clone(&self.0))
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for OutputTypes {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f, "OutputTypes",
            &&self.0)
    }
}Debug, #[automatically_derived]
impl ::core::hash::Hash for OutputTypes {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.0, state)
    }
}Hash, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for OutputTypes
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    OutputTypes(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for OutputTypes {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    OutputTypes(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for OutputTypes {
            fn decode(__decoder: &mut __D) -> Self {
                OutputTypes(::rustc_serialize::Decodable::decode(__decoder))
            }
        }
    };Decodable)]
843pub struct OutputTypes(BTreeMap<OutputType, Option<OutFileName>>);
844
845impl OutputTypes {
846    pub fn new(entries: &[(OutputType, Option<OutFileName>)]) -> OutputTypes {
847        OutputTypes(BTreeMap::from_iter(entries.iter().map(|&(k, ref v)| (k, v.clone()))))
848    }
849
850    pub(crate) fn get(&self, key: &OutputType) -> Option<&Option<OutFileName>> {
851        self.0.get(key)
852    }
853
854    pub fn contains_key(&self, key: &OutputType) -> bool {
855        self.0.contains_key(key)
856    }
857
858    /// Returns `true` if user specified a name and not just produced type
859    pub fn contains_explicit_name(&self, key: &OutputType) -> bool {
860        #[allow(non_exhaustive_omitted_patterns)] match self.0.get(key) {
    Some(Some(..)) => true,
    _ => false,
}matches!(self.0.get(key), Some(Some(..)))
861    }
862
863    pub fn iter(&self) -> BTreeMapIter<'_, OutputType, Option<OutFileName>> {
864        self.0.iter()
865    }
866
867    pub fn keys(&self) -> BTreeMapKeysIter<'_, OutputType, Option<OutFileName>> {
868        self.0.keys()
869    }
870
871    pub fn values(&self) -> BTreeMapValuesIter<'_, OutputType, Option<OutFileName>> {
872        self.0.values()
873    }
874
875    pub fn len(&self) -> usize {
876        self.0.len()
877    }
878
879    /// Returns `true` if any of the output types require codegen or linking.
880    pub fn should_codegen(&self) -> bool {
881        self.0.keys().any(|k| match *k {
882            OutputType::Bitcode
883            | OutputType::ThinLinkBitcode
884            | OutputType::Assembly
885            | OutputType::LlvmAssembly
886            | OutputType::Mir
887            | OutputType::Object
888            | OutputType::Exe => true,
889            OutputType::Metadata | OutputType::DepInfo => false,
890        })
891    }
892
893    /// Returns `true` if any of the output types require linking.
894    pub fn should_link(&self) -> bool {
895        self.0.keys().any(|k| match *k {
896            OutputType::Bitcode
897            | OutputType::ThinLinkBitcode
898            | OutputType::Assembly
899            | OutputType::LlvmAssembly
900            | OutputType::Mir
901            | OutputType::Metadata
902            | OutputType::Object
903            | OutputType::DepInfo => false,
904            OutputType::Exe => true,
905        })
906    }
907}
908
909/// Use tree-based collections to cheaply get a deterministic `Hash` implementation.
910/// *Do not* switch `BTreeMap` or `BTreeSet` out for an unsorted container type! That
911/// would break dependency tracking for command-line arguments.
912#[derive(#[automatically_derived]
impl ::core::clone::Clone for Externs {
    #[inline]
    fn clone(&self) -> Externs {
        Externs(::core::clone::Clone::clone(&self.0))
    }
}Clone)]
913pub struct Externs(BTreeMap<String, ExternEntry>);
914
915#[derive(#[automatically_derived]
impl ::core::clone::Clone for ExternEntry {
    #[inline]
    fn clone(&self) -> ExternEntry {
        ExternEntry {
            location: ::core::clone::Clone::clone(&self.location),
            is_private_dep: ::core::clone::Clone::clone(&self.is_private_dep),
            add_prelude: ::core::clone::Clone::clone(&self.add_prelude),
            nounused_dep: ::core::clone::Clone::clone(&self.nounused_dep),
            force: ::core::clone::Clone::clone(&self.force),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for ExternEntry {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field5_finish(f, "ExternEntry",
            "location", &self.location, "is_private_dep",
            &self.is_private_dep, "add_prelude", &self.add_prelude,
            "nounused_dep", &self.nounused_dep, "force", &&self.force)
    }
}Debug)]
916pub struct ExternEntry {
917    pub location: ExternLocation,
918    /// Indicates this is a "private" dependency for the
919    /// `exported_private_dependencies` lint.
920    ///
921    /// This can be set with the `priv` option like
922    /// `--extern priv:name=foo.rlib`.
923    pub is_private_dep: bool,
924    /// Add the extern entry to the extern prelude.
925    ///
926    /// This can be disabled with the `noprelude` option like
927    /// `--extern noprelude:name`.
928    pub add_prelude: bool,
929    /// The extern entry shouldn't be considered for unused dependency warnings.
930    ///
931    /// `--extern nounused:std=/path/to/lib/libstd.rlib`. This is used to
932    /// suppress `unused-crate-dependencies` warnings.
933    pub nounused_dep: bool,
934    /// If the extern entry is not referenced in the crate, force it to be resolved anyway.
935    ///
936    /// Allows a dependency satisfying, for instance, a missing panic handler to be injected
937    /// without modifying source:
938    /// `--extern force:extras=/path/to/lib/libstd.rlib`
939    pub force: bool,
940}
941
942#[derive(#[automatically_derived]
impl ::core::clone::Clone for ExternLocation {
    #[inline]
    fn clone(&self) -> ExternLocation {
        match self {
            ExternLocation::FoundInLibrarySearchDirectories =>
                ExternLocation::FoundInLibrarySearchDirectories,
            ExternLocation::ExactPaths(__self_0) =>
                ExternLocation::ExactPaths(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for ExternLocation {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            ExternLocation::FoundInLibrarySearchDirectories =>
                ::core::fmt::Formatter::write_str(f,
                    "FoundInLibrarySearchDirectories"),
            ExternLocation::ExactPaths(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "ExactPaths", &__self_0),
        }
    }
}Debug)]
943pub enum ExternLocation {
944    /// Indicates to look for the library in the search paths.
945    ///
946    /// Added via `--extern name`.
947    FoundInLibrarySearchDirectories,
948    /// The locations where this extern entry must be found.
949    ///
950    /// The `CrateLoader` is responsible for loading these and figuring out
951    /// which one to use.
952    ///
953    /// Added via `--extern prelude_name=some_file.rlib`
954    ExactPaths(BTreeSet<CanonicalizedPath>),
955}
956
957impl Externs {
958    /// Used for testing.
959    pub fn new(data: BTreeMap<String, ExternEntry>) -> Externs {
960        Externs(data)
961    }
962
963    pub fn get(&self, key: &str) -> Option<&ExternEntry> {
964        self.0.get(key)
965    }
966
967    pub fn iter(&self) -> BTreeMapIter<'_, String, ExternEntry> {
968        self.0.iter()
969    }
970}
971
972impl ExternEntry {
973    fn new(location: ExternLocation) -> ExternEntry {
974        ExternEntry {
975            location,
976            is_private_dep: false,
977            add_prelude: false,
978            nounused_dep: false,
979            force: false,
980        }
981    }
982
983    pub fn files(&self) -> Option<impl Iterator<Item = &CanonicalizedPath>> {
984        match &self.location {
985            ExternLocation::ExactPaths(set) => Some(set.iter()),
986            _ => None,
987        }
988    }
989}
990
991#[derive(#[automatically_derived]
impl ::core::fmt::Debug for NextSolverConfig {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "NextSolverConfig", "coherence", &self.coherence, "globally",
            &&self.globally)
    }
}Debug, #[automatically_derived]
impl ::core::marker::Copy for NextSolverConfig { }Copy, #[automatically_derived]
impl ::core::clone::Clone for NextSolverConfig {
    #[inline]
    fn clone(&self) -> NextSolverConfig {
        let _: ::core::clone::AssertParamIsClone<bool>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::hash::Hash for NextSolverConfig {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.coherence, state);
        ::core::hash::Hash::hash(&self.globally, state)
    }
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for NextSolverConfig {
    #[inline]
    fn eq(&self, other: &NextSolverConfig) -> bool {
        self.coherence == other.coherence && self.globally == other.globally
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for NextSolverConfig {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<bool>;
    }
}Eq, #[automatically_derived]
impl ::core::default::Default for NextSolverConfig {
    #[inline]
    fn default() -> NextSolverConfig {
        NextSolverConfig { coherence: const true, globally: const false }
    }
}Default)]
992pub struct NextSolverConfig {
993    /// Whether the new trait solver should be enabled in coherence.
994    pub coherence: bool = true,
995    /// Whether the new trait solver should be enabled everywhere.
996    /// This is only `true` if `coherence` is also enabled.
997    pub globally: bool = false,
998}
999
1000#[derive(#[automatically_derived]
impl ::core::clone::Clone for Input {
    #[inline]
    fn clone(&self) -> Input {
        match self {
            Input::File(__self_0) =>
                Input::File(::core::clone::Clone::clone(__self_0)),
            Input::Str { name: __self_0, input: __self_1 } =>
                Input::Str {
                    name: ::core::clone::Clone::clone(__self_0),
                    input: ::core::clone::Clone::clone(__self_1),
                },
        }
    }
}Clone)]
1001pub enum Input {
1002    /// Load source code from a file.
1003    File(PathBuf),
1004    /// Load source code from a string.
1005    Str {
1006        /// A string that is shown in place of a filename.
1007        name: FileName,
1008        /// An anonymous string containing the source code.
1009        input: String,
1010    },
1011}
1012
1013impl Input {
1014    pub fn filestem(&self) -> &str {
1015        if let Input::File(ifile) = self {
1016            // If for some reason getting the file stem as a UTF-8 string fails,
1017            // then fallback to a fixed name.
1018            if let Some(name) = ifile.file_stem().and_then(OsStr::to_str) {
1019                return name;
1020            }
1021        }
1022        "rust_out"
1023    }
1024
1025    pub fn file_name(&self, session: &Session) -> FileName {
1026        match *self {
1027            Input::File(ref ifile) => FileName::Real(
1028                session
1029                    .psess
1030                    .source_map()
1031                    .path_mapping()
1032                    .to_real_filename(session.psess.source_map().working_dir(), ifile.as_path()),
1033            ),
1034            Input::Str { ref name, .. } => name.clone(),
1035        }
1036    }
1037
1038    pub fn opt_path(&self) -> Option<&Path> {
1039        match self {
1040            Input::File(file) => Some(file),
1041            Input::Str { name, .. } => match name {
1042                FileName::Real(real) => real.local_path(),
1043                FileName::CfgSpec(_) => None,
1044                FileName::Anon(_) => None,
1045                FileName::MacroExpansion(_) => None,
1046                FileName::ProcMacroSourceCode(_) => None,
1047                FileName::CliCrateAttr(_) => None,
1048                FileName::Custom(_) => None,
1049                FileName::DocTest(path, _) => Some(path),
1050                FileName::InlineAsm(_) => None,
1051            },
1052        }
1053    }
1054}
1055
1056#[derive(#[automatically_derived]
impl ::core::clone::Clone for OutFileName {
    #[inline]
    fn clone(&self) -> OutFileName {
        match self {
            OutFileName::Real(__self_0) =>
                OutFileName::Real(::core::clone::Clone::clone(__self_0)),
            OutFileName::Stdout => OutFileName::Stdout,
        }
    }
}Clone, #[automatically_derived]
impl ::core::hash::Hash for OutFileName {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            OutFileName::Real(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for OutFileName {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            OutFileName::Real(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Real",
                    &__self_0),
            OutFileName::Stdout =>
                ::core::fmt::Formatter::write_str(f, "Stdout"),
        }
    }
}Debug, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for OutFileName
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    OutFileName::Real(ref __binding_0) => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                    OutFileName::Stdout => {}
                }
            }
        }
    };StableHash, #[automatically_derived]
impl ::core::cmp::PartialEq for OutFileName {
    #[inline]
    fn eq(&self, other: &OutFileName) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (OutFileName::Real(__self_0), OutFileName::Real(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for OutFileName {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<PathBuf>;
    }
}Eq, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for OutFileName {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        OutFileName::Real(ref __binding_0) => { 0usize }
                        OutFileName::Stdout => { 1usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    OutFileName::Real(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    OutFileName::Stdout => {}
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for OutFileName {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        OutFileName::Real(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => { OutFileName::Stdout }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `OutFileName`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable)]
1057pub enum OutFileName {
1058    Real(PathBuf),
1059    Stdout,
1060}
1061
1062impl OutFileName {
1063    pub fn parent(&self) -> Option<&Path> {
1064        match *self {
1065            OutFileName::Real(ref path) => path.parent(),
1066            OutFileName::Stdout => None,
1067        }
1068    }
1069
1070    pub fn filestem(&self) -> Option<&OsStr> {
1071        match *self {
1072            OutFileName::Real(ref path) => path.file_stem(),
1073            OutFileName::Stdout => Some(OsStr::new("stdout")),
1074        }
1075    }
1076
1077    pub fn is_stdout(&self) -> bool {
1078        match *self {
1079            OutFileName::Real(_) => false,
1080            OutFileName::Stdout => true,
1081        }
1082    }
1083
1084    pub fn is_tty(&self) -> bool {
1085        use std::io::IsTerminal;
1086        match *self {
1087            OutFileName::Real(_) => false,
1088            OutFileName::Stdout => std::io::stdout().is_terminal(),
1089        }
1090    }
1091
1092    pub fn as_path(&self) -> &Path {
1093        match *self {
1094            OutFileName::Real(ref path) => path.as_ref(),
1095            OutFileName::Stdout => Path::new("stdout"),
1096        }
1097    }
1098
1099    /// For a given output filename, return the actual name of the file that
1100    /// can be used to write codegen data of type `flavor`. For real-path
1101    /// output filenames, this would be trivial as we can just use the path.
1102    /// Otherwise for stdout, return a temporary path so that the codegen data
1103    /// may be later copied to stdout.
1104    pub fn file_for_writing(
1105        &self,
1106        outputs: &OutputFilenames,
1107        flavor: OutputType,
1108        codegen_unit_name: &str,
1109    ) -> PathBuf {
1110        match *self {
1111            OutFileName::Real(ref path) => path.clone(),
1112            OutFileName::Stdout => outputs.temp_path_for_cgu(flavor, codegen_unit_name),
1113        }
1114    }
1115
1116    pub fn overwrite(&self, content: &str, sess: &Session) {
1117        match self {
1118            OutFileName::Stdout => { ::std::io::_print(format_args!("{0}", content)); }print!("{content}"),
1119            OutFileName::Real(path) => {
1120                if let Err(e) = fs::write(path, content) {
1121                    sess.dcx().emit_fatal(FileWriteFail { path, err: e.to_string() });
1122                }
1123            }
1124        }
1125    }
1126}
1127
1128#[derive(#[automatically_derived]
impl ::core::clone::Clone for OutputFilenames {
    #[inline]
    fn clone(&self) -> OutputFilenames {
        OutputFilenames {
            out_directory: ::core::clone::Clone::clone(&self.out_directory),
            crate_stem: ::core::clone::Clone::clone(&self.crate_stem),
            filestem: ::core::clone::Clone::clone(&self.filestem),
            single_output_file: ::core::clone::Clone::clone(&self.single_output_file),
            temps_directory: ::core::clone::Clone::clone(&self.temps_directory),
            invocation_temp: ::core::clone::Clone::clone(&self.invocation_temp),
            explicit_dwo_out_directory: ::core::clone::Clone::clone(&self.explicit_dwo_out_directory),
            outputs: ::core::clone::Clone::clone(&self.outputs),
        }
    }
}Clone, #[automatically_derived]
impl ::core::hash::Hash for OutputFilenames {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.out_directory, state);
        ::core::hash::Hash::hash(&self.crate_stem, state);
        ::core::hash::Hash::hash(&self.filestem, state);
        ::core::hash::Hash::hash(&self.single_output_file, state);
        ::core::hash::Hash::hash(&self.temps_directory, state);
        ::core::hash::Hash::hash(&self.invocation_temp, state);
        ::core::hash::Hash::hash(&self.explicit_dwo_out_directory, state);
        ::core::hash::Hash::hash(&self.outputs, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for OutputFilenames {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        let names: &'static _ =
            &["out_directory", "crate_stem", "filestem", "single_output_file",
                        "temps_directory", "invocation_temp",
                        "explicit_dwo_out_directory", "outputs"];
        let values: &[&dyn ::core::fmt::Debug] =
            &[&self.out_directory, &self.crate_stem, &self.filestem,
                        &self.single_output_file, &self.temps_directory,
                        &self.invocation_temp, &self.explicit_dwo_out_directory,
                        &&self.outputs];
        ::core::fmt::Formatter::debug_struct_fields_finish(f,
            "OutputFilenames", names, values)
    }
}Debug, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for
            OutputFilenames {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                match *self {
                    OutputFilenames {
                        out_directory: ref __binding_0,
                        crate_stem: ref __binding_1,
                        filestem: ref __binding_2,
                        single_output_file: ref __binding_3,
                        temps_directory: ref __binding_4,
                        invocation_temp: ref __binding_5,
                        explicit_dwo_out_directory: ref __binding_6,
                        outputs: ref __binding_7 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                        { __binding_1.stable_hash(__hcx, __hasher); }
                        { __binding_2.stable_hash(__hcx, __hasher); }
                        { __binding_3.stable_hash(__hcx, __hasher); }
                        { __binding_4.stable_hash(__hcx, __hasher); }
                        {}
                        { __binding_6.stable_hash(__hcx, __hasher); }
                        { __binding_7.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for OutputFilenames {
            fn encode(&self, __encoder: &mut __E) {
                match *self {
                    OutputFilenames {
                        out_directory: ref __binding_0,
                        crate_stem: ref __binding_1,
                        filestem: ref __binding_2,
                        single_output_file: ref __binding_3,
                        temps_directory: ref __binding_4,
                        invocation_temp: ref __binding_5,
                        explicit_dwo_out_directory: ref __binding_6,
                        outputs: ref __binding_7 } => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_1,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_2,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_3,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_4,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_5,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_6,
                            __encoder);
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_7,
                            __encoder);
                    }
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for OutputFilenames {
            fn decode(__decoder: &mut __D) -> Self {
                OutputFilenames {
                    out_directory: ::rustc_serialize::Decodable::decode(__decoder),
                    crate_stem: ::rustc_serialize::Decodable::decode(__decoder),
                    filestem: ::rustc_serialize::Decodable::decode(__decoder),
                    single_output_file: ::rustc_serialize::Decodable::decode(__decoder),
                    temps_directory: ::rustc_serialize::Decodable::decode(__decoder),
                    invocation_temp: ::rustc_serialize::Decodable::decode(__decoder),
                    explicit_dwo_out_directory: ::rustc_serialize::Decodable::decode(__decoder),
                    outputs: ::rustc_serialize::Decodable::decode(__decoder),
                }
            }
        }
    };Decodable)]
1129pub struct OutputFilenames {
1130    pub(crate) out_directory: PathBuf,
1131    /// Crate name. Never contains '-'.
1132    crate_stem: String,
1133    /// Typically based on `.rs` input file name. Any '-' is preserved.
1134    filestem: String,
1135    pub single_output_file: Option<OutFileName>,
1136    temps_directory: Option<PathBuf>,
1137
1138    /// A random string generated per invocation of rustc.
1139    ///
1140    /// This is prepended to all temporary files so that they do not collide
1141    /// during concurrent invocations of rustc, or past invocations that were
1142    /// preserved with a flag like `-C save-temps`, since these files may be
1143    /// hard linked.
1144    // This does not affect incr comp outputs, only where temp files are stored.
1145    #[stable_hash(ignore)]
1146    invocation_temp: Option<String>,
1147
1148    explicit_dwo_out_directory: Option<PathBuf>,
1149    pub outputs: OutputTypes,
1150}
1151
1152pub const RLINK_EXT: &str = "rlink";
1153pub const RUST_CGU_EXT: &str = "rcgu";
1154pub const DWARF_OBJECT_EXT: &str = "dwo";
1155pub const MAX_FILENAME_LENGTH: usize = 143; // ecryptfs limits filenames to 143 bytes see #49914
1156
1157/// Ensure the filename is not too long, as some filesystems have a limit.
1158/// If the filename is too long, hash part of it and append the hash to the filename.
1159/// This is a workaround for long crate names generating overly long filenames.
1160fn maybe_strip_file_name(mut path: PathBuf) -> PathBuf {
1161    if path.file_name().map_or(0, |name| name.len()) > MAX_FILENAME_LENGTH {
1162        let filename = path.file_name().unwrap().to_string_lossy();
1163        let hash_len = 64 / 4; // Hash64 is 64 bits encoded in hex
1164        let hyphen_len = 1; // the '-' we insert between hash and suffix
1165
1166        // number of bytes of suffix we can keep so that "hash-<suffix>" fits
1167        let allowed_suffix = MAX_FILENAME_LENGTH.saturating_sub(hash_len + hyphen_len);
1168
1169        // number of bytes to remove from the start
1170        let stripped_bytes = filename.len().saturating_sub(allowed_suffix);
1171
1172        // ensure we don't cut in a middle of a char
1173        let split_at = filename.ceil_char_boundary(stripped_bytes);
1174
1175        let mut hasher = StableHasher::new();
1176        filename[..split_at].hash(&mut hasher);
1177        let hash = hasher.finish::<Hash64>();
1178
1179        path.set_file_name(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0:x}-{1}", hash,
                &filename[split_at..]))
    })format!("{:x}-{}", hash, &filename[split_at..]));
1180    }
1181    path
1182}
1183impl OutputFilenames {
1184    pub fn new(
1185        out_directory: PathBuf,
1186        out_crate_name: String,
1187        out_filestem: String,
1188        single_output_file: Option<OutFileName>,
1189        temps_directory: Option<PathBuf>,
1190        invocation_temp: Option<String>,
1191        explicit_dwo_out_directory: Option<PathBuf>,
1192        extra: String,
1193        outputs: OutputTypes,
1194    ) -> Self {
1195        OutputFilenames {
1196            out_directory,
1197            single_output_file,
1198            temps_directory,
1199            invocation_temp,
1200            explicit_dwo_out_directory,
1201            outputs,
1202            crate_stem: ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1}", out_crate_name, extra))
    })format!("{out_crate_name}{extra}"),
1203            filestem: ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1}", out_filestem, extra))
    })format!("{out_filestem}{extra}"),
1204        }
1205    }
1206
1207    pub fn path(&self, flavor: OutputType) -> OutFileName {
1208        self.outputs
1209            .get(&flavor)
1210            .and_then(|p| p.to_owned())
1211            .or_else(|| self.single_output_file.clone())
1212            .unwrap_or_else(|| OutFileName::Real(self.output_path(flavor)))
1213    }
1214
1215    pub fn interface_path(&self) -> PathBuf {
1216        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_session/src/config.rs:1216",
                        "rustc_session::config", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_session/src/config.rs"),
                        ::tracing_core::__macro_support::Option::Some(1216u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_session::config"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("using crate_name={0} for interface_path",
                                                    self.crate_stem) as &dyn Value))])
            });
    } else { ; }
};debug!("using crate_name={} for interface_path", self.crate_stem);
1217        self.out_directory.join(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("lib{0}.rs", self.crate_stem))
    })format!("lib{}.rs", self.crate_stem))
1218    }
1219
1220    /// Gets the output path where a compilation artifact of the given type
1221    /// should be placed on disk.
1222    fn output_path(&self, flavor: OutputType) -> PathBuf {
1223        let extension = flavor.extension();
1224        match flavor {
1225            OutputType::Metadata => {
1226                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_session/src/config.rs:1226",
                        "rustc_session::config", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_session/src/config.rs"),
                        ::tracing_core::__macro_support::Option::Some(1226u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_session::config"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("using crate_name={0} for {1}",
                                                    self.crate_stem, extension) as &dyn Value))])
            });
    } else { ; }
};debug!("using crate_name={} for {extension}", self.crate_stem);
1227                self.out_directory.join(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("lib{0}.{1}", self.crate_stem,
                extension))
    })format!("lib{}.{}", self.crate_stem, extension))
1228            }
1229            _ => self.with_directory_and_extension(&self.out_directory, extension),
1230        }
1231    }
1232
1233    /// Gets the path where a compilation artifact of the given type for the
1234    /// given codegen unit should be placed on disk. If codegen_unit_name is
1235    /// None, a path distinct from those of any codegen unit will be generated.
1236    pub fn temp_path_for_cgu(&self, flavor: OutputType, codegen_unit_name: &str) -> PathBuf {
1237        let extension = flavor.extension();
1238        self.temp_path_ext_for_cgu(extension, codegen_unit_name)
1239    }
1240
1241    /// Like `temp_path`, but specifically for dwarf objects.
1242    pub fn temp_path_dwo_for_cgu(&self, codegen_unit_name: &str) -> PathBuf {
1243        let p = self.temp_path_ext_for_cgu(DWARF_OBJECT_EXT, codegen_unit_name);
1244        if let Some(dwo_out) = &self.explicit_dwo_out_directory {
1245            let mut o = dwo_out.clone();
1246            o.push(p.file_name().unwrap());
1247            o
1248        } else {
1249            p
1250        }
1251    }
1252
1253    /// Like `temp_path`, but also supports things where there is no corresponding
1254    /// OutputType, like noopt-bitcode or lto-bitcode.
1255    pub fn temp_path_ext_for_cgu(&self, ext: &str, codegen_unit_name: &str) -> PathBuf {
1256        let mut extension = codegen_unit_name.to_string();
1257
1258        // Append `.{invocation_temp}` to ensure temporary files are unique.
1259        if let Some(rng) = &self.invocation_temp {
1260            extension.push('.');
1261            extension.push_str(rng);
1262        }
1263
1264        // FIXME: This is sketchy that we're not appending `.rcgu` when the ext is empty.
1265        // Append `.rcgu.{ext}`.
1266        if !ext.is_empty() {
1267            extension.push('.');
1268            extension.push_str(RUST_CGU_EXT);
1269            extension.push('.');
1270            extension.push_str(ext);
1271        }
1272
1273        let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
1274        maybe_strip_file_name(self.with_directory_and_extension(temps_directory, &extension))
1275    }
1276
1277    pub fn temp_path_for_diagnostic(&self, ext: &str) -> PathBuf {
1278        let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
1279        self.with_directory_and_extension(temps_directory, &ext)
1280    }
1281
1282    pub fn with_extension(&self, extension: &str) -> PathBuf {
1283        self.with_directory_and_extension(&self.out_directory, extension)
1284    }
1285
1286    pub fn with_directory_and_extension(&self, directory: &Path, extension: &str) -> PathBuf {
1287        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_session/src/config.rs:1287",
                        "rustc_session::config", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_session/src/config.rs"),
                        ::tracing_core::__macro_support::Option::Some(1287u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_session::config"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("using filestem={0} for {1}",
                                                    self.filestem, extension) as &dyn Value))])
            });
    } else { ; }
};debug!("using filestem={} for {extension}", self.filestem);
1288        let mut path = directory.join(&self.filestem);
1289        path.set_extension(extension);
1290        path
1291    }
1292
1293    /// Returns the path for the Split DWARF file - this can differ depending on which Split DWARF
1294    /// mode is being used, which is the logic that this function is intended to encapsulate.
1295    pub fn split_dwarf_path(
1296        &self,
1297        split_debuginfo_kind: SplitDebuginfo,
1298        split_dwarf_kind: SplitDwarfKind,
1299        cgu_name: &str,
1300    ) -> Option<PathBuf> {
1301        let obj_out = self.temp_path_for_cgu(OutputType::Object, cgu_name);
1302        let dwo_out = self.temp_path_dwo_for_cgu(cgu_name);
1303        match (split_debuginfo_kind, split_dwarf_kind) {
1304            (SplitDebuginfo::Off, SplitDwarfKind::Single | SplitDwarfKind::Split) => None,
1305            // Single mode doesn't change how DWARF is emitted, but does add Split DWARF attributes
1306            // (pointing at the path which is being determined here). Use the path to the current
1307            // object file.
1308            (SplitDebuginfo::Packed | SplitDebuginfo::Unpacked, SplitDwarfKind::Single) => {
1309                Some(obj_out)
1310            }
1311            // Split mode emits the DWARF into a different file, use that path.
1312            (SplitDebuginfo::Packed | SplitDebuginfo::Unpacked, SplitDwarfKind::Split) => {
1313                Some(dwo_out)
1314            }
1315        }
1316    }
1317}
1318
1319// pub for rustdoc
1320pub fn parse_remap_path_scope(
1321    early_dcx: &EarlyDiagCtxt,
1322    matches: &getopts::Matches,
1323    unstable_opts: &UnstableOptions,
1324) -> RemapPathScopeComponents {
1325    if let Some(v) = matches.opt_str("remap-path-scope") {
1326        let mut slot = RemapPathScopeComponents::empty();
1327        for s in v.split(',') {
1328            slot |= match s {
1329                "macro" => RemapPathScopeComponents::MACRO,
1330                "diagnostics" => RemapPathScopeComponents::DIAGNOSTICS,
1331                "documentation" => {
1332                    if !unstable_opts.unstable_options {
1333                        early_dcx.early_fatal("remapping `documentation` path scope requested but `-Zunstable-options` not specified");
1334                    }
1335
1336                    RemapPathScopeComponents::DOCUMENTATION
1337                },
1338                "debuginfo" => RemapPathScopeComponents::DEBUGINFO,
1339                "coverage" => RemapPathScopeComponents::COVERAGE,
1340                "object" => RemapPathScopeComponents::OBJECT,
1341                "all" => RemapPathScopeComponents::all(),
1342                _ => early_dcx.early_fatal("argument for `--remap-path-scope` must be a comma separated list of scopes: `macro`, `diagnostics`, `documentation`, `debuginfo`, `coverage`, `object`, `all`"),
1343            }
1344        }
1345        slot
1346    } else {
1347        RemapPathScopeComponents::all()
1348    }
1349}
1350
1351#[derive(#[automatically_derived]
impl ::core::clone::Clone for Sysroot {
    #[inline]
    fn clone(&self) -> Sysroot {
        Sysroot {
            explicit: ::core::clone::Clone::clone(&self.explicit),
            default: ::core::clone::Clone::clone(&self.default),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Sysroot {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "Sysroot",
            "explicit", &self.explicit, "default", &&self.default)
    }
}Debug)]
1352pub struct Sysroot {
1353    pub explicit: Option<PathBuf>,
1354    pub default: PathBuf,
1355}
1356
1357impl Sysroot {
1358    pub fn new(explicit: Option<PathBuf>) -> Sysroot {
1359        Sysroot { explicit, default: filesearch::default_sysroot() }
1360    }
1361
1362    /// Return explicit sysroot if it was passed with `--sysroot`, or default sysroot otherwise.
1363    pub fn path(&self) -> &Path {
1364        self.explicit.as_deref().unwrap_or(&self.default)
1365    }
1366
1367    /// Returns both explicit sysroot if it was passed with `--sysroot` and the default sysroot.
1368    pub fn all_paths(&self) -> impl Iterator<Item = &Path> {
1369        self.explicit.as_deref().into_iter().chain(iter::once(&*self.default))
1370    }
1371}
1372
1373pub fn host_tuple() -> &'static str {
1374    // Get the host triple out of the build environment. This ensures that our
1375    // idea of the host triple is the same as for the set of libraries we've
1376    // actually built. We can't just take LLVM's host triple because they
1377    // normalize all ix86 architectures to i386.
1378    //
1379    // Instead of grabbing the host triple (for the current host), we grab (at
1380    // compile time) the target triple that this rustc is built with and
1381    // calling that (at runtime) the host triple.
1382    (::core::option::Option::Some("x86_64-unknown-linux-gnu")option_env!("CFG_COMPILER_HOST_TRIPLE")).expect("CFG_COMPILER_HOST_TRIPLE")
1383}
1384
1385fn file_path_mapping(
1386    remap_path_prefix: Vec<(PathBuf, PathBuf)>,
1387    remap_cwd_prefix: Option<&Path>,
1388    remap_path_scope: RemapPathScopeComponents,
1389) -> FilePathMapping {
1390    // Apply `-Zremap-cwd-prefix` here rather than in `parse_remap_path_prefix`, so the
1391    // absolute cwd is never stored in the tracked `remap_path_prefix` option (#132132).
1392    let cwd_remap = if let Some(to) = remap_cwd_prefix
1393        && let Ok(cwd) = std::env::current_dir()
1394    {
1395        Some((cwd, to.to_path_buf()))
1396    } else {
1397        None
1398    };
1399    // The cwd remapping is appended last: `map_prefix` tries entries in reverse order, so this
1400    // keeps `-Zremap-cwd-prefix` taking precedence over `--remap-path-prefix`, as documented.
1401    FilePathMapping::new(remap_path_prefix.into_iter().chain(cwd_remap).collect(), remap_path_scope)
1402}
1403
1404impl Default for Options {
1405    fn default() -> Options {
1406        let unstable_opts = UnstableOptions::default();
1407
1408        // FIXME(Urgau): This is a hack that ideally shouldn't exist, but rustdoc
1409        // currently uses this `Default` implementation, so we have no choice but
1410        // to create a default working directory.
1411        let working_dir = {
1412            let working_dir = std::env::current_dir().unwrap();
1413            let file_mapping =
1414                file_path_mapping(Vec::new(), None, RemapPathScopeComponents::empty());
1415            file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
1416        };
1417
1418        Options {
1419            crate_types: Vec::new(),
1420            optimize: OptLevel::No,
1421            debuginfo: DebugInfo::None,
1422            lint_opts: Vec::new(),
1423            lint_cap: None,
1424            describe_lints: false,
1425            output_types: OutputTypes(BTreeMap::new()),
1426            search_paths: ::alloc::vec::Vec::new()vec![],
1427            sysroot: Sysroot::new(None),
1428            target_triple: TargetTuple::from_tuple(host_tuple()),
1429            test: false,
1430            incremental: None,
1431            unstable_opts,
1432            prints: Vec::new(),
1433            cg: Default::default(),
1434            error_format: ErrorOutputType::default(),
1435            diagnostic_width: None,
1436            externs: Externs(BTreeMap::new()),
1437            crate_name: None,
1438            libs: Vec::new(),
1439            unstable_features: UnstableFeatures::Disallow,
1440            debug_assertions: true,
1441            actually_rustdoc: false,
1442            resolve_doc_links: ResolveDocLinks::None,
1443            trimmed_def_paths: false,
1444            cli_forced_codegen_units: None,
1445            cli_forced_local_thinlto_off: false,
1446            remap_path_prefix: Vec::new(),
1447            remap_path_scope: RemapPathScopeComponents::all(),
1448            real_rust_source_base_dir: None,
1449            real_rustc_dev_source_base_dir: None,
1450            edition: DEFAULT_EDITION,
1451            json_artifact_notifications: false,
1452            json_timings: false,
1453            json_unused_externs: JsonUnusedExterns::No,
1454            json_future_incompat: false,
1455            pretty: None,
1456            working_dir,
1457            color: ColorConfig::Auto,
1458            logical_env: FxIndexMap::default(),
1459            verbose: false,
1460            target_modifiers: BTreeMap::default(),
1461            mitigation_coverage_map: Default::default(),
1462        }
1463    }
1464}
1465
1466impl Options {
1467    /// Returns `true` if there is a reason to build the dep graph.
1468    pub fn build_dep_graph(&self) -> bool {
1469        self.incremental.is_some()
1470            || self.unstable_opts.dump_dep_graph
1471            || self.unstable_opts.query_dep_graph
1472    }
1473
1474    pub fn file_path_mapping(&self) -> FilePathMapping {
1475        file_path_mapping(
1476            self.remap_path_prefix.clone(),
1477            self.unstable_opts.remap_cwd_prefix.as_deref(),
1478            self.remap_path_scope,
1479        )
1480    }
1481
1482    /// Returns `true` if there will be an output file generated.
1483    pub fn will_create_output_file(&self) -> bool {
1484        !self.unstable_opts.parse_crate_root_only && // The file is just being parsed
1485            self.unstable_opts.ls.is_empty() // The file is just being queried
1486    }
1487
1488    #[inline]
1489    pub fn share_generics(&self) -> bool {
1490        match self.unstable_opts.share_generics {
1491            Some(setting) => setting,
1492            None => match self.optimize {
1493                OptLevel::No | OptLevel::Less | OptLevel::Size | OptLevel::SizeMin => true,
1494                OptLevel::More | OptLevel::Aggressive => false,
1495            },
1496        }
1497    }
1498
1499    pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
1500        self.cg.symbol_mangling_version.unwrap_or(SymbolManglingVersion::V0)
1501    }
1502
1503    #[inline]
1504    pub fn autodiff_enabled(&self) -> bool {
1505        self.unstable_opts.autodiff.contains(&AutoDiff::Enable)
1506    }
1507}
1508
1509impl UnstableOptions {
1510    pub fn dcx_flags(&self, can_emit_warnings: bool) -> DiagCtxtFlags {
1511        DiagCtxtFlags {
1512            can_emit_warnings,
1513            treat_err_as_bug: self.treat_err_as_bug,
1514            eagerly_emit_delayed_bugs: self.eagerly_emit_delayed_bugs,
1515            macro_backtrace: self.macro_backtrace,
1516            deduplicate_diagnostics: self.deduplicate_diagnostics,
1517            track_diagnostics: self.track_diagnostics,
1518        }
1519    }
1520
1521    pub fn src_hash_algorithm(&self, target: &Target) -> SourceFileHashAlgorithm {
1522        self.src_hash_algorithm.unwrap_or_else(|| {
1523            if target.is_like_msvc {
1524                SourceFileHashAlgorithm::Sha256
1525            } else {
1526                SourceFileHashAlgorithm::Md5
1527            }
1528        })
1529    }
1530
1531    pub fn checksum_hash_algorithm(&self) -> Option<SourceFileHashAlgorithm> {
1532        self.checksum_hash_algorithm
1533    }
1534}
1535
1536// The type of entry function, so users can have their own entry functions
1537#[derive(#[automatically_derived]
impl ::core::marker::Copy for EntryFnType { }Copy, #[automatically_derived]
impl ::core::clone::Clone for EntryFnType {
    #[inline]
    fn clone(&self) -> EntryFnType {
        let _: ::core::clone::AssertParamIsClone<u8>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for EntryFnType {
    #[inline]
    fn eq(&self, other: &EntryFnType) -> bool {
        match (self, other) {
            (EntryFnType::Main { sigpipe: __self_0 }, EntryFnType::Main {
                sigpipe: __arg1_0 }) => __self_0 == __arg1_0,
        }
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for EntryFnType {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        match self {
            EntryFnType::Main { sigpipe: __self_0 } =>
                ::core::hash::Hash::hash(__self_0, state),
        }
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for EntryFnType {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            EntryFnType::Main { sigpipe: __self_0 } =>
                ::core::fmt::Formatter::debug_struct_field1_finish(f, "Main",
                    "sigpipe", &__self_0),
        }
    }
}Debug, const _: () =
    {
        impl ::rustc_data_structures::stable_hash::StableHash for EntryFnType
            {
            #[inline]
            fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
                __hcx: &mut __Hcx,
                __hasher:
                    &mut ::rustc_data_structures::stable_hash::StableHasher) {
                ::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
                match *self {
                    EntryFnType::Main { sigpipe: ref __binding_0 } => {
                        { __binding_0.stable_hash(__hcx, __hasher); }
                    }
                }
            }
        }
    };StableHash)]
1538pub enum EntryFnType {
1539    Main {
1540        /// Specifies what to do with `SIGPIPE` before calling `fn main()`.
1541        ///
1542        /// What values that are valid and what they mean must be in sync
1543        /// across rustc and libstd, but we don't want it public in libstd,
1544        /// so we take a bit of an unusual approach with simple constants
1545        /// and an `include!()`.
1546        sigpipe: u8,
1547    },
1548}
1549
1550pub use rustc_hir::attrs::CrateType;
1551
1552#[derive(#[automatically_derived]
impl ::core::clone::Clone for Passes {
    #[inline]
    fn clone(&self) -> Passes {
        match self {
            Passes::Some(__self_0) =>
                Passes::Some(::core::clone::Clone::clone(__self_0)),
            Passes::All => Passes::All,
        }
    }
}Clone, #[automatically_derived]
impl ::core::hash::Hash for Passes {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            Passes::Some(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Passes {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Passes::Some(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Some",
                    &__self_0),
            Passes::All => ::core::fmt::Formatter::write_str(f, "All"),
        }
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for Passes {
    #[inline]
    fn eq(&self, other: &Passes) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (Passes::Some(__self_0), Passes::Some(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Passes {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<Vec<String>>;
    }
}Eq, const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for Passes {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        Passes::Some(ref __binding_0) => { 0usize }
                        Passes::All => { 1usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
                match *self {
                    Passes::Some(ref __binding_0) => {
                        ::rustc_serialize::Encodable::<__E>::encode(__binding_0,
                            __encoder);
                    }
                    Passes::All => {}
                }
            }
        }
    };Encodable, const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for Passes {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => {
                        Passes::Some(::rustc_serialize::Decodable::decode(__decoder))
                    }
                    1usize => { Passes::All }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Passes`, expected 0..2, actual {0}",
                                n));
                    }
                }
            }
        }
    };Decodable)]
1553pub enum Passes {
1554    Some(Vec<String>),
1555    All,
1556}
1557
1558impl Passes {
1559    fn is_empty(&self) -> bool {
1560        match *self {
1561            Passes::Some(ref v) => v.is_empty(),
1562            Passes::All => false,
1563        }
1564    }
1565
1566    pub(crate) fn extend(&mut self, passes: impl IntoIterator<Item = String>) {
1567        match *self {
1568            Passes::Some(ref mut v) => v.extend(passes),
1569            Passes::All => {}
1570        }
1571    }
1572}
1573
1574#[derive(#[automatically_derived]
impl ::core::clone::Clone for PAuthKey {
    #[inline]
    fn clone(&self) -> PAuthKey { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for PAuthKey { }Copy, #[automatically_derived]
impl ::core::hash::Hash for PAuthKey {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for PAuthKey {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self { PAuthKey::A => "A", PAuthKey::B => "B", })
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for PAuthKey {
    #[inline]
    fn eq(&self, other: &PAuthKey) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq)]
1575pub enum PAuthKey {
1576    A,
1577    B,
1578}
1579
1580#[derive(#[automatically_derived]
impl ::core::clone::Clone for PacRet {
    #[inline]
    fn clone(&self) -> PacRet {
        let _: ::core::clone::AssertParamIsClone<bool>;
        let _: ::core::clone::AssertParamIsClone<PAuthKey>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for PacRet { }Copy, #[automatically_derived]
impl ::core::hash::Hash for PacRet {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.leaf, state);
        ::core::hash::Hash::hash(&self.pc, state);
        ::core::hash::Hash::hash(&self.key, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for PacRet {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f, "PacRet",
            "leaf", &self.leaf, "pc", &self.pc, "key", &&self.key)
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for PacRet {
    #[inline]
    fn eq(&self, other: &PacRet) -> bool {
        self.leaf == other.leaf && self.pc == other.pc &&
            self.key == other.key
    }
}PartialEq)]
1581pub struct PacRet {
1582    pub leaf: bool,
1583    pub pc: bool,
1584    pub key: PAuthKey,
1585}
1586
1587#[derive(#[automatically_derived]
impl ::core::clone::Clone for BranchProtection {
    #[inline]
    fn clone(&self) -> BranchProtection {
        let _: ::core::clone::AssertParamIsClone<bool>;
        let _: ::core::clone::AssertParamIsClone<Option<PacRet>>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for BranchProtection { }Copy, #[automatically_derived]
impl ::core::hash::Hash for BranchProtection {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.bti, state);
        ::core::hash::Hash::hash(&self.pac_ret, state);
        ::core::hash::Hash::hash(&self.gcs, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for BranchProtection {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "BranchProtection", "bti", &self.bti, "pac_ret", &self.pac_ret,
            "gcs", &&self.gcs)
    }
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for BranchProtection {
    #[inline]
    fn eq(&self, other: &BranchProtection) -> bool {
        self.bti == other.bti && self.gcs == other.gcs &&
            self.pac_ret == other.pac_ret
    }
}PartialEq, #[automatically_derived]
impl ::core::default::Default for BranchProtection {
    #[inline]
    fn default() -> BranchProtection {
        BranchProtection {
            bti: ::core::default::Default::default(),
            pac_ret: ::core::default::Default::default(),
            gcs: ::core::default::Default::default(),
        }
    }
}Default)]
1588pub struct BranchProtection {
1589    pub bti: bool,
1590    pub pac_ret: Option<PacRet>,
1591    pub gcs: bool,
1592}
1593
1594pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
1595    // First disallow some configuration given on the command line
1596    cfg::disallow_cfgs(sess, &user_cfg);
1597
1598    // Then combine the configuration requested by the session (command line) with
1599    // some default and generated configuration items.
1600    user_cfg.extend(cfg::default_configuration(sess));
1601    user_cfg
1602}
1603
1604pub fn build_target_config(
1605    early_dcx: &EarlyDiagCtxt,
1606    target: &TargetTuple,
1607    sysroot: &Path,
1608    unstable_options: bool,
1609) -> Target {
1610    match Target::search(target, sysroot, unstable_options) {
1611        Ok((target, warnings)) => {
1612            for warning in warnings.warning_messages() {
1613                early_dcx.early_warn(warning)
1614            }
1615
1616            if !#[allow(non_exhaustive_omitted_patterns)] match target.pointer_width {
    16 | 32 | 64 => true,
    _ => false,
}matches!(target.pointer_width, 16 | 32 | 64) {
1617                early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("target specification was invalid: unrecognized target-pointer-width {0}",
                target.pointer_width))
    })format!(
1618                    "target specification was invalid: unrecognized target-pointer-width {}",
1619                    target.pointer_width
1620                ))
1621            }
1622            target
1623        }
1624        Err(e) => {
1625            let mut err =
1626                early_dcx.early_struct_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("error loading target specification: {0}",
                e))
    })format!("error loading target specification: {e}"));
1627            err.help("run `rustc --print target-list` for a list of built-in targets");
1628            let typed = target.tuple();
1629            let limit = typed.len() / 3 + 1;
1630            if let Some(suggestion) = rustc_target::spec::TARGETS
1631                .iter()
1632                .filter_map(|&t| {
1633                    rustc_span::edit_distance::edit_distance_with_substrings(typed, t, limit)
1634                        .map(|d| (d, t))
1635                })
1636                .min_by_key(|(d, _)| *d)
1637                .map(|(_, t)| t)
1638            {
1639                err.help(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("did you mean `{0}`?", suggestion))
    })format!("did you mean `{suggestion}`?"));
1640            }
1641            err.emit()
1642        }
1643    }
1644}
1645
1646#[derive(#[automatically_derived]
impl ::core::marker::Copy for OptionStability { }Copy, #[automatically_derived]
impl ::core::clone::Clone for OptionStability {
    #[inline]
    fn clone(&self) -> OptionStability { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for OptionStability {
    #[inline]
    fn eq(&self, other: &OptionStability) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for OptionStability {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for OptionStability {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                OptionStability::Stable => "Stable",
                OptionStability::Unstable => "Unstable",
            })
    }
}Debug)]
1647pub enum OptionStability {
1648    Stable,
1649    Unstable,
1650}
1651
1652#[derive(#[automatically_derived]
impl ::core::marker::Copy for OptionKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for OptionKind {
    #[inline]
    fn clone(&self) -> OptionKind { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for OptionKind {
    #[inline]
    fn eq(&self, other: &OptionKind) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for OptionKind {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for OptionKind {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                OptionKind::Opt => "Opt",
                OptionKind::Multi => "Multi",
                OptionKind::Flag => "Flag",
                OptionKind::FlagMulti => "FlagMulti",
            })
    }
}Debug)]
1653pub enum OptionKind {
1654    /// An option that takes a value, and cannot appear more than once (e.g. `--out-dir`).
1655    ///
1656    /// Corresponds to [`getopts::Options::optopt`].
1657    Opt,
1658
1659    /// An option that takes a value, and can appear multiple times (e.g. `--emit`).
1660    ///
1661    /// Corresponds to [`getopts::Options::optmulti`].
1662    Multi,
1663
1664    /// An option that does not take a value, and cannot appear more than once (e.g. `--help`).
1665    ///
1666    /// Corresponds to [`getopts::Options::optflag`].
1667    /// The `hint` string must be empty.
1668    Flag,
1669
1670    /// An option that does not take a value, and can appear multiple times (e.g. `-O`).
1671    ///
1672    /// Corresponds to [`getopts::Options::optflagmulti`].
1673    /// The `hint` string must be empty.
1674    FlagMulti,
1675}
1676
1677pub struct RustcOptGroup {
1678    /// The "primary" name for this option. Normally equal to `long_name`,
1679    /// except for options that don't have a long name, in which case
1680    /// `short_name` is used.
1681    ///
1682    /// This is needed when interacting with `getopts` in some situations,
1683    /// because if an option has both forms, that library treats the long name
1684    /// as primary and the short name as an alias.
1685    pub name: &'static str,
1686    stability: OptionStability,
1687    kind: OptionKind,
1688
1689    short_name: &'static str,
1690    long_name: &'static str,
1691    desc: &'static str,
1692    value_hint: &'static str,
1693
1694    /// If true, this option should not be printed by `rustc --help`, but
1695    /// should still be printed by `rustc --help -v`.
1696    pub is_verbose_help_only: bool,
1697}
1698
1699impl RustcOptGroup {
1700    pub fn is_stable(&self) -> bool {
1701        self.stability == OptionStability::Stable
1702    }
1703
1704    pub fn apply(&self, options: &mut getopts::Options) {
1705        let &Self { short_name, long_name, desc, value_hint, .. } = self;
1706        match self.kind {
1707            OptionKind::Opt => options.optopt(short_name, long_name, desc, value_hint),
1708            OptionKind::Multi => options.optmulti(short_name, long_name, desc, value_hint),
1709            OptionKind::Flag => options.optflag(short_name, long_name, desc),
1710            OptionKind::FlagMulti => options.optflagmulti(short_name, long_name, desc),
1711        };
1712    }
1713
1714    /// This is for diagnostics-only.
1715    pub fn long_name(&self) -> &str {
1716        self.long_name
1717    }
1718}
1719
1720pub fn make_opt(
1721    stability: OptionStability,
1722    kind: OptionKind,
1723    short_name: &'static str,
1724    long_name: &'static str,
1725    desc: &'static str,
1726    value_hint: &'static str,
1727) -> RustcOptGroup {
1728    // "Flag" options don't have a value, and therefore don't have a value hint.
1729    match kind {
1730        OptionKind::Opt | OptionKind::Multi => {}
1731        OptionKind::Flag | OptionKind::FlagMulti => match (&value_hint, &"") {
    (left_val, right_val) => {
        if !(*left_val == *right_val) {
            let kind = ::core::panicking::AssertKind::Eq;
            ::core::panicking::assert_failed(kind, &*left_val, &*right_val,
                ::core::option::Option::None);
        }
    }
}assert_eq!(value_hint, ""),
1732    }
1733    RustcOptGroup {
1734        name: cmp::max_by_key(short_name, long_name, |s| s.len()),
1735        stability,
1736        kind,
1737        short_name,
1738        long_name,
1739        desc,
1740        value_hint,
1741        is_verbose_help_only: false,
1742    }
1743}
1744
1745static EDITION_STRING: LazyLock<String> = LazyLock::new(|| {
1746    ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("Specify which edition of the compiler to use when compiling code. The default is {0} and the latest stable edition is {1}.",
                DEFAULT_EDITION, LATEST_STABLE_EDITION))
    })format!(
1747        "Specify which edition of the compiler to use when compiling code. \
1748The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE_EDITION}."
1749    )
1750});
1751
1752static EMIT_HELP: LazyLock<String> = LazyLock::new(|| {
1753    let mut result =
1754        String::from("Comma separated list of types of output for the compiler to emit.\n");
1755    result.push_str("Each TYPE has the default FILE name:\n");
1756
1757    for output in OutputType::iter_all() {
1758        result.push_str(&::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("*  {0} - {1}\n",
                output.shorthand(), output.default_filename()))
    })format!("*  {} - {}\n", output.shorthand(), output.default_filename()));
1759    }
1760
1761    result
1762});
1763
1764/// Returns all rustc command line options, including metadata for
1765/// each option, such as whether the option is stable.
1766///
1767/// # Option style guidelines
1768///
1769/// - `<param>`: Indicates a required parameter
1770/// - `[param]`: Indicates an optional parameter
1771/// - `|`: Indicates a mutually exclusive option
1772/// - `*`: a list element with description
1773pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
1774    use OptionKind::{Flag, FlagMulti, Multi, Opt};
1775    use OptionStability::{Stable, Unstable};
1776
1777    use self::make_opt as opt;
1778
1779    let mut options = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [opt(Stable, Flag, "h", "help", "Display this message", ""),
                opt(Stable, Multi, "", "cfg",
                    "Configure the compilation environment.\n\
                SPEC supports the syntax `<NAME>[=\"<VALUE>\"]`.",
                    "<SPEC>"),
                opt(Stable, Multi, "", "check-cfg",
                    "Provide list of expected cfgs for checking", "<SPEC>"),
                opt(Stable, Multi, "L", "",
                    "Add a directory to the library search path. \
                The optional KIND can be one of <dependency|crate|native|framework|all> (default: all).",
                    "[<KIND>=]<PATH>"),
                opt(Stable, Multi, "l", "",
                    "Link the generated crate(s) to the specified native\n\
                library NAME. The optional KIND can be one of\n\
                <static|framework|dylib> (default: dylib).\n\
                Optional comma separated MODIFIERS\n\
                <bundle|verbatim|whole-archive|as-needed>\n\
                may be specified each with a prefix of either '+' to\n\
                enable or '-' to disable.",
                    "[<KIND>[:<MODIFIERS>]=]<NAME>[:<RENAME>]"),
                make_crate_type_option(),
                opt(Stable, Opt, "", "crate-name",
                    "Specify the name of the crate being built", "<NAME>"),
                opt(Stable, Opt, "", "edition", &EDITION_STRING,
                    EDITION_NAME_LIST),
                opt(Stable, Multi, "", "emit", &EMIT_HELP, "<TYPE>[=<FILE>]"),
                opt(Stable, Multi, "", "print", &print_request::PRINT_HELP,
                    "<INFO>[=<FILE>]"),
                opt(Stable, FlagMulti, "g", "",
                    "Equivalent to -C debuginfo=2", ""),
                opt(Stable, FlagMulti, "O", "",
                    "Equivalent to -C opt-level=3", ""),
                opt(Stable, Opt, "o", "", "Write output to FILENAME",
                    "<FILENAME>"),
                opt(Stable, Opt, "", "out-dir",
                    "Write output to compiler-chosen filename in DIR", "<DIR>"),
                opt(Stable, Opt, "", "explain",
                    "Provide a detailed explanation of an error message",
                    "<OPT>"),
                opt(Stable, Flag, "", "test", "Build a test harness", ""),
                opt(Stable, Opt, "", "target",
                    "Target tuple for which the code is compiled", "<TARGET>"),
                opt(Stable, Multi, "A", "allow", "Set lint allowed",
                    "<LINT>"),
                opt(Stable, Multi, "W", "warn", "Set lint warnings",
                    "<LINT>"),
                opt(Stable, Multi, "", "force-warn", "Set lint force-warn",
                    "<LINT>"),
                opt(Stable, Multi, "D", "deny", "Set lint denied", "<LINT>"),
                opt(Stable, Multi, "F", "forbid", "Set lint forbidden",
                    "<LINT>"),
                opt(Stable, Multi, "", "cap-lints",
                    "Set the most restrictive lint level. More restrictive lints are capped at this level",
                    "<LEVEL>"),
                opt(Stable, Multi, "C", "codegen", "Set a codegen option",
                    "<OPT>[=<VALUE>]"),
                opt(Stable, Flag, "V", "version",
                    "Print version info and exit", ""),
                opt(Stable, Flag, "v", "verbose", "Use verbose output", "")]))vec![
1780        opt(Stable, Flag, "h", "help", "Display this message", ""),
1781        opt(
1782            Stable,
1783            Multi,
1784            "",
1785            "cfg",
1786            "Configure the compilation environment.\n\
1787                SPEC supports the syntax `<NAME>[=\"<VALUE>\"]`.",
1788            "<SPEC>",
1789        ),
1790        opt(Stable, Multi, "", "check-cfg", "Provide list of expected cfgs for checking", "<SPEC>"),
1791        opt(
1792            Stable,
1793            Multi,
1794            "L",
1795            "",
1796            "Add a directory to the library search path. \
1797                The optional KIND can be one of <dependency|crate|native|framework|all> (default: all).",
1798            "[<KIND>=]<PATH>",
1799        ),
1800        opt(
1801            Stable,
1802            Multi,
1803            "l",
1804            "",
1805            "Link the generated crate(s) to the specified native\n\
1806                library NAME. The optional KIND can be one of\n\
1807                <static|framework|dylib> (default: dylib).\n\
1808                Optional comma separated MODIFIERS\n\
1809                <bundle|verbatim|whole-archive|as-needed>\n\
1810                may be specified each with a prefix of either '+' to\n\
1811                enable or '-' to disable.",
1812            "[<KIND>[:<MODIFIERS>]=]<NAME>[:<RENAME>]",
1813        ),
1814        make_crate_type_option(),
1815        opt(Stable, Opt, "", "crate-name", "Specify the name of the crate being built", "<NAME>"),
1816        opt(Stable, Opt, "", "edition", &EDITION_STRING, EDITION_NAME_LIST),
1817        opt(Stable, Multi, "", "emit", &EMIT_HELP, "<TYPE>[=<FILE>]"),
1818        opt(Stable, Multi, "", "print", &print_request::PRINT_HELP, "<INFO>[=<FILE>]"),
1819        opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
1820        opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=3", ""),
1821        opt(Stable, Opt, "o", "", "Write output to FILENAME", "<FILENAME>"),
1822        opt(Stable, Opt, "", "out-dir", "Write output to compiler-chosen filename in DIR", "<DIR>"),
1823        opt(
1824            Stable,
1825            Opt,
1826            "",
1827            "explain",
1828            "Provide a detailed explanation of an error message",
1829            "<OPT>",
1830        ),
1831        opt(Stable, Flag, "", "test", "Build a test harness", ""),
1832        opt(Stable, Opt, "", "target", "Target tuple for which the code is compiled", "<TARGET>"),
1833        opt(Stable, Multi, "A", "allow", "Set lint allowed", "<LINT>"),
1834        opt(Stable, Multi, "W", "warn", "Set lint warnings", "<LINT>"),
1835        opt(Stable, Multi, "", "force-warn", "Set lint force-warn", "<LINT>"),
1836        opt(Stable, Multi, "D", "deny", "Set lint denied", "<LINT>"),
1837        opt(Stable, Multi, "F", "forbid", "Set lint forbidden", "<LINT>"),
1838        opt(
1839            Stable,
1840            Multi,
1841            "",
1842            "cap-lints",
1843            "Set the most restrictive lint level. More restrictive lints are capped at this level",
1844            "<LEVEL>",
1845        ),
1846        opt(Stable, Multi, "C", "codegen", "Set a codegen option", "<OPT>[=<VALUE>]"),
1847        opt(Stable, Flag, "V", "version", "Print version info and exit", ""),
1848        opt(Stable, Flag, "v", "verbose", "Use verbose output", ""),
1849    ];
1850
1851    // Options in this list are hidden from `rustc --help` by default, but are
1852    // shown by `rustc --help -v`.
1853    let verbose_only = [
1854        opt(
1855            Stable,
1856            Multi,
1857            "",
1858            "extern",
1859            "Specify where an external rust library is located",
1860            "<NAME>[=<PATH>]",
1861        ),
1862        opt(Stable, Opt, "", "sysroot", "Override the system root", "<PATH>"),
1863        opt(Unstable, Multi, "Z", "", "Set unstable / perma-unstable options", "<FLAG>"),
1864        opt(
1865            Stable,
1866            Opt,
1867            "",
1868            "error-format",
1869            "How errors and other messages are produced",
1870            "<human|json|short>",
1871        ),
1872        opt(Stable, Multi, "", "json", "Configure the JSON output of the compiler", "<CONFIG>"),
1873        opt(
1874            Stable,
1875            Opt,
1876            "",
1877            "color",
1878            "Configure coloring of output:
1879                * auto   = colorize, if output goes to a tty (default);
1880                * always = always colorize output;
1881                * never  = never colorize output",
1882            "<auto|always|never>",
1883        ),
1884        opt(
1885            Stable,
1886            Opt,
1887            "",
1888            "diagnostic-width",
1889            "Inform rustc of the width of the output so that diagnostics can be truncated to fit",
1890            "<WIDTH>",
1891        ),
1892        opt(
1893            Stable,
1894            Multi,
1895            "",
1896            "remap-path-prefix",
1897            "Remap source names in all output (compiler messages and output files)",
1898            "<FROM>=<TO>",
1899        ),
1900        opt(
1901            Stable,
1902            Opt,
1903            "",
1904            "remap-path-scope",
1905            "Defines which scopes of paths should be remapped by `--remap-path-prefix`",
1906            "<macro,diagnostics,debuginfo,coverage,object,all>",
1907        ),
1908        opt(Unstable, Multi, "", "env-set", "Inject an environment variable", "<VAR>=<VALUE>"),
1909    ];
1910    options.extend(verbose_only.into_iter().map(|mut opt| {
1911        opt.is_verbose_help_only = true;
1912        opt
1913    }));
1914
1915    options
1916}
1917
1918pub fn get_cmd_lint_options(
1919    early_dcx: &EarlyDiagCtxt,
1920    matches: &getopts::Matches,
1921) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
1922    let mut lint_opts_with_position = ::alloc::vec::Vec::new()vec![];
1923    let mut describe_lints = false;
1924
1925    for level in [lint::Allow, lint::Warn, lint::ForceWarn, lint::Deny, lint::Forbid] {
1926        for (arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
1927            if lint_name == "help" {
1928                describe_lints = true;
1929            } else {
1930                lint_opts_with_position.push((arg_pos, lint_name.replace('-', "_"), level));
1931            }
1932        }
1933    }
1934
1935    lint_opts_with_position.sort_by_key(|x| x.0);
1936    let lint_opts = lint_opts_with_position
1937        .iter()
1938        .cloned()
1939        .map(|(_, lint_name, level)| (lint_name, level))
1940        .collect();
1941
1942    let lint_cap = matches.opt_str("cap-lints").map(|cap| {
1943        lint::Level::from_str(&cap)
1944            .unwrap_or_else(|| early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown lint level: `{0}`", cap))
    })format!("unknown lint level: `{cap}`")))
1945    });
1946
1947    (lint_opts, describe_lints, lint_cap)
1948}
1949
1950/// Parses the `--color` flag.
1951pub fn parse_color(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> ColorConfig {
1952    match matches.opt_str("color").as_deref() {
1953        Some("auto") => ColorConfig::Auto,
1954        Some("always") => ColorConfig::Always,
1955        Some("never") => ColorConfig::Never,
1956
1957        None => ColorConfig::Auto,
1958
1959        Some(arg) => early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("argument for `--color` must be auto, always or never (instead was `{0}`)",
                arg))
    })format!(
1960            "argument for `--color` must be auto, \
1961                 always or never (instead was `{arg}`)"
1962        )),
1963    }
1964}
1965
1966/// Possible json config files
1967pub struct JsonConfig {
1968    pub json_rendered: HumanReadableErrorType,
1969    pub json_color: ColorConfig,
1970    json_artifact_notifications: bool,
1971    /// Output start and end timestamps of several high-level compilation sections
1972    /// (frontend, backend, linker).
1973    json_timings: bool,
1974    pub json_unused_externs: JsonUnusedExterns,
1975    json_future_incompat: bool,
1976}
1977
1978/// Report unused externs in event stream
1979#[derive(#[automatically_derived]
impl ::core::marker::Copy for JsonUnusedExterns { }Copy, #[automatically_derived]
impl ::core::clone::Clone for JsonUnusedExterns {
    #[inline]
    fn clone(&self) -> JsonUnusedExterns { *self }
}Clone)]
1980pub enum JsonUnusedExterns {
1981    /// Do not
1982    No,
1983    /// Report, but do not exit with failure status for deny/forbid
1984    Silent,
1985    /// Report, and also exit with failure status for deny/forbid
1986    Loud,
1987}
1988
1989impl JsonUnusedExterns {
1990    pub fn is_enabled(&self) -> bool {
1991        match self {
1992            JsonUnusedExterns::No => false,
1993            JsonUnusedExterns::Loud | JsonUnusedExterns::Silent => true,
1994        }
1995    }
1996
1997    pub fn is_loud(&self) -> bool {
1998        match self {
1999            JsonUnusedExterns::No | JsonUnusedExterns::Silent => false,
2000            JsonUnusedExterns::Loud => true,
2001        }
2002    }
2003}
2004
2005/// Parse the `--json` flag.
2006///
2007/// The first value returned is how to render JSON diagnostics, and the second
2008/// is whether or not artifact notifications are enabled.
2009pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> JsonConfig {
2010    let mut json_rendered = HumanReadableErrorType { short: false, unicode: false };
2011    let mut json_color = ColorConfig::Never;
2012    let mut json_artifact_notifications = false;
2013    let mut json_unused_externs = JsonUnusedExterns::No;
2014    let mut json_future_incompat = false;
2015    let mut json_timings = false;
2016    for option in matches.opt_strs("json") {
2017        // For now conservatively forbid `--color` with `--json` since `--json`
2018        // won't actually be emitting any colors and anything colorized is
2019        // embedded in a diagnostic message anyway.
2020        if matches.opt_str("color").is_some() {
2021            early_dcx.early_fatal("cannot specify the `--color` option with `--json`");
2022        }
2023
2024        for sub_option in option.split(',') {
2025            match sub_option {
2026                "diagnostic-short" => {
2027                    json_rendered = HumanReadableErrorType { short: true, unicode: false };
2028                }
2029                "diagnostic-unicode" => {
2030                    json_rendered = HumanReadableErrorType { short: false, unicode: true };
2031                }
2032                "diagnostic-rendered-ansi" => json_color = ColorConfig::Always,
2033                "artifacts" => json_artifact_notifications = true,
2034                "timings" => json_timings = true,
2035                "unused-externs" => json_unused_externs = JsonUnusedExterns::Loud,
2036                "unused-externs-silent" => json_unused_externs = JsonUnusedExterns::Silent,
2037                "future-incompat" => json_future_incompat = true,
2038                s => early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown `--json` option `{0}`", s))
    })format!("unknown `--json` option `{s}`")),
2039            }
2040        }
2041    }
2042
2043    JsonConfig {
2044        json_rendered,
2045        json_color,
2046        json_artifact_notifications,
2047        json_timings,
2048        json_unused_externs,
2049        json_future_incompat,
2050    }
2051}
2052
2053/// Parses the `--error-format` flag.
2054pub fn parse_error_format(
2055    early_dcx: &mut EarlyDiagCtxt,
2056    matches: &getopts::Matches,
2057    color_config: ColorConfig,
2058    json_color: ColorConfig,
2059    json_rendered: HumanReadableErrorType,
2060) -> ErrorOutputType {
2061    let default_kind = HumanReadableErrorType { short: false, unicode: false };
2062    // We need the `opts_present` check because the driver will send us Matches
2063    // with only stable options if no unstable options are used. Since error-format
2064    // is unstable, it will not be present. We have to use `opts_present` not
2065    // `opt_present` because the latter will panic.
2066    let error_format = if matches.opts_present(&["error-format".to_owned()]) {
2067        match matches.opt_str("error-format").as_deref() {
2068            None | Some("human") => {
2069                ErrorOutputType::HumanReadable { color_config, kind: default_kind }
2070            }
2071            Some("json") => {
2072                ErrorOutputType::Json { pretty: false, json_rendered, color_config: json_color }
2073            }
2074            Some("pretty-json") => {
2075                ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color }
2076            }
2077            Some("short") => ErrorOutputType::HumanReadable {
2078                kind: HumanReadableErrorType { short: true, unicode: false },
2079                color_config,
2080            },
2081            Some("human-unicode") => ErrorOutputType::HumanReadable {
2082                kind: HumanReadableErrorType { short: false, unicode: true },
2083                color_config,
2084            },
2085            Some(arg) => {
2086                early_dcx.set_error_format(ErrorOutputType::HumanReadable {
2087                    color_config,
2088                    kind: default_kind,
2089                });
2090                early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("argument for `--error-format` must be `human`, `human-unicode`, `json`, `pretty-json` or `short` (instead was `{0}`)",
                arg))
    })format!(
2091                    "argument for `--error-format` must be `human`, `human-unicode`, \
2092                    `json`, `pretty-json` or `short` (instead was `{arg}`)"
2093                ))
2094            }
2095        }
2096    } else {
2097        ErrorOutputType::HumanReadable { color_config, kind: default_kind }
2098    };
2099
2100    match error_format {
2101        ErrorOutputType::Json { .. } => {}
2102
2103        // Conservatively require that the `--json` argument is coupled with
2104        // `--error-format=json`. This means that `--json` is specified we
2105        // should actually be emitting JSON blobs.
2106        _ if !matches.opt_strs("json").is_empty() => {
2107            early_dcx.early_fatal("using `--json` requires also using `--error-format=json`");
2108        }
2109
2110        _ => {}
2111    }
2112
2113    error_format
2114}
2115
2116pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Edition {
2117    let edition = match matches.opt_str("edition") {
2118        Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| {
2119            early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("argument for `--edition` must be one of: {0}. (instead was `{1}`)",
                EDITION_NAME_LIST, arg))
    })format!(
2120                "argument for `--edition` must be one of: \
2121                     {EDITION_NAME_LIST}. (instead was `{arg}`)"
2122            ))
2123        }),
2124        None => DEFAULT_EDITION,
2125    };
2126
2127    if !edition.is_stable() && !nightly_options::is_unstable_enabled(matches) {
2128        let is_nightly = nightly_options::match_is_nightly_build(matches);
2129        let msg = if !is_nightly {
2130            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the crate requires edition {0}, but the latest edition supported by this Rust version is {1}",
                edition, LATEST_STABLE_EDITION))
    })format!(
2131                "the crate requires edition {edition}, but the latest edition supported by this Rust version is {LATEST_STABLE_EDITION}"
2132            )
2133        } else {
2134            ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("edition {0} is unstable and only available with -Z unstable-options",
                edition))
    })format!("edition {edition} is unstable and only available with -Z unstable-options")
2135        };
2136        early_dcx.early_fatal(msg)
2137    }
2138
2139    edition
2140}
2141
2142fn check_error_format_stability(
2143    early_dcx: &EarlyDiagCtxt,
2144    unstable_opts: &UnstableOptions,
2145    is_nightly_build: bool,
2146    format: ErrorOutputType,
2147) {
2148    if unstable_opts.unstable_options || is_nightly_build {
2149        return;
2150    }
2151    let format = match format {
2152        ErrorOutputType::Json { pretty: true, .. } => "pretty-json",
2153        ErrorOutputType::HumanReadable { kind, .. } => match kind {
2154            HumanReadableErrorType { unicode: true, .. } => "human-unicode",
2155            _ => return,
2156        },
2157        _ => return,
2158    };
2159    early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`--error-format={0}` is unstable",
                format))
    })format!("`--error-format={format}` is unstable"))
2160}
2161
2162fn parse_output_types(
2163    early_dcx: &EarlyDiagCtxt,
2164    unstable_opts: &UnstableOptions,
2165    matches: &getopts::Matches,
2166) -> OutputTypes {
2167    let mut output_types = BTreeMap::new();
2168    if !unstable_opts.parse_crate_root_only {
2169        for list in matches.opt_strs("emit") {
2170            for output_type in list.split(',') {
2171                let (shorthand, path) = split_out_file_name(output_type);
2172                let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
2173                    early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown emission type: `{1}` - expected one of: {0}",
                OutputType::shorthands_display(), shorthand))
    })format!(
2174                        "unknown emission type: `{shorthand}` - expected one of: {display}",
2175                        display = OutputType::shorthands_display(),
2176                    ))
2177                });
2178                if output_type == OutputType::ThinLinkBitcode && !unstable_opts.unstable_options {
2179                    early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} requested but -Zunstable-options not specified",
                OutputType::ThinLinkBitcode.shorthand()))
    })format!(
2180                        "{} requested but -Zunstable-options not specified",
2181                        OutputType::ThinLinkBitcode.shorthand()
2182                    ));
2183                }
2184                output_types.insert(output_type, path);
2185            }
2186        }
2187    };
2188    if output_types.is_empty() {
2189        output_types.insert(OutputType::Exe, None);
2190    }
2191    OutputTypes(output_types)
2192}
2193
2194fn split_out_file_name(arg: &str) -> (&str, Option<OutFileName>) {
2195    match arg.split_once('=') {
2196        None => (arg, None),
2197        Some((kind, "-")) => (kind, Some(OutFileName::Stdout)),
2198        Some((kind, path)) => (kind, Some(OutFileName::Real(PathBuf::from(path)))),
2199    }
2200}
2201
2202fn should_override_cgus_and_disable_thinlto(
2203    early_dcx: &EarlyDiagCtxt,
2204    output_types: &OutputTypes,
2205    matches: &getopts::Matches,
2206    mut codegen_units: Option<usize>,
2207) -> (bool, Option<usize>) {
2208    let mut disable_local_thinlto = false;
2209    // Issue #30063: if user requests LLVM-related output to one
2210    // particular path, disable codegen-units.
2211    let incompatible: Vec<_> = output_types
2212        .0
2213        .iter()
2214        .map(|ot_path| ot_path.0)
2215        .filter(|ot| !ot.is_compatible_with_codegen_units_and_single_output_file())
2216        .map(|ot| ot.shorthand())
2217        .collect();
2218    if !incompatible.is_empty() {
2219        match codegen_units {
2220            Some(n) if n > 1 => {
2221                if matches.opt_present("o") {
2222                    for ot in &incompatible {
2223                        early_dcx.early_warn(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`--emit={0}` with `-o` incompatible with `-C codegen-units=N` for N > 1",
                ot))
    })format!(
2224                            "`--emit={ot}` with `-o` incompatible with \
2225                                 `-C codegen-units=N` for N > 1",
2226                        ));
2227                    }
2228                    early_dcx.early_warn("resetting to default -C codegen-units=1");
2229                    codegen_units = Some(1);
2230                    disable_local_thinlto = true;
2231                }
2232            }
2233            _ => {
2234                codegen_units = Some(1);
2235                disable_local_thinlto = true;
2236            }
2237        }
2238    }
2239
2240    if codegen_units == Some(0) {
2241        early_dcx.early_fatal("value for codegen units must be a positive non-zero integer");
2242    }
2243
2244    (disable_local_thinlto, codegen_units)
2245}
2246
2247pub fn parse_target_triple(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> TargetTuple {
2248    match matches.opt_str("target") {
2249        Some(target) if target.ends_with(".json") => {
2250            let path = Path::new(&target);
2251            TargetTuple::from_path(path).unwrap_or_else(|_| {
2252                early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("target file {0:?} does not exist",
                path))
    })format!("target file {path:?} does not exist"))
2253            })
2254        }
2255        Some(target) => TargetTuple::TargetTuple(target),
2256        _ => TargetTuple::from_tuple(host_tuple()),
2257    }
2258}
2259
2260fn parse_opt_level(
2261    early_dcx: &EarlyDiagCtxt,
2262    matches: &getopts::Matches,
2263    cg: &CodegenOptions,
2264) -> OptLevel {
2265    // The `-O` and `-C opt-level` flags specify the same setting, so we want to be able
2266    // to use them interchangeably. However, because they're technically different flags,
2267    // we need to work out manually which should take precedence if both are supplied (i.e.
2268    // the rightmost flag). We do this by finding the (rightmost) position of both flags and
2269    // comparing them. Note that if a flag is not found, its position will be `None`, which
2270    // always compared less than `Some(_)`.
2271    let max_o = matches.opt_positions("O").into_iter().max();
2272    let max_c = matches
2273        .opt_strs_pos("C")
2274        .into_iter()
2275        .flat_map(|(i, s)| {
2276            // NB: This can match a string without `=`.
2277            if let Some("opt-level") = s.split('=').next() { Some(i) } else { None }
2278        })
2279        .max();
2280    if max_o > max_c {
2281        OptLevel::Aggressive
2282    } else {
2283        match cg.opt_level.as_ref() {
2284            "0" => OptLevel::No,
2285            "1" => OptLevel::Less,
2286            "2" => OptLevel::More,
2287            "3" => OptLevel::Aggressive,
2288            "s" => OptLevel::Size,
2289            "z" => OptLevel::SizeMin,
2290            arg => {
2291                early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("optimization level needs to be between 0-3, s or z (instead was `{0}`)",
                arg))
    })format!(
2292                    "optimization level needs to be \
2293                            between 0-3, s or z (instead was `{arg}`)"
2294                ));
2295            }
2296        }
2297    }
2298}
2299
2300fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInfo {
2301    let max_g = matches.opt_positions("g").into_iter().max();
2302    let max_c = matches
2303        .opt_strs_pos("C")
2304        .into_iter()
2305        .flat_map(|(i, s)| {
2306            // NB: This can match a string without `=`.
2307            if let Some("debuginfo") = s.split('=').next() { Some(i) } else { None }
2308        })
2309        .max();
2310    if max_g > max_c { DebugInfo::Full } else { cg.debuginfo }
2311}
2312
2313pub fn parse_externs(
2314    early_dcx: &EarlyDiagCtxt,
2315    matches: &getopts::Matches,
2316    unstable_opts: &UnstableOptions,
2317) -> Externs {
2318    let is_unstable_enabled = unstable_opts.unstable_options;
2319    let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
2320    for arg in matches.opt_strs("extern") {
2321        let ExternOpt { crate_name: name, path, options } =
2322            split_extern_opt(early_dcx, unstable_opts, &arg).unwrap_or_else(|e| e.emit());
2323
2324        let entry = externs.entry(name.to_owned());
2325
2326        use std::collections::btree_map::Entry;
2327
2328        let entry = if let Some(path) = path {
2329            // --extern prelude_name=some_file.rlib
2330            let path = CanonicalizedPath::new(path);
2331            match entry {
2332                Entry::Vacant(vacant) => {
2333                    let files = BTreeSet::from_iter(iter::once(path));
2334                    vacant.insert(ExternEntry::new(ExternLocation::ExactPaths(files)))
2335                }
2336                Entry::Occupied(occupied) => {
2337                    let ext_ent = occupied.into_mut();
2338                    match ext_ent {
2339                        ExternEntry { location: ExternLocation::ExactPaths(files), .. } => {
2340                            files.insert(path);
2341                        }
2342                        ExternEntry {
2343                            location: location @ ExternLocation::FoundInLibrarySearchDirectories,
2344                            ..
2345                        } => {
2346                            // Exact paths take precedence over search directories.
2347                            let files = BTreeSet::from_iter(iter::once(path));
2348                            *location = ExternLocation::ExactPaths(files);
2349                        }
2350                    }
2351                    ext_ent
2352                }
2353            }
2354        } else {
2355            // --extern prelude_name
2356            match entry {
2357                Entry::Vacant(vacant) => {
2358                    vacant.insert(ExternEntry::new(ExternLocation::FoundInLibrarySearchDirectories))
2359                }
2360                Entry::Occupied(occupied) => {
2361                    // Ignore if already specified.
2362                    occupied.into_mut()
2363                }
2364            }
2365        };
2366
2367        let mut is_private_dep = false;
2368        let mut add_prelude = true;
2369        let mut nounused_dep = false;
2370        let mut force = false;
2371        if let Some(opts) = options {
2372            if !is_unstable_enabled {
2373                early_dcx.early_fatal(
2374                    "the `-Z unstable-options` flag must also be passed to \
2375                     enable `--extern` options",
2376                );
2377            }
2378            for opt in opts.split(',') {
2379                match opt {
2380                    "priv" => is_private_dep = true,
2381                    "noprelude" => {
2382                        if let ExternLocation::ExactPaths(_) = &entry.location {
2383                            add_prelude = false;
2384                        } else {
2385                            early_dcx.early_fatal(
2386                                "the `noprelude` --extern option requires a file path",
2387                            );
2388                        }
2389                    }
2390                    "nounused" => nounused_dep = true,
2391                    "force" => force = true,
2392                    _ => early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown --extern option `{0}`",
                opt))
    })format!("unknown --extern option `{opt}`")),
2393                }
2394            }
2395        }
2396
2397        // Crates start out being not private, and go to being private `priv`
2398        // is specified.
2399        entry.is_private_dep |= is_private_dep;
2400        // likewise `nounused`
2401        entry.nounused_dep |= nounused_dep;
2402        // and `force`
2403        entry.force |= force;
2404        // If any flag is missing `noprelude`, then add to the prelude.
2405        entry.add_prelude |= add_prelude;
2406    }
2407    Externs(externs)
2408}
2409
2410fn parse_remap_path_prefix(
2411    early_dcx: &EarlyDiagCtxt,
2412    matches: &getopts::Matches,
2413) -> Vec<(PathBuf, PathBuf)> {
2414    matches
2415        .opt_strs("remap-path-prefix")
2416        .into_iter()
2417        .map(|remap| match remap.rsplit_once('=') {
2418            None => {
2419                early_dcx.early_fatal("--remap-path-prefix must contain '=' between FROM and TO")
2420            }
2421            Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)),
2422        })
2423        .collect()
2424}
2425
2426fn parse_logical_env(
2427    early_dcx: &EarlyDiagCtxt,
2428    matches: &getopts::Matches,
2429) -> FxIndexMap<String, String> {
2430    let mut vars = FxIndexMap::default();
2431
2432    for arg in matches.opt_strs("env-set") {
2433        if let Some((name, val)) = arg.split_once('=') {
2434            vars.insert(name.to_string(), val.to_string());
2435        } else {
2436            early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("`--env-set`: specify value for variable `{0}`",
                arg))
    })format!("`--env-set`: specify value for variable `{arg}`"));
2437        }
2438    }
2439
2440    vars
2441}
2442
2443// JUSTIFICATION: before wrapper fn is available
2444#[allow(rustc::bad_opt_access)]
2445pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::Matches) -> Options {
2446    let color = parse_color(early_dcx, matches);
2447
2448    let edition = parse_crate_edition(early_dcx, matches);
2449
2450    let crate_name = matches.opt_str("crate-name");
2451    let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
2452    let JsonConfig {
2453        json_rendered,
2454        json_color,
2455        json_artifact_notifications,
2456        json_timings,
2457        json_unused_externs,
2458        json_future_incompat,
2459    } = parse_json(early_dcx, matches);
2460
2461    let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered);
2462
2463    early_dcx.set_error_format(error_format);
2464
2465    let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
2466        early_dcx.early_fatal("`--diagnostic-width` must be an positive integer");
2467    });
2468
2469    let unparsed_crate_types = matches.opt_strs("crate-type");
2470    let crate_types = parse_crate_types_from_list(unparsed_crate_types)
2471        .unwrap_or_else(|e| early_dcx.early_fatal(e));
2472
2473    let mut collected_options = Default::default();
2474
2475    let mut unstable_opts = UnstableOptions::build(early_dcx, matches, &mut collected_options);
2476
2477    if unstable_opts.staticlib_hide_internal_symbols && !crate_types.contains(&CrateType::StaticLib)
2478    {
2479        early_dcx.early_warn(
2480            "-Zstaticlib-hide-internal-symbols has no effect without `--crate-type staticlib`",
2481        );
2482    }
2483
2484    if unstable_opts.staticlib_rename_internal_symbols
2485        && !crate_types.contains(&CrateType::StaticLib)
2486    {
2487        early_dcx.early_warn(
2488            "-Zstaticlib-rename-internal-symbols has no effect without `--crate-type staticlib`",
2489        );
2490    }
2491
2492    let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches);
2493
2494    if !unstable_opts.unstable_options && json_timings {
2495        early_dcx.early_fatal("--json=timings is unstable and requires using `-Zunstable-options`");
2496    }
2497
2498    check_error_format_stability(
2499        early_dcx,
2500        &unstable_opts,
2501        unstable_features.is_nightly_build(),
2502        error_format,
2503    );
2504
2505    let output_types = parse_output_types(early_dcx, &unstable_opts, matches);
2506
2507    let mut cg = CodegenOptions::build(early_dcx, matches, &mut collected_options);
2508    let (disable_local_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto(
2509        early_dcx,
2510        &output_types,
2511        matches,
2512        cg.codegen_units,
2513    );
2514
2515    if unstable_opts.threads == Some(parse::MAX_THREADS_CAP) {
2516        early_dcx.early_warn(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("number of threads was capped at {0}",
                parse::MAX_THREADS_CAP))
    })format!("number of threads was capped at {}", parse::MAX_THREADS_CAP));
2517    }
2518
2519    let incremental = cg.incremental.as_ref().map(PathBuf::from);
2520
2521    if cg.profile_generate.enabled() && cg.profile_use.is_some() {
2522        early_dcx.early_fatal("options `-C profile-generate` and `-C profile-use` are exclusive");
2523    }
2524
2525    if unstable_opts.profile_sample_use.is_some()
2526        && (cg.profile_generate.enabled() || cg.profile_use.is_some())
2527    {
2528        early_dcx.early_fatal(
2529            "option `-Z profile-sample-use` cannot be used with `-C profile-generate` or `-C profile-use`",
2530        );
2531    }
2532
2533    // Check for unstable values of `-C symbol-mangling-version`.
2534    // This is what prevents them from being used on stable compilers.
2535    match cg.symbol_mangling_version {
2536        // Stable values:
2537        None | Some(SymbolManglingVersion::V0) => {}
2538
2539        // Unstable values:
2540        Some(SymbolManglingVersion::Legacy) => {
2541            if !unstable_opts.unstable_options {
2542                early_dcx.early_fatal(
2543                    "`-C symbol-mangling-version=legacy` requires `-Z unstable-options`",
2544                );
2545            }
2546        }
2547        Some(SymbolManglingVersion::Hashed) => {
2548            if !unstable_opts.unstable_options {
2549                early_dcx.early_fatal(
2550                    "`-C symbol-mangling-version=hashed` requires `-Z unstable-options`",
2551                );
2552            }
2553        }
2554    }
2555
2556    if cg.instrument_coverage != InstrumentCoverage::No {
2557        if cg.profile_generate.enabled() || cg.profile_use.is_some() {
2558            early_dcx.early_fatal(
2559                "option `-C instrument-coverage` is not compatible with either `-C profile-use` \
2560                or `-C profile-generate`",
2561            );
2562        }
2563
2564        // `-C instrument-coverage` implies `-C symbol-mangling-version=v0` - to ensure consistent
2565        // and reversible name mangling. Note, LLVM coverage tools can analyze coverage over
2566        // multiple runs, including some changes to source code; so mangled names must be consistent
2567        // across compilations.
2568        match cg.symbol_mangling_version {
2569            None => cg.symbol_mangling_version = Some(SymbolManglingVersion::V0),
2570            Some(SymbolManglingVersion::Legacy) => {
2571                early_dcx.early_warn(
2572                    "-C instrument-coverage requires symbol mangling version `v0`, \
2573                    but `-C symbol-mangling-version=legacy` was specified",
2574                );
2575            }
2576            Some(SymbolManglingVersion::V0) => {}
2577            Some(SymbolManglingVersion::Hashed) => {
2578                early_dcx.early_warn(
2579                    "-C instrument-coverage requires symbol mangling version `v0`, \
2580                    but `-C symbol-mangling-version=hashed` was specified",
2581                );
2582            }
2583        }
2584    }
2585
2586    if let Ok(graphviz_font) = std::env::var("RUSTC_GRAPHVIZ_FONT") {
2587        // FIXME: this is only mutation of UnstableOptions here, move into
2588        // UnstableOptions::build?
2589        unstable_opts.graphviz_font = graphviz_font;
2590    }
2591
2592    if !cg.embed_bitcode {
2593        match cg.lto {
2594            LtoCli::No | LtoCli::Unspecified => {}
2595            LtoCli::Yes | LtoCli::NoParam | LtoCli::Thin | LtoCli::Fat => {
2596                early_dcx.early_fatal("options `-C embed-bitcode=no` and `-C lto` are incompatible")
2597            }
2598        }
2599    }
2600
2601    let unstable_options_enabled = nightly_options::is_unstable_enabled(matches);
2602    if !unstable_options_enabled && cg.force_frame_pointers == FramePointer::NonLeaf {
2603        early_dcx.early_fatal(
2604            "`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \
2605                and a nightly compiler",
2606        )
2607    }
2608
2609    if !nightly_options::is_unstable_enabled(matches) && !unstable_opts.offload.is_empty() {
2610        early_dcx.early_fatal(
2611            "`-Zoffload=Enable` also requires `-Zunstable-options` \
2612                and a nightly compiler",
2613        )
2614    }
2615
2616    let target_triple = parse_target_triple(early_dcx, matches);
2617
2618    // Ensure `-Z unstable-options` is required when using the unstable `-C link-self-contained` and
2619    // `-C linker-flavor` options.
2620    if !unstable_options_enabled {
2621        if let Err(error) = cg.link_self_contained.check_unstable_variants(&target_triple) {
2622            early_dcx.early_fatal(error);
2623        }
2624
2625        if let Some(flavor) = cg.linker_flavor {
2626            if flavor.is_unstable() {
2627                early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the linker flavor `{0}` is unstable, the `-Z unstable-options` flag must also be passed to use the unstable values",
                flavor.desc()))
    })format!(
2628                    "the linker flavor `{}` is unstable, the `-Z unstable-options` \
2629                        flag must also be passed to use the unstable values",
2630                    flavor.desc()
2631                ));
2632            }
2633        }
2634    }
2635
2636    // Check `-C link-self-contained` for consistency: individual components cannot be both enabled
2637    // and disabled at the same time.
2638    if let Some(erroneous_components) = cg.link_self_contained.check_consistency() {
2639        let names: String = erroneous_components
2640            .into_iter()
2641            .map(|c| c.as_str().unwrap())
2642            .intersperse(", ")
2643            .collect();
2644        early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("some `-C link-self-contained` components were both enabled and disabled: {0}",
                names))
    })format!(
2645            "some `-C link-self-contained` components were both enabled and disabled: {names}"
2646        ));
2647    }
2648
2649    let prints = print_request::collect_print_requests(early_dcx, &mut cg, &unstable_opts, matches);
2650
2651    // -Zretpoline-external-thunk also requires -Zretpoline
2652    if unstable_opts.retpoline_external_thunk {
2653        unstable_opts.retpoline = true;
2654        collected_options.target_modifiers.insert(
2655            OptionsTargetModifiers::UnstableOptions(UnstableOptionsTargetModifiers::Retpoline),
2656            "true".to_string(),
2657        );
2658    }
2659
2660    let cg = cg;
2661
2662    let opt_level = parse_opt_level(early_dcx, matches, &cg);
2663    // The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
2664    // to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
2665    // for more details.
2666    let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
2667    let debuginfo = select_debuginfo(matches, &cg);
2668
2669    if !unstable_options_enabled {
2670        if let Err(error) = cg.linker_features.check_unstable_variants(&target_triple) {
2671            early_dcx.early_fatal(error);
2672        }
2673    }
2674
2675    if !unstable_options_enabled && cg.panic == Some(PanicStrategy::ImmediateAbort) {
2676        early_dcx.early_fatal(
2677            "`-Cpanic=immediate-abort` requires `-Zunstable-options` and a nightly compiler",
2678        )
2679    }
2680
2681    // Parse any `-l` flags, which link to native libraries.
2682    let libs = parse_native_libs(early_dcx, &unstable_opts, unstable_features, matches);
2683
2684    let test = matches.opt_present("test");
2685
2686    if !cg.remark.is_empty() && debuginfo == DebugInfo::None {
2687        early_dcx.early_warn("-C remark requires \"-C debuginfo=n\" to show source locations");
2688    }
2689
2690    if cg.remark.is_empty() && unstable_opts.remark_dir.is_some() {
2691        early_dcx
2692            .early_warn("using -Z remark-dir without enabling remarks using e.g. -C remark=all");
2693    }
2694
2695    let externs = parse_externs(early_dcx, matches, &unstable_opts);
2696
2697    let remap_path_prefix = parse_remap_path_prefix(early_dcx, matches);
2698    let remap_path_scope = parse_remap_path_scope(early_dcx, matches, &unstable_opts);
2699
2700    let pretty = parse_pretty(early_dcx, &unstable_opts);
2701
2702    // query-dep-graph is required if dump-dep-graph is given #106736
2703    if unstable_opts.dump_dep_graph && !unstable_opts.query_dep_graph {
2704        early_dcx.early_fatal("can't dump dependency graph without `-Z query-dep-graph`");
2705    }
2706
2707    let logical_env = parse_logical_env(early_dcx, matches);
2708
2709    let sysroot = Sysroot::new(matches.opt_str("sysroot").map(PathBuf::from));
2710
2711    let real_source_base_dir = |suffix: &str, confirm: &str| {
2712        let mut candidate = sysroot.path().join(suffix);
2713        if let Ok(metadata) = candidate.symlink_metadata() {
2714            // Replace the symlink bootstrap creates, with its destination.
2715            // We could try to use `fs::canonicalize` instead, but that might
2716            // produce unnecessarily verbose path.
2717            if metadata.file_type().is_symlink() {
2718                if let Ok(symlink_dest) = std::fs::read_link(&candidate) {
2719                    candidate = symlink_dest;
2720                }
2721            }
2722        }
2723
2724        // Only use this directory if it has a file we can expect to always find.
2725        candidate.join(confirm).is_file().then_some(candidate)
2726    };
2727
2728    let real_rust_source_base_dir =
2729        // This is the location used by the `rust-src` `rustup` component.
2730        real_source_base_dir("lib/rustlib/src/rust", "library/std/src/lib.rs");
2731
2732    let real_rustc_dev_source_base_dir =
2733        // This is the location used by the `rustc-dev` `rustup` component.
2734        real_source_base_dir("lib/rustlib/rustc-src/rust", "compiler/rustc/src/main.rs");
2735
2736    // We eagerly scan all files in each passed -L path. If the same directory is passed multiple
2737    // times, and the directory contains a lot of files, this can take a lot of time.
2738    // So we remove -L paths that were passed multiple times, and keep only the first occurrence.
2739    // We still have to keep the original order of the -L arguments.
2740    let search_paths: Vec<SearchPath> = {
2741        let mut seen_search_paths = FxHashSet::default();
2742        let search_path_matches: Vec<String> = matches.opt_strs("L");
2743        search_path_matches
2744            .iter()
2745            .filter(|p| seen_search_paths.insert(*p))
2746            .map(|path| {
2747                SearchPath::from_cli_opt(
2748                    sysroot.path(),
2749                    &target_triple,
2750                    early_dcx,
2751                    &path,
2752                    unstable_opts.unstable_options,
2753                )
2754            })
2755            .collect()
2756    };
2757
2758    // Ideally we would use `SourceMap::working_dir` instead, but we don't have access to it
2759    // so we manually create the potentially-remapped working directory
2760    let working_dir = {
2761        let working_dir = std::env::current_dir().unwrap_or_else(|e| {
2762            early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("Current directory is invalid: {0}",
                e))
    })format!("Current directory is invalid: {e}"));
2763        });
2764
2765        let file_mapping = file_path_mapping(
2766            remap_path_prefix.clone(),
2767            unstable_opts.remap_cwd_prefix.as_deref(),
2768            remap_path_scope,
2769        );
2770        file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
2771    };
2772
2773    let verbose = matches.opt_present("verbose") || unstable_opts.verbose_internals;
2774
2775    Options {
2776        crate_types,
2777        optimize: opt_level,
2778        debuginfo,
2779        lint_opts,
2780        lint_cap,
2781        describe_lints,
2782        output_types,
2783        search_paths,
2784        sysroot,
2785        target_triple,
2786        test,
2787        incremental,
2788        unstable_opts,
2789        prints,
2790        cg,
2791        error_format,
2792        diagnostic_width,
2793        externs,
2794        unstable_features,
2795        crate_name,
2796        libs,
2797        debug_assertions,
2798        actually_rustdoc: false,
2799        resolve_doc_links: ResolveDocLinks::ExportedMetadata,
2800        trimmed_def_paths: false,
2801        cli_forced_codegen_units: codegen_units,
2802        cli_forced_local_thinlto_off: disable_local_thinlto,
2803        remap_path_prefix,
2804        remap_path_scope,
2805        real_rust_source_base_dir,
2806        real_rustc_dev_source_base_dir,
2807        edition,
2808        json_artifact_notifications,
2809        json_timings,
2810        json_unused_externs,
2811        json_future_incompat,
2812        pretty,
2813        working_dir,
2814        color,
2815        logical_env,
2816        verbose,
2817        target_modifiers: collected_options.target_modifiers,
2818        mitigation_coverage_map: collected_options.mitigations,
2819    }
2820}
2821
2822fn parse_pretty(early_dcx: &EarlyDiagCtxt, unstable_opts: &UnstableOptions) -> Option<PpMode> {
2823    use PpMode::*;
2824
2825    let first = match unstable_opts.unpretty.as_deref()? {
2826        "normal" => Source(PpSourceMode::Normal),
2827        "expanded" => Source(PpSourceMode::Expanded),
2828        "expanded,identified" => Source(PpSourceMode::ExpandedIdentified),
2829        "expanded,hygiene" => Source(PpSourceMode::ExpandedHygiene),
2830        "ast-tree" => AstTree,
2831        "ast-tree,expanded" => AstTreeExpanded,
2832        "hir" => Hir(PpHirMode::Normal),
2833        "hir,identified" => Hir(PpHirMode::Identified),
2834        "hir,typed" => Hir(PpHirMode::Typed),
2835        "hir-tree" => HirTree,
2836        "thir-tree" => ThirTree,
2837        "thir-flat" => ThirFlat,
2838        "mir" => Mir,
2839        "stable-mir" => StableMir,
2840        "mir-cfg" => MirCFG,
2841        name => early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("argument to `unpretty` must be one of `normal`, `expanded`, `expanded,identified`, `expanded,hygiene`, `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, `hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir`, `stable-mir`, or `mir-cfg`; got {0}",
                name))
    })format!(
2842            "argument to `unpretty` must be one of `normal`, \
2843                            `expanded`, `expanded,identified`, `expanded,hygiene`, \
2844                            `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
2845                            `hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir`, `stable-mir`, or \
2846                            `mir-cfg`; got {name}"
2847        )),
2848    };
2849    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event compiler/rustc_session/src/config.rs:2849",
                        "rustc_session::config", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_session/src/config.rs"),
                        ::tracing_core::__macro_support::Option::Some(2849u32),
                        ::tracing_core::__macro_support::Option::Some("rustc_session::config"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::DEBUG <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                let mut iter = __CALLSITE.metadata().fields().iter();
                __CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
                                    ::tracing::__macro_support::Option::Some(&format_args!("got unpretty option: {0:?}",
                                                    first) as &dyn Value))])
            });
    } else { ; }
};debug!("got unpretty option: {first:?}");
2850    Some(first)
2851}
2852
2853pub fn make_crate_type_option() -> RustcOptGroup {
2854    make_opt(
2855        OptionStability::Stable,
2856        OptionKind::Multi,
2857        "",
2858        "crate-type",
2859        "Comma separated list of types of crates
2860                                for the compiler to emit",
2861        "<bin|lib|rlib|dylib|cdylib|staticlib|proc-macro>",
2862    )
2863}
2864
2865pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> {
2866    let mut crate_types: Vec<CrateType> = Vec::new();
2867    for unparsed_crate_type in &list_list {
2868        for part in unparsed_crate_type.split(',') {
2869            let new_part = match part {
2870                "lib" => CrateType::default(),
2871                "rlib" => CrateType::Rlib,
2872                "staticlib" => CrateType::StaticLib,
2873                "dylib" => CrateType::Dylib,
2874                "cdylib" => CrateType::Cdylib,
2875                "bin" => CrateType::Executable,
2876                "proc-macro" => CrateType::ProcMacro,
2877                "sdylib" => CrateType::Sdylib,
2878                _ => {
2879                    return Err(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown crate type: `{0}`, expected one of: `lib`, `rlib`, `staticlib`, `dylib`, `cdylib`, `bin`, `proc-macro`",
                part))
    })format!(
2880                        "unknown crate type: `{part}`, expected one of: \
2881                        `lib`, `rlib`, `staticlib`, `dylib`, `cdylib`, `bin`, `proc-macro`",
2882                    ));
2883                }
2884            };
2885            if !crate_types.contains(&new_part) {
2886                crate_types.push(new_part)
2887            }
2888        }
2889    }
2890
2891    Ok(crate_types)
2892}
2893
2894pub mod nightly_options {
2895    use rustc_feature::UnstableFeatures;
2896
2897    use super::{OptionStability, RustcOptGroup};
2898    use crate::EarlyDiagCtxt;
2899
2900    pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
2901        match_is_nightly_build(matches)
2902            && matches.opt_strs("Z").iter().any(|x| *x == "unstable-options")
2903    }
2904
2905    pub fn match_is_nightly_build(matches: &getopts::Matches) -> bool {
2906        is_nightly_build(matches.opt_str("crate-name").as_deref())
2907    }
2908
2909    fn is_nightly_build(krate: Option<&str>) -> bool {
2910        UnstableFeatures::from_environment(krate).is_nightly_build()
2911    }
2912
2913    pub fn check_nightly_options(
2914        early_dcx: &EarlyDiagCtxt,
2915        matches: &getopts::Matches,
2916        flags: &[RustcOptGroup],
2917    ) {
2918        let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options");
2919        let really_allows_unstable_options = match_is_nightly_build(matches);
2920        let mut nightly_options_on_stable = 0;
2921
2922        for opt in flags.iter() {
2923            if opt.stability == OptionStability::Stable {
2924                continue;
2925            }
2926            if !matches.opt_present(opt.name) {
2927                continue;
2928            }
2929            if opt.name != "Z" && !has_z_unstable_option {
2930                early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the `-Z unstable-options` flag must also be passed to enable the flag `{0}`",
                opt.name))
    })format!(
2931                    "the `-Z unstable-options` flag must also be passed to enable \
2932                         the flag `{}`",
2933                    opt.name
2934                ));
2935            }
2936            if really_allows_unstable_options {
2937                continue;
2938            }
2939            match opt.stability {
2940                OptionStability::Unstable => {
2941                    nightly_options_on_stable += 1;
2942                    let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the option `{0}` is only accepted on the nightly compiler",
                opt.name))
    })format!(
2943                        "the option `{}` is only accepted on the nightly compiler",
2944                        opt.name
2945                    );
2946                    // The non-zero nightly_options_on_stable will force an early_fatal eventually.
2947                    let _ = early_dcx.early_err(msg);
2948                }
2949                OptionStability::Stable => {}
2950            }
2951        }
2952        if nightly_options_on_stable > 0 {
2953            early_dcx
2954                .early_help("consider switching to a nightly toolchain: `rustup default nightly`");
2955            early_dcx.early_note("selecting a toolchain with `+toolchain` arguments require a rustup proxy; see <https://rust-lang.github.io/rustup/concepts/index.html>");
2956            early_dcx.early_note("for more information about Rust's stability policy, see <https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#unstable-features>");
2957            early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} nightly option{1} were parsed",
                nightly_options_on_stable,
                if nightly_options_on_stable > 1 { "s" } else { "" }))
    })format!(
2958                "{} nightly option{} were parsed",
2959                nightly_options_on_stable,
2960                if nightly_options_on_stable > 1 { "s" } else { "" }
2961            ));
2962        }
2963    }
2964}
2965
2966#[derive(#[automatically_derived]
impl ::core::marker::Copy for PpSourceMode { }Copy, #[automatically_derived]
impl ::core::clone::Clone for PpSourceMode {
    #[inline]
    fn clone(&self) -> PpSourceMode { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for PpSourceMode {
    #[inline]
    fn eq(&self, other: &PpSourceMode) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for PpSourceMode {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                PpSourceMode::Normal => "Normal",
                PpSourceMode::Expanded => "Expanded",
                PpSourceMode::ExpandedIdentified => "ExpandedIdentified",
                PpSourceMode::ExpandedHygiene => "ExpandedHygiene",
            })
    }
}Debug)]
2967pub enum PpSourceMode {
2968    /// `-Zunpretty=normal`
2969    Normal,
2970    /// `-Zunpretty=expanded`
2971    Expanded,
2972    /// `-Zunpretty=expanded,identified`
2973    ExpandedIdentified,
2974    /// `-Zunpretty=expanded,hygiene`
2975    ExpandedHygiene,
2976}
2977
2978#[derive(#[automatically_derived]
impl ::core::marker::Copy for PpHirMode { }Copy, #[automatically_derived]
impl ::core::clone::Clone for PpHirMode {
    #[inline]
    fn clone(&self) -> PpHirMode { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for PpHirMode {
    #[inline]
    fn eq(&self, other: &PpHirMode) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for PpHirMode {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                PpHirMode::Normal => "Normal",
                PpHirMode::Identified => "Identified",
                PpHirMode::Typed => "Typed",
            })
    }
}Debug)]
2979pub enum PpHirMode {
2980    /// `-Zunpretty=hir`
2981    Normal,
2982    /// `-Zunpretty=hir,identified`
2983    Identified,
2984    /// `-Zunpretty=hir,typed`
2985    Typed,
2986}
2987
2988#[derive(#[automatically_derived]
impl ::core::marker::Copy for PpMode { }Copy, #[automatically_derived]
impl ::core::clone::Clone for PpMode {
    #[inline]
    fn clone(&self) -> PpMode {
        let _: ::core::clone::AssertParamIsClone<PpSourceMode>;
        let _: ::core::clone::AssertParamIsClone<PpHirMode>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for PpMode {
    #[inline]
    fn eq(&self, other: &PpMode) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (PpMode::Source(__self_0), PpMode::Source(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (PpMode::Hir(__self_0), PpMode::Hir(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for PpMode {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            PpMode::Source(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Source",
                    &__self_0),
            PpMode::AstTree =>
                ::core::fmt::Formatter::write_str(f, "AstTree"),
            PpMode::AstTreeExpanded =>
                ::core::fmt::Formatter::write_str(f, "AstTreeExpanded"),
            PpMode::Hir(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Hir",
                    &__self_0),
            PpMode::HirTree =>
                ::core::fmt::Formatter::write_str(f, "HirTree"),
            PpMode::ThirTree =>
                ::core::fmt::Formatter::write_str(f, "ThirTree"),
            PpMode::ThirFlat =>
                ::core::fmt::Formatter::write_str(f, "ThirFlat"),
            PpMode::Mir => ::core::fmt::Formatter::write_str(f, "Mir"),
            PpMode::MirCFG => ::core::fmt::Formatter::write_str(f, "MirCFG"),
            PpMode::StableMir =>
                ::core::fmt::Formatter::write_str(f, "StableMir"),
        }
    }
}Debug)]
2989/// Pretty print mode
2990pub enum PpMode {
2991    /// Options that print the source code, i.e.
2992    /// `-Zunpretty=normal` and `-Zunpretty=expanded`
2993    Source(PpSourceMode),
2994    /// `-Zunpretty=ast-tree`
2995    AstTree,
2996    /// `-Zunpretty=ast-tree,expanded`
2997    AstTreeExpanded,
2998    /// Options that print the HIR, i.e. `-Zunpretty=hir`
2999    Hir(PpHirMode),
3000    /// `-Zunpretty=hir-tree`
3001    HirTree,
3002    /// `-Zunpretty=thir-tree`
3003    ThirTree,
3004    /// `-Zunpretty=thir-flat`
3005    ThirFlat,
3006    /// `-Zunpretty=mir`
3007    Mir,
3008    /// `-Zunpretty=mir-cfg`
3009    MirCFG,
3010    /// `-Zunpretty=stable-mir`
3011    StableMir,
3012}
3013
3014impl PpMode {
3015    pub fn needs_ast_map(&self) -> bool {
3016        use PpMode::*;
3017        use PpSourceMode::*;
3018        match *self {
3019            Source(Normal) | AstTree => false,
3020
3021            Source(Expanded | ExpandedIdentified | ExpandedHygiene)
3022            | AstTreeExpanded
3023            | Hir(_)
3024            | HirTree
3025            | ThirTree
3026            | ThirFlat
3027            | Mir
3028            | MirCFG
3029            | StableMir => true,
3030        }
3031    }
3032
3033    pub fn needs_analysis(&self) -> bool {
3034        use PpMode::*;
3035        #[allow(non_exhaustive_omitted_patterns)] match *self {
    Hir(PpHirMode::Typed) | Mir | StableMir | MirCFG | ThirTree | ThirFlat =>
        true,
    _ => false,
}matches!(*self, Hir(PpHirMode::Typed) | Mir | StableMir | MirCFG | ThirTree | ThirFlat)
3036    }
3037}
3038
3039#[derive(#[automatically_derived]
impl ::core::clone::Clone for WasiExecModel {
    #[inline]
    fn clone(&self) -> WasiExecModel {
        match self {
            WasiExecModel::Command => WasiExecModel::Command,
            WasiExecModel::Reactor => WasiExecModel::Reactor,
        }
    }
}Clone, #[automatically_derived]
impl ::core::hash::Hash for WasiExecModel {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for WasiExecModel {
    #[inline]
    fn eq(&self, other: &WasiExecModel) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for WasiExecModel {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for WasiExecModel {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                WasiExecModel::Command => "Command",
                WasiExecModel::Reactor => "Reactor",
            })
    }
}Debug)]
3040pub enum WasiExecModel {
3041    Command,
3042    Reactor,
3043}
3044
3045/// Command-line arguments passed to the compiler have to be incorporated with
3046/// the dependency tracking system for incremental compilation. This module
3047/// provides some utilities to make this more convenient.
3048///
3049/// The values of all command-line arguments that are relevant for dependency
3050/// tracking are hashed into a single value that determines whether the
3051/// incremental compilation cache can be re-used or not. This hashing is done
3052/// via the `DepTrackingHash` trait defined below, since the standard `Hash`
3053/// implementation might not be suitable (e.g., arguments are stored in a `Vec`,
3054/// the hash of which is order dependent, but we might not want the order of
3055/// arguments to make a difference for the hash).
3056///
3057/// However, since the value provided by `Hash::hash` often *is* suitable,
3058/// especially for primitive types, there is the
3059/// `impl_dep_tracking_hash_via_hash!()` macro that allows to simply reuse the
3060/// `Hash` implementation for `DepTrackingHash`. It's important though that
3061/// we have an opt-in scheme here, so one is hopefully forced to think about
3062/// how the hash should be calculated when adding a new command-line argument.
3063pub(crate) mod dep_tracking {
3064    use std::collections::BTreeMap;
3065    use std::hash::Hash;
3066    use std::num::NonZero;
3067    use std::path::PathBuf;
3068
3069    use rustc_abi::Align;
3070    use rustc_ast::attr::version::RustcVersion;
3071    use rustc_data_structures::fx::FxIndexMap;
3072    use rustc_data_structures::stable_hash::StableHasher;
3073    use rustc_errors::LanguageIdentifier;
3074    use rustc_feature::UnstableFeatures;
3075    use rustc_hashes::Hash64;
3076    use rustc_hir::attrs::CollapseMacroDebuginfo;
3077    use rustc_span::edition::Edition;
3078    use rustc_span::{RealFileName, RemapPathScopeComponents};
3079    use rustc_target::spec::{
3080        CodeModel, FramePointer, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel,
3081        RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility, TargetTuple,
3082        TlsModel,
3083    };
3084
3085    use super::{
3086        AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CodegenRetagOptions,
3087        CoverageOptions, CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug,
3088        FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto,
3089        LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel,
3090        OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks,
3091        SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
3092        WasiExecModel,
3093    };
3094    use crate::lint;
3095    use crate::utils::NativeLib;
3096
3097    pub(crate) trait DepTrackingHash {
3098        fn hash(
3099            &self,
3100            hasher: &mut StableHasher,
3101            error_format: ErrorOutputType,
3102            for_crate_hash: bool,
3103        );
3104    }
3105
3106    macro_rules! impl_dep_tracking_hash_via_hash {
3107        ($($t:ty),+ $(,)?) => {$(
3108            impl DepTrackingHash for $t {
3109                fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType, _for_crate_hash: bool) {
3110                    Hash::hash(self, hasher);
3111                }
3112            }
3113        )+};
3114    }
3115
3116    impl<T: DepTrackingHash> DepTrackingHash for Option<T> {
3117        fn hash(
3118            &self,
3119            hasher: &mut StableHasher,
3120            error_format: ErrorOutputType,
3121            for_crate_hash: bool,
3122        ) {
3123            match self {
3124                Some(x) => {
3125                    Hash::hash(&1, hasher);
3126                    DepTrackingHash::hash(x, hasher, error_format, for_crate_hash);
3127                }
3128                None => Hash::hash(&0, hasher),
3129            }
3130        }
3131    }
3132
3133    impl DepTrackingHash for RustcVersion {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}impl_dep_tracking_hash_via_hash!(
3134        (),
3135        AnnotateMoves,
3136        AutoDiff,
3137        Offload,
3138        bool,
3139        usize,
3140        NonZero<usize>,
3141        u64,
3142        Hash64,
3143        String,
3144        PathBuf,
3145        lint::Level,
3146        WasiExecModel,
3147        u32,
3148        FramePointer,
3149        RelocModel,
3150        CodeModel,
3151        TlsModel,
3152        InstrumentCoverage,
3153        CoverageOptions,
3154        InstrumentXRay,
3155        CrateType,
3156        MergeFunctions,
3157        OnBrokenPipe,
3158        PanicStrategy,
3159        RelroLevel,
3160        OptLevel,
3161        LtoCli,
3162        DebugInfo,
3163        DebugInfoCompression,
3164        MirStripDebugInfo,
3165        CollapseMacroDebuginfo,
3166        UnstableFeatures,
3167        NativeLib,
3168        SanitizerSet,
3169        CFGuard,
3170        CFProtection,
3171        TargetTuple,
3172        Edition,
3173        LinkerPluginLto,
3174        ResolveDocLinks,
3175        SplitDebuginfo,
3176        SplitDwarfKind,
3177        StackProtector,
3178        SwitchWithOptPath,
3179        SymbolManglingVersion,
3180        SymbolVisibility,
3181        RemapPathScopeComponents,
3182        SourceFileHashAlgorithm,
3183        OutFileName,
3184        OutputType,
3185        RealFileName,
3186        LocationDetail,
3187        FmtDebug,
3188        BranchProtection,
3189        LanguageIdentifier,
3190        NextSolverConfig,
3191        PatchableFunctionEntry,
3192        Polonius,
3193        InliningThreshold,
3194        FunctionReturn,
3195        Align,
3196        CodegenRetagOptions,
3197        RustcVersion,
3198    );
3199
3200    impl<T1, T2> DepTrackingHash for (T1, T2)
3201    where
3202        T1: DepTrackingHash,
3203        T2: DepTrackingHash,
3204    {
3205        fn hash(
3206            &self,
3207            hasher: &mut StableHasher,
3208            error_format: ErrorOutputType,
3209            for_crate_hash: bool,
3210        ) {
3211            Hash::hash(&0, hasher);
3212            DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash);
3213            Hash::hash(&1, hasher);
3214            DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash);
3215        }
3216    }
3217
3218    impl<T1, T2, T3> DepTrackingHash for (T1, T2, T3)
3219    where
3220        T1: DepTrackingHash,
3221        T2: DepTrackingHash,
3222        T3: DepTrackingHash,
3223    {
3224        fn hash(
3225            &self,
3226            hasher: &mut StableHasher,
3227            error_format: ErrorOutputType,
3228            for_crate_hash: bool,
3229        ) {
3230            Hash::hash(&0, hasher);
3231            DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash);
3232            Hash::hash(&1, hasher);
3233            DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash);
3234            Hash::hash(&2, hasher);
3235            DepTrackingHash::hash(&self.2, hasher, error_format, for_crate_hash);
3236        }
3237    }
3238
3239    impl<T: DepTrackingHash> DepTrackingHash for Vec<T> {
3240        fn hash(
3241            &self,
3242            hasher: &mut StableHasher,
3243            error_format: ErrorOutputType,
3244            for_crate_hash: bool,
3245        ) {
3246            Hash::hash(&self.len(), hasher);
3247            for (index, elem) in self.iter().enumerate() {
3248                Hash::hash(&index, hasher);
3249                DepTrackingHash::hash(elem, hasher, error_format, for_crate_hash);
3250            }
3251        }
3252    }
3253
3254    impl<T: DepTrackingHash, V: DepTrackingHash> DepTrackingHash for FxIndexMap<T, V> {
3255        fn hash(
3256            &self,
3257            hasher: &mut StableHasher,
3258            error_format: ErrorOutputType,
3259            for_crate_hash: bool,
3260        ) {
3261            Hash::hash(&self.len(), hasher);
3262            for (key, value) in self.iter() {
3263                DepTrackingHash::hash(key, hasher, error_format, for_crate_hash);
3264                DepTrackingHash::hash(value, hasher, error_format, for_crate_hash);
3265            }
3266        }
3267    }
3268
3269    impl DepTrackingHash for OutputTypes {
3270        fn hash(
3271            &self,
3272            hasher: &mut StableHasher,
3273            error_format: ErrorOutputType,
3274            for_crate_hash: bool,
3275        ) {
3276            Hash::hash(&self.0.len(), hasher);
3277            for (key, val) in &self.0 {
3278                DepTrackingHash::hash(key, hasher, error_format, for_crate_hash);
3279                if !for_crate_hash {
3280                    DepTrackingHash::hash(val, hasher, error_format, for_crate_hash);
3281                }
3282            }
3283        }
3284    }
3285
3286    // This is a stable hash because BTreeMap is a sorted container
3287    pub(crate) fn stable_hash(
3288        sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>,
3289        hasher: &mut StableHasher,
3290        error_format: ErrorOutputType,
3291        for_crate_hash: bool,
3292    ) {
3293        for (key, sub_hash) in sub_hashes {
3294            // Using Hash::hash() instead of DepTrackingHash::hash() is fine for
3295            // the keys, as they are just plain strings
3296            Hash::hash(&key.len(), hasher);
3297            Hash::hash(key, hasher);
3298            sub_hash.hash(hasher, error_format, for_crate_hash);
3299        }
3300    }
3301}
3302
3303/// How to run proc-macro code when building this crate
3304#[derive(#[automatically_derived]
impl ::core::clone::Clone for ProcMacroExecutionStrategy {
    #[inline]
    fn clone(&self) -> ProcMacroExecutionStrategy { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for ProcMacroExecutionStrategy { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for ProcMacroExecutionStrategy {
    #[inline]
    fn eq(&self, other: &ProcMacroExecutionStrategy) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for ProcMacroExecutionStrategy {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for ProcMacroExecutionStrategy {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                ProcMacroExecutionStrategy::SameThread => "SameThread",
                ProcMacroExecutionStrategy::CrossThread => "CrossThread",
            })
    }
}Debug)]
3305pub enum ProcMacroExecutionStrategy {
3306    /// Run the proc-macro code on the same thread as the server.
3307    SameThread,
3308
3309    /// Run the proc-macro code on a different thread.
3310    CrossThread,
3311}
3312
3313/// Which format to use for `-Z dump-mono-stats`
3314#[derive(#[automatically_derived]
impl ::core::clone::Clone for DumpMonoStatsFormat {
    #[inline]
    fn clone(&self) -> DumpMonoStatsFormat { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for DumpMonoStatsFormat { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for DumpMonoStatsFormat {
    #[inline]
    fn eq(&self, other: &DumpMonoStatsFormat) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for DumpMonoStatsFormat {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for DumpMonoStatsFormat {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                DumpMonoStatsFormat::Markdown => "Markdown",
                DumpMonoStatsFormat::Json => "Json",
            })
    }
}Debug)]
3315pub enum DumpMonoStatsFormat {
3316    /// Pretty-print a markdown table
3317    Markdown,
3318    /// Emit structured JSON
3319    Json,
3320}
3321
3322impl DumpMonoStatsFormat {
3323    pub fn extension(self) -> &'static str {
3324        match self {
3325            Self::Markdown => "md",
3326            Self::Json => "json",
3327        }
3328    }
3329}
3330
3331/// `-Z patchable-function-entry` representation - how many nops to put before and after function
3332/// entry.
3333#[derive(#[automatically_derived]
impl ::core::clone::Clone for PatchableFunctionEntry {
    #[inline]
    fn clone(&self) -> PatchableFunctionEntry {
        let _: ::core::clone::AssertParamIsClone<u8>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for PatchableFunctionEntry { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for PatchableFunctionEntry {
    #[inline]
    fn eq(&self, other: &PatchableFunctionEntry) -> bool {
        self.prefix == other.prefix && self.entry == other.entry
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for PatchableFunctionEntry {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        ::core::hash::Hash::hash(&self.prefix, state);
        ::core::hash::Hash::hash(&self.entry, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for PatchableFunctionEntry {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "PatchableFunctionEntry", "prefix", &self.prefix, "entry",
            &&self.entry)
    }
}Debug, #[automatically_derived]
impl ::core::default::Default for PatchableFunctionEntry {
    #[inline]
    fn default() -> PatchableFunctionEntry {
        PatchableFunctionEntry {
            prefix: ::core::default::Default::default(),
            entry: ::core::default::Default::default(),
        }
    }
}Default)]
3334pub struct PatchableFunctionEntry {
3335    /// Nops before the entry
3336    prefix: u8,
3337    /// Nops after the entry
3338    entry: u8,
3339}
3340
3341impl PatchableFunctionEntry {
3342    pub fn from_total_and_prefix_nops(
3343        total_nops: u8,
3344        prefix_nops: u8,
3345    ) -> Option<PatchableFunctionEntry> {
3346        if total_nops < prefix_nops {
3347            None
3348        } else {
3349            Some(Self { prefix: prefix_nops, entry: total_nops - prefix_nops })
3350        }
3351    }
3352    pub fn prefix(&self) -> u8 {
3353        self.prefix
3354    }
3355    pub fn entry(&self) -> u8 {
3356        self.entry
3357    }
3358}
3359
3360/// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy,
3361/// or future prototype.
3362#[derive(#[automatically_derived]
impl ::core::clone::Clone for Polonius {
    #[inline]
    fn clone(&self) -> Polonius { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Polonius { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for Polonius {
    #[inline]
    fn eq(&self, other: &Polonius) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for Polonius {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Polonius {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                Polonius::Off => "Off",
                Polonius::Legacy => "Legacy",
                Polonius::Next => "Next",
            })
    }
}Debug, #[automatically_derived]
impl ::core::default::Default for Polonius {
    #[inline]
    fn default() -> Polonius { Self::Off }
}Default)]
3363pub enum Polonius {
3364    /// The default value: disabled.
3365    #[default]
3366    Off,
3367
3368    /// Legacy version, using datalog and the `polonius-engine` crate. Historical value for `-Zpolonius`.
3369    Legacy,
3370
3371    /// In-tree prototype, extending the NLL infrastructure.
3372    Next,
3373}
3374
3375impl Polonius {
3376    /// Returns whether the legacy version of polonius is enabled
3377    pub fn is_legacy_enabled(&self) -> bool {
3378        #[allow(non_exhaustive_omitted_patterns)] match self {
    Polonius::Legacy => true,
    _ => false,
}matches!(self, Polonius::Legacy)
3379    }
3380
3381    /// Returns whether the "next" version of polonius is enabled
3382    pub fn is_next_enabled(&self) -> bool {
3383        #[allow(non_exhaustive_omitted_patterns)] match self {
    Polonius::Next => true,
    _ => false,
}matches!(self, Polonius::Next)
3384    }
3385}
3386
3387#[derive(#[automatically_derived]
impl ::core::clone::Clone for InliningThreshold {
    #[inline]
    fn clone(&self) -> InliningThreshold {
        let _: ::core::clone::AssertParamIsClone<usize>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for InliningThreshold { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for InliningThreshold {
    #[inline]
    fn eq(&self, other: &InliningThreshold) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (InliningThreshold::Sometimes(__self_0),
                    InliningThreshold::Sometimes(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for InliningThreshold {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state);
        match self {
            InliningThreshold::Sometimes(__self_0) =>
                ::core::hash::Hash::hash(__self_0, state),
            _ => {}
        }
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for InliningThreshold {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            InliningThreshold::Always =>
                ::core::fmt::Formatter::write_str(f, "Always"),
            InliningThreshold::Sometimes(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Sometimes", &__self_0),
            InliningThreshold::Never =>
                ::core::fmt::Formatter::write_str(f, "Never"),
        }
    }
}Debug)]
3388pub enum InliningThreshold {
3389    Always,
3390    Sometimes(usize),
3391    Never,
3392}
3393
3394impl Default for InliningThreshold {
3395    fn default() -> Self {
3396        Self::Sometimes(100)
3397    }
3398}
3399
3400/// The different settings that the `-Zfunction-return` flag can have.
3401#[derive(#[automatically_derived]
impl ::core::clone::Clone for FunctionReturn {
    #[inline]
    fn clone(&self) -> FunctionReturn { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for FunctionReturn { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for FunctionReturn {
    #[inline]
    fn eq(&self, other: &FunctionReturn) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for FunctionReturn {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        ::core::hash::Hash::hash(&__self_discr, state)
    }
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for FunctionReturn {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                FunctionReturn::Keep => "Keep",
                FunctionReturn::ThunkExtern => "ThunkExtern",
            })
    }
}Debug, #[automatically_derived]
impl ::core::default::Default for FunctionReturn {
    #[inline]
    fn default() -> FunctionReturn { Self::Keep }
}Default)]
3402pub enum FunctionReturn {
3403    /// Keep the function return unmodified.
3404    #[default]
3405    Keep,
3406
3407    /// Replace returns with jumps to thunk, without emitting the thunk.
3408    ThunkExtern,
3409}
3410
3411/// Whether extra span comments are included when dumping MIR, via the `-Z mir-include-spans` flag.
3412/// By default, only enabled in the NLL MIR dumps, and disabled in all other passes.
3413#[derive(#[automatically_derived]
impl ::core::clone::Clone for MirIncludeSpans {
    #[inline]
    fn clone(&self) -> MirIncludeSpans { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for MirIncludeSpans { }Copy, #[automatically_derived]
impl ::core::default::Default for MirIncludeSpans {
    #[inline]
    fn default() -> MirIncludeSpans { Self::Nll }
}Default, #[automatically_derived]
impl ::core::cmp::PartialEq for MirIncludeSpans {
    #[inline]
    fn eq(&self, other: &MirIncludeSpans) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for MirIncludeSpans {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                MirIncludeSpans::Off => "Off",
                MirIncludeSpans::On => "On",
                MirIncludeSpans::Nll => "Nll",
            })
    }
}Debug)]
3414pub enum MirIncludeSpans {
3415    Off,
3416    On,
3417    /// Default: include extra comments in NLL MIR dumps only. Can be ignored and considered as
3418    /// `Off` in all other cases.
3419    #[default]
3420    Nll,
3421}
3422
3423impl MirIncludeSpans {
3424    /// Unless opting into extra comments for all passes, they can be considered disabled.
3425    /// The cases where a distinction between on/off and a per-pass value can exist will be handled
3426    /// in the passes themselves: i.e. the `Nll` value is considered off for all intents and
3427    /// purposes, except for the NLL MIR dump pass.
3428    pub fn is_enabled(self) -> bool {
3429        self == MirIncludeSpans::On
3430    }
3431}