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