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
1323pub(crate) fn parse_remap_path_scope(
1324    early_dcx: &EarlyDiagCtxt,
1325    matches: &getopts::Matches,
1326    unstable_opts: &UnstableOptions,
1327) -> RemapPathScopeComponents {
1328    if let Some(v) = matches.opt_str("remap-path-scope") {
1329        let mut slot = RemapPathScopeComponents::empty();
1330        for s in v.split(',') {
1331            slot |= match s {
1332                "macro" => RemapPathScopeComponents::MACRO,
1333                "diagnostics" => RemapPathScopeComponents::DIAGNOSTICS,
1334                "documentation" => {
1335                    if !unstable_opts.unstable_options {
1336                        early_dcx.early_fatal("remapping `documentation` path scope requested but `-Zunstable-options` not specified");
1337                    }
1338
1339                    RemapPathScopeComponents::DOCUMENTATION
1340                },
1341                "debuginfo" => RemapPathScopeComponents::DEBUGINFO,
1342                "coverage" => RemapPathScopeComponents::COVERAGE,
1343                "object" => RemapPathScopeComponents::OBJECT,
1344                "all" => RemapPathScopeComponents::all(),
1345                _ => early_dcx.early_fatal("argument for `--remap-path-scope` must be a comma separated list of scopes: `macro`, `diagnostics`, `documentation`, `debuginfo`, `coverage`, `object`, `all`"),
1346            }
1347        }
1348        slot
1349    } else {
1350        RemapPathScopeComponents::all()
1351    }
1352}
1353
1354#[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)]
1355pub struct Sysroot {
1356    pub explicit: Option<PathBuf>,
1357    pub default: PathBuf,
1358}
1359
1360impl Sysroot {
1361    pub fn new(explicit: Option<PathBuf>) -> Sysroot {
1362        Sysroot { explicit, default: filesearch::default_sysroot() }
1363    }
1364
1365    /// Return explicit sysroot if it was passed with `--sysroot`, or default sysroot otherwise.
1366    pub fn path(&self) -> &Path {
1367        self.explicit.as_deref().unwrap_or(&self.default)
1368    }
1369
1370    /// Returns both explicit sysroot if it was passed with `--sysroot` and the default sysroot.
1371    pub fn all_paths(&self) -> impl Iterator<Item = &Path> {
1372        self.explicit.as_deref().into_iter().chain(iter::once(&*self.default))
1373    }
1374}
1375
1376pub fn host_tuple() -> &'static str {
1377    // Get the host triple out of the build environment. This ensures that our
1378    // idea of the host triple is the same as for the set of libraries we've
1379    // actually built. We can't just take LLVM's host triple because they
1380    // normalize all ix86 architectures to i386.
1381    //
1382    // Instead of grabbing the host triple (for the current host), we grab (at
1383    // compile time) the target triple that this rustc is built with and
1384    // calling that (at runtime) the host triple.
1385    (::core::option::Option::Some("x86_64-unknown-linux-gnu")option_env!("CFG_COMPILER_HOST_TRIPLE")).expect("CFG_COMPILER_HOST_TRIPLE")
1386}
1387
1388fn file_path_mapping(
1389    remap_path_prefix: Vec<(PathBuf, PathBuf)>,
1390    remap_path_scope: RemapPathScopeComponents,
1391) -> FilePathMapping {
1392    FilePathMapping::new(remap_path_prefix.clone(), remap_path_scope)
1393}
1394
1395impl Default for Options {
1396    fn default() -> Options {
1397        let unstable_opts = UnstableOptions::default();
1398
1399        // FIXME(Urgau): This is a hack that ideally shouldn't exist, but rustdoc
1400        // currently uses this `Default` implementation, so we have no choice but
1401        // to create a default working directory.
1402        let working_dir = {
1403            let working_dir = std::env::current_dir().unwrap();
1404            let file_mapping = file_path_mapping(Vec::new(), RemapPathScopeComponents::empty());
1405            file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
1406        };
1407
1408        Options {
1409            crate_types: Vec::new(),
1410            optimize: OptLevel::No,
1411            debuginfo: DebugInfo::None,
1412            lint_opts: Vec::new(),
1413            lint_cap: None,
1414            describe_lints: false,
1415            output_types: OutputTypes(BTreeMap::new()),
1416            search_paths: ::alloc::vec::Vec::new()vec![],
1417            sysroot: Sysroot::new(None),
1418            target_triple: TargetTuple::from_tuple(host_tuple()),
1419            test: false,
1420            incremental: None,
1421            untracked_state_hash: Default::default(),
1422            unstable_opts,
1423            prints: Vec::new(),
1424            cg: Default::default(),
1425            error_format: ErrorOutputType::default(),
1426            diagnostic_width: None,
1427            externs: Externs(BTreeMap::new()),
1428            crate_name: None,
1429            libs: Vec::new(),
1430            unstable_features: UnstableFeatures::Disallow,
1431            debug_assertions: true,
1432            actually_rustdoc: false,
1433            resolve_doc_links: ResolveDocLinks::None,
1434            trimmed_def_paths: false,
1435            cli_forced_codegen_units: None,
1436            cli_forced_local_thinlto_off: false,
1437            remap_path_prefix: Vec::new(),
1438            remap_path_scope: RemapPathScopeComponents::all(),
1439            real_rust_source_base_dir: None,
1440            real_rustc_dev_source_base_dir: None,
1441            edition: DEFAULT_EDITION,
1442            json_artifact_notifications: false,
1443            json_timings: false,
1444            json_unused_externs: JsonUnusedExterns::No,
1445            json_future_incompat: false,
1446            pretty: None,
1447            working_dir,
1448            color: ColorConfig::Auto,
1449            logical_env: FxIndexMap::default(),
1450            verbose: false,
1451            target_modifiers: BTreeMap::default(),
1452        }
1453    }
1454}
1455
1456impl Options {
1457    /// Returns `true` if there is a reason to build the dep graph.
1458    pub fn build_dep_graph(&self) -> bool {
1459        self.incremental.is_some()
1460            || self.unstable_opts.dump_dep_graph
1461            || self.unstable_opts.query_dep_graph
1462    }
1463
1464    pub fn file_path_mapping(&self) -> FilePathMapping {
1465        file_path_mapping(self.remap_path_prefix.clone(), self.remap_path_scope)
1466    }
1467
1468    /// Returns `true` if there will be an output file generated.
1469    pub fn will_create_output_file(&self) -> bool {
1470        !self.unstable_opts.parse_crate_root_only && // The file is just being parsed
1471            self.unstable_opts.ls.is_empty() // The file is just being queried
1472    }
1473
1474    #[inline]
1475    pub fn share_generics(&self) -> bool {
1476        match self.unstable_opts.share_generics {
1477            Some(setting) => setting,
1478            None => match self.optimize {
1479                OptLevel::No | OptLevel::Less | OptLevel::Size | OptLevel::SizeMin => true,
1480                OptLevel::More | OptLevel::Aggressive => false,
1481            },
1482        }
1483    }
1484
1485    pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
1486        self.cg.symbol_mangling_version.unwrap_or(if self.unstable_features.is_nightly_build() {
1487            SymbolManglingVersion::V0
1488        } else {
1489            SymbolManglingVersion::Legacy
1490        })
1491    }
1492
1493    #[inline]
1494    pub fn autodiff_enabled(&self) -> bool {
1495        self.unstable_opts.autodiff.contains(&AutoDiff::Enable)
1496    }
1497}
1498
1499impl UnstableOptions {
1500    pub fn dcx_flags(&self, can_emit_warnings: bool) -> DiagCtxtFlags {
1501        DiagCtxtFlags {
1502            can_emit_warnings,
1503            treat_err_as_bug: self.treat_err_as_bug,
1504            eagerly_emit_delayed_bugs: self.eagerly_emit_delayed_bugs,
1505            macro_backtrace: self.macro_backtrace,
1506            deduplicate_diagnostics: self.deduplicate_diagnostics,
1507            track_diagnostics: self.track_diagnostics,
1508        }
1509    }
1510
1511    pub fn src_hash_algorithm(&self, target: &Target) -> SourceFileHashAlgorithm {
1512        self.src_hash_algorithm.unwrap_or_else(|| {
1513            if target.is_like_msvc {
1514                SourceFileHashAlgorithm::Sha256
1515            } else {
1516                SourceFileHashAlgorithm::Md5
1517            }
1518        })
1519    }
1520
1521    pub fn checksum_hash_algorithm(&self) -> Option<SourceFileHashAlgorithm> {
1522        self.checksum_hash_algorithm
1523    }
1524}
1525
1526// The type of entry function, so users can have their own entry functions
1527#[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)]
1528pub enum EntryFnType {
1529    Main {
1530        /// Specifies what to do with `SIGPIPE` before calling `fn main()`.
1531        ///
1532        /// What values that are valid and what they mean must be in sync
1533        /// across rustc and libstd, but we don't want it public in libstd,
1534        /// so we take a bit of an unusual approach with simple constants
1535        /// and an `include!()`.
1536        sigpipe: u8,
1537    },
1538}
1539
1540pub use rustc_hir::attrs::CrateType;
1541
1542#[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)]
1543pub enum Passes {
1544    Some(Vec<String>),
1545    All,
1546}
1547
1548impl Passes {
1549    fn is_empty(&self) -> bool {
1550        match *self {
1551            Passes::Some(ref v) => v.is_empty(),
1552            Passes::All => false,
1553        }
1554    }
1555
1556    pub(crate) fn extend(&mut self, passes: impl IntoIterator<Item = String>) {
1557        match *self {
1558            Passes::Some(ref mut v) => v.extend(passes),
1559            Passes::All => {}
1560        }
1561    }
1562}
1563
1564#[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)]
1565pub enum PAuthKey {
1566    A,
1567    B,
1568}
1569
1570#[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)]
1571pub struct PacRet {
1572    pub leaf: bool,
1573    pub pc: bool,
1574    pub key: PAuthKey,
1575}
1576
1577#[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)]
1578pub struct BranchProtection {
1579    pub bti: bool,
1580    pub pac_ret: Option<PacRet>,
1581    pub gcs: bool,
1582}
1583
1584pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
1585    // First disallow some configuration given on the command line
1586    cfg::disallow_cfgs(sess, &user_cfg);
1587
1588    // Then combine the configuration requested by the session (command line) with
1589    // some default and generated configuration items.
1590    user_cfg.extend(cfg::default_configuration(sess));
1591    user_cfg
1592}
1593
1594pub fn build_target_config(
1595    early_dcx: &EarlyDiagCtxt,
1596    target: &TargetTuple,
1597    sysroot: &Path,
1598    unstable_options: bool,
1599) -> Target {
1600    match Target::search(target, sysroot, unstable_options) {
1601        Ok((target, warnings)) => {
1602            for warning in warnings.warning_messages() {
1603                early_dcx.early_warn(warning)
1604            }
1605
1606            if !#[allow(non_exhaustive_omitted_patterns)] match target.pointer_width {
    16 | 32 | 64 => true,
    _ => false,
}matches!(target.pointer_width, 16 | 32 | 64) {
1607                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!(
1608                    "target specification was invalid: unrecognized target-pointer-width {}",
1609                    target.pointer_width
1610                ))
1611            }
1612            target
1613        }
1614        Err(e) => {
1615            let mut err =
1616                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}"));
1617            err.help("run `rustc --print target-list` for a list of built-in targets");
1618            err.emit()
1619        }
1620    }
1621}
1622
1623#[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)]
1624pub enum OptionStability {
1625    Stable,
1626    Unstable,
1627}
1628
1629#[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)]
1630pub enum OptionKind {
1631    /// An option that takes a value, and cannot appear more than once (e.g. `--out-dir`).
1632    ///
1633    /// Corresponds to [`getopts::Options::optopt`].
1634    Opt,
1635
1636    /// An option that takes a value, and can appear multiple times (e.g. `--emit`).
1637    ///
1638    /// Corresponds to [`getopts::Options::optmulti`].
1639    Multi,
1640
1641    /// An option that does not take a value, and cannot appear more than once (e.g. `--help`).
1642    ///
1643    /// Corresponds to [`getopts::Options::optflag`].
1644    /// The `hint` string must be empty.
1645    Flag,
1646
1647    /// An option that does not take a value, and can appear multiple times (e.g. `-O`).
1648    ///
1649    /// Corresponds to [`getopts::Options::optflagmulti`].
1650    /// The `hint` string must be empty.
1651    FlagMulti,
1652}
1653
1654pub struct RustcOptGroup {
1655    /// The "primary" name for this option. Normally equal to `long_name`,
1656    /// except for options that don't have a long name, in which case
1657    /// `short_name` is used.
1658    ///
1659    /// This is needed when interacting with `getopts` in some situations,
1660    /// because if an option has both forms, that library treats the long name
1661    /// as primary and the short name as an alias.
1662    pub name: &'static str,
1663    stability: OptionStability,
1664    kind: OptionKind,
1665
1666    short_name: &'static str,
1667    long_name: &'static str,
1668    desc: &'static str,
1669    value_hint: &'static str,
1670
1671    /// If true, this option should not be printed by `rustc --help`, but
1672    /// should still be printed by `rustc --help -v`.
1673    pub is_verbose_help_only: bool,
1674}
1675
1676impl RustcOptGroup {
1677    pub fn is_stable(&self) -> bool {
1678        self.stability == OptionStability::Stable
1679    }
1680
1681    pub fn apply(&self, options: &mut getopts::Options) {
1682        let &Self { short_name, long_name, desc, value_hint, .. } = self;
1683        match self.kind {
1684            OptionKind::Opt => options.optopt(short_name, long_name, desc, value_hint),
1685            OptionKind::Multi => options.optmulti(short_name, long_name, desc, value_hint),
1686            OptionKind::Flag => options.optflag(short_name, long_name, desc),
1687            OptionKind::FlagMulti => options.optflagmulti(short_name, long_name, desc),
1688        };
1689    }
1690
1691    /// This is for diagnostics-only.
1692    pub fn long_name(&self) -> &str {
1693        self.long_name
1694    }
1695}
1696
1697pub fn make_opt(
1698    stability: OptionStability,
1699    kind: OptionKind,
1700    short_name: &'static str,
1701    long_name: &'static str,
1702    desc: &'static str,
1703    value_hint: &'static str,
1704) -> RustcOptGroup {
1705    // "Flag" options don't have a value, and therefore don't have a value hint.
1706    match kind {
1707        OptionKind::Opt | OptionKind::Multi => {}
1708        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, ""),
1709    }
1710    RustcOptGroup {
1711        name: cmp::max_by_key(short_name, long_name, |s| s.len()),
1712        stability,
1713        kind,
1714        short_name,
1715        long_name,
1716        desc,
1717        value_hint,
1718        is_verbose_help_only: false,
1719    }
1720}
1721
1722static EDITION_STRING: LazyLock<String> = LazyLock::new(|| {
1723    ::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!(
1724        "Specify which edition of the compiler to use when compiling code. \
1725The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE_EDITION}."
1726    )
1727});
1728
1729static EMIT_HELP: LazyLock<String> = LazyLock::new(|| {
1730    let mut result =
1731        String::from("Comma separated list of types of output for the compiler to emit.\n");
1732    result.push_str("Each TYPE has the default FILE name:\n");
1733
1734    for output in OutputType::iter_all() {
1735        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()));
1736    }
1737
1738    result
1739});
1740
1741/// Returns all rustc command line options, including metadata for
1742/// each option, such as whether the option is stable.
1743///
1744/// # Option style guidelines
1745///
1746/// - `<param>`: Indicates a required parameter
1747/// - `[param]`: Indicates an optional parameter
1748/// - `|`: Indicates a mutually exclusive option
1749/// - `*`: a list element with description
1750pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
1751    use OptionKind::{Flag, FlagMulti, Multi, Opt};
1752    use OptionStability::{Stable, Unstable};
1753
1754    use self::make_opt as opt;
1755
1756    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![
1757        opt(Stable, Flag, "h", "help", "Display this message", ""),
1758        opt(
1759            Stable,
1760            Multi,
1761            "",
1762            "cfg",
1763            "Configure the compilation environment.\n\
1764                SPEC supports the syntax `<NAME>[=\"<VALUE>\"]`.",
1765            "<SPEC>",
1766        ),
1767        opt(Stable, Multi, "", "check-cfg", "Provide list of expected cfgs for checking", "<SPEC>"),
1768        opt(
1769            Stable,
1770            Multi,
1771            "L",
1772            "",
1773            "Add a directory to the library search path. \
1774                The optional KIND can be one of <dependency|crate|native|framework|all> (default: all).",
1775            "[<KIND>=]<PATH>",
1776        ),
1777        opt(
1778            Stable,
1779            Multi,
1780            "l",
1781            "",
1782            "Link the generated crate(s) to the specified native\n\
1783                library NAME. The optional KIND can be one of\n\
1784                <static|framework|dylib> (default: dylib).\n\
1785                Optional comma separated MODIFIERS\n\
1786                <bundle|verbatim|whole-archive|as-needed>\n\
1787                may be specified each with a prefix of either '+' to\n\
1788                enable or '-' to disable.",
1789            "[<KIND>[:<MODIFIERS>]=]<NAME>[:<RENAME>]",
1790        ),
1791        make_crate_type_option(),
1792        opt(Stable, Opt, "", "crate-name", "Specify the name of the crate being built", "<NAME>"),
1793        opt(Stable, Opt, "", "edition", &EDITION_STRING, EDITION_NAME_LIST),
1794        opt(Stable, Multi, "", "emit", &EMIT_HELP, "<TYPE>[=<FILE>]"),
1795        opt(Stable, Multi, "", "print", &print_request::PRINT_HELP, "<INFO>[=<FILE>]"),
1796        opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
1797        opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=3", ""),
1798        opt(Stable, Opt, "o", "", "Write output to FILENAME", "<FILENAME>"),
1799        opt(Stable, Opt, "", "out-dir", "Write output to compiler-chosen filename in DIR", "<DIR>"),
1800        opt(
1801            Stable,
1802            Opt,
1803            "",
1804            "explain",
1805            "Provide a detailed explanation of an error message",
1806            "<OPT>",
1807        ),
1808        opt(Stable, Flag, "", "test", "Build a test harness", ""),
1809        opt(Stable, Opt, "", "target", "Target tuple for which the code is compiled", "<TARGET>"),
1810        opt(Stable, Multi, "A", "allow", "Set lint allowed", "<LINT>"),
1811        opt(Stable, Multi, "W", "warn", "Set lint warnings", "<LINT>"),
1812        opt(Stable, Multi, "", "force-warn", "Set lint force-warn", "<LINT>"),
1813        opt(Stable, Multi, "D", "deny", "Set lint denied", "<LINT>"),
1814        opt(Stable, Multi, "F", "forbid", "Set lint forbidden", "<LINT>"),
1815        opt(
1816            Stable,
1817            Multi,
1818            "",
1819            "cap-lints",
1820            "Set the most restrictive lint level. More restrictive lints are capped at this level",
1821            "<LEVEL>",
1822        ),
1823        opt(Stable, Multi, "C", "codegen", "Set a codegen option", "<OPT>[=<VALUE>]"),
1824        opt(Stable, Flag, "V", "version", "Print version info and exit", ""),
1825        opt(Stable, Flag, "v", "verbose", "Use verbose output", ""),
1826    ];
1827
1828    // Options in this list are hidden from `rustc --help` by default, but are
1829    // shown by `rustc --help -v`.
1830    let verbose_only = [
1831        opt(
1832            Stable,
1833            Multi,
1834            "",
1835            "extern",
1836            "Specify where an external rust library is located",
1837            "<NAME>[=<PATH>]",
1838        ),
1839        opt(Stable, Opt, "", "sysroot", "Override the system root", "<PATH>"),
1840        opt(Unstable, Multi, "Z", "", "Set unstable / perma-unstable options", "<FLAG>"),
1841        opt(
1842            Stable,
1843            Opt,
1844            "",
1845            "error-format",
1846            "How errors and other messages are produced",
1847            "<human|json|short>",
1848        ),
1849        opt(Stable, Multi, "", "json", "Configure the JSON output of the compiler", "<CONFIG>"),
1850        opt(
1851            Stable,
1852            Opt,
1853            "",
1854            "color",
1855            "Configure coloring of output:
1856                * auto   = colorize, if output goes to a tty (default);
1857                * always = always colorize output;
1858                * never  = never colorize output",
1859            "<auto|always|never>",
1860        ),
1861        opt(
1862            Stable,
1863            Opt,
1864            "",
1865            "diagnostic-width",
1866            "Inform rustc of the width of the output so that diagnostics can be truncated to fit",
1867            "<WIDTH>",
1868        ),
1869        opt(
1870            Stable,
1871            Multi,
1872            "",
1873            "remap-path-prefix",
1874            "Remap source names in all output (compiler messages and output files)",
1875            "<FROM>=<TO>",
1876        ),
1877        opt(
1878            Stable,
1879            Opt,
1880            "",
1881            "remap-path-scope",
1882            "Defines which scopes of paths should be remapped by `--remap-path-prefix`",
1883            "<macro,diagnostics,debuginfo,coverage,object,all>",
1884        ),
1885        opt(Unstable, Multi, "", "env-set", "Inject an environment variable", "<VAR>=<VALUE>"),
1886    ];
1887    options.extend(verbose_only.into_iter().map(|mut opt| {
1888        opt.is_verbose_help_only = true;
1889        opt
1890    }));
1891
1892    options
1893}
1894
1895pub fn get_cmd_lint_options(
1896    early_dcx: &EarlyDiagCtxt,
1897    matches: &getopts::Matches,
1898) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
1899    let mut lint_opts_with_position = ::alloc::vec::Vec::new()vec![];
1900    let mut describe_lints = false;
1901
1902    for level in [lint::Allow, lint::Warn, lint::ForceWarn, lint::Deny, lint::Forbid] {
1903        for (arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
1904            if lint_name == "help" {
1905                describe_lints = true;
1906            } else {
1907                lint_opts_with_position.push((arg_pos, lint_name.replace('-', "_"), level));
1908            }
1909        }
1910    }
1911
1912    lint_opts_with_position.sort_by_key(|x| x.0);
1913    let lint_opts = lint_opts_with_position
1914        .iter()
1915        .cloned()
1916        .map(|(_, lint_name, level)| (lint_name, level))
1917        .collect();
1918
1919    let lint_cap = matches.opt_str("cap-lints").map(|cap| {
1920        lint::Level::from_str(&cap)
1921            .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}`")))
1922    });
1923
1924    (lint_opts, describe_lints, lint_cap)
1925}
1926
1927/// Parses the `--color` flag.
1928pub fn parse_color(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> ColorConfig {
1929    match matches.opt_str("color").as_deref() {
1930        Some("auto") => ColorConfig::Auto,
1931        Some("always") => ColorConfig::Always,
1932        Some("never") => ColorConfig::Never,
1933
1934        None => ColorConfig::Auto,
1935
1936        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!(
1937            "argument for `--color` must be auto, \
1938                 always or never (instead was `{arg}`)"
1939        )),
1940    }
1941}
1942
1943/// Possible json config files
1944pub struct JsonConfig {
1945    pub json_rendered: HumanReadableErrorType,
1946    pub json_color: ColorConfig,
1947    json_artifact_notifications: bool,
1948    /// Output start and end timestamps of several high-level compilation sections
1949    /// (frontend, backend, linker).
1950    json_timings: bool,
1951    pub json_unused_externs: JsonUnusedExterns,
1952    json_future_incompat: bool,
1953}
1954
1955/// Report unused externs in event stream
1956#[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)]
1957pub enum JsonUnusedExterns {
1958    /// Do not
1959    No,
1960    /// Report, but do not exit with failure status for deny/forbid
1961    Silent,
1962    /// Report, and also exit with failure status for deny/forbid
1963    Loud,
1964}
1965
1966impl JsonUnusedExterns {
1967    pub fn is_enabled(&self) -> bool {
1968        match self {
1969            JsonUnusedExterns::No => false,
1970            JsonUnusedExterns::Loud | JsonUnusedExterns::Silent => true,
1971        }
1972    }
1973
1974    pub fn is_loud(&self) -> bool {
1975        match self {
1976            JsonUnusedExterns::No | JsonUnusedExterns::Silent => false,
1977            JsonUnusedExterns::Loud => true,
1978        }
1979    }
1980}
1981
1982/// Parse the `--json` flag.
1983///
1984/// The first value returned is how to render JSON diagnostics, and the second
1985/// is whether or not artifact notifications are enabled.
1986pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> JsonConfig {
1987    let mut json_rendered = HumanReadableErrorType { short: false, unicode: false };
1988    let mut json_color = ColorConfig::Never;
1989    let mut json_artifact_notifications = false;
1990    let mut json_unused_externs = JsonUnusedExterns::No;
1991    let mut json_future_incompat = false;
1992    let mut json_timings = false;
1993    for option in matches.opt_strs("json") {
1994        // For now conservatively forbid `--color` with `--json` since `--json`
1995        // won't actually be emitting any colors and anything colorized is
1996        // embedded in a diagnostic message anyway.
1997        if matches.opt_str("color").is_some() {
1998            early_dcx.early_fatal("cannot specify the `--color` option with `--json`");
1999        }
2000
2001        for sub_option in option.split(',') {
2002            match sub_option {
2003                "diagnostic-short" => {
2004                    json_rendered = HumanReadableErrorType { short: true, unicode: false };
2005                }
2006                "diagnostic-unicode" => {
2007                    json_rendered = HumanReadableErrorType { short: false, unicode: true };
2008                }
2009                "diagnostic-rendered-ansi" => json_color = ColorConfig::Always,
2010                "artifacts" => json_artifact_notifications = true,
2011                "timings" => json_timings = true,
2012                "unused-externs" => json_unused_externs = JsonUnusedExterns::Loud,
2013                "unused-externs-silent" => json_unused_externs = JsonUnusedExterns::Silent,
2014                "future-incompat" => json_future_incompat = true,
2015                s => early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown `--json` option `{0}`", s))
    })format!("unknown `--json` option `{s}`")),
2016            }
2017        }
2018    }
2019
2020    JsonConfig {
2021        json_rendered,
2022        json_color,
2023        json_artifact_notifications,
2024        json_timings,
2025        json_unused_externs,
2026        json_future_incompat,
2027    }
2028}
2029
2030/// Parses the `--error-format` flag.
2031pub fn parse_error_format(
2032    early_dcx: &mut EarlyDiagCtxt,
2033    matches: &getopts::Matches,
2034    color_config: ColorConfig,
2035    json_color: ColorConfig,
2036    json_rendered: HumanReadableErrorType,
2037) -> ErrorOutputType {
2038    let default_kind = HumanReadableErrorType { short: false, unicode: false };
2039    // We need the `opts_present` check because the driver will send us Matches
2040    // with only stable options if no unstable options are used. Since error-format
2041    // is unstable, it will not be present. We have to use `opts_present` not
2042    // `opt_present` because the latter will panic.
2043    let error_format = if matches.opts_present(&["error-format".to_owned()]) {
2044        match matches.opt_str("error-format").as_deref() {
2045            None | Some("human") => {
2046                ErrorOutputType::HumanReadable { color_config, kind: default_kind }
2047            }
2048            Some("json") => {
2049                ErrorOutputType::Json { pretty: false, json_rendered, color_config: json_color }
2050            }
2051            Some("pretty-json") => {
2052                ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color }
2053            }
2054            Some("short") => ErrorOutputType::HumanReadable {
2055                kind: HumanReadableErrorType { short: true, unicode: false },
2056                color_config,
2057            },
2058            Some("human-unicode") => ErrorOutputType::HumanReadable {
2059                kind: HumanReadableErrorType { short: false, unicode: true },
2060                color_config,
2061            },
2062            Some(arg) => {
2063                early_dcx.set_error_format(ErrorOutputType::HumanReadable {
2064                    color_config,
2065                    kind: default_kind,
2066                });
2067                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!(
2068                    "argument for `--error-format` must be `human`, `human-unicode`, \
2069                    `json`, `pretty-json` or `short` (instead was `{arg}`)"
2070                ))
2071            }
2072        }
2073    } else {
2074        ErrorOutputType::HumanReadable { color_config, kind: default_kind }
2075    };
2076
2077    match error_format {
2078        ErrorOutputType::Json { .. } => {}
2079
2080        // Conservatively require that the `--json` argument is coupled with
2081        // `--error-format=json`. This means that `--json` is specified we
2082        // should actually be emitting JSON blobs.
2083        _ if !matches.opt_strs("json").is_empty() => {
2084            early_dcx.early_fatal("using `--json` requires also using `--error-format=json`");
2085        }
2086
2087        _ => {}
2088    }
2089
2090    error_format
2091}
2092
2093pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Edition {
2094    let edition = match matches.opt_str("edition") {
2095        Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| {
2096            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!(
2097                "argument for `--edition` must be one of: \
2098                     {EDITION_NAME_LIST}. (instead was `{arg}`)"
2099            ))
2100        }),
2101        None => DEFAULT_EDITION,
2102    };
2103
2104    if !edition.is_stable() && !nightly_options::is_unstable_enabled(matches) {
2105        let is_nightly = nightly_options::match_is_nightly_build(matches);
2106        let msg = if !is_nightly {
2107            ::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!(
2108                "the crate requires edition {edition}, but the latest edition supported by this Rust version is {LATEST_STABLE_EDITION}"
2109            )
2110        } else {
2111            ::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")
2112        };
2113        early_dcx.early_fatal(msg)
2114    }
2115
2116    edition
2117}
2118
2119fn check_error_format_stability(
2120    early_dcx: &EarlyDiagCtxt,
2121    unstable_opts: &UnstableOptions,
2122    is_nightly_build: bool,
2123    format: ErrorOutputType,
2124) {
2125    if unstable_opts.unstable_options || is_nightly_build {
2126        return;
2127    }
2128    let format = match format {
2129        ErrorOutputType::Json { pretty: true, .. } => "pretty-json",
2130        ErrorOutputType::HumanReadable { kind, .. } => match kind {
2131            HumanReadableErrorType { unicode: true, .. } => "human-unicode",
2132            _ => return,
2133        },
2134        _ => return,
2135    };
2136    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"))
2137}
2138
2139fn parse_output_types(
2140    early_dcx: &EarlyDiagCtxt,
2141    unstable_opts: &UnstableOptions,
2142    matches: &getopts::Matches,
2143) -> OutputTypes {
2144    let mut output_types = BTreeMap::new();
2145    if !unstable_opts.parse_crate_root_only {
2146        for list in matches.opt_strs("emit") {
2147            for output_type in list.split(',') {
2148                let (shorthand, path) = split_out_file_name(output_type);
2149                let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
2150                    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!(
2151                        "unknown emission type: `{shorthand}` - expected one of: {display}",
2152                        display = OutputType::shorthands_display(),
2153                    ))
2154                });
2155                if output_type == OutputType::ThinLinkBitcode && !unstable_opts.unstable_options {
2156                    early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} requested but -Zunstable-options not specified",
                OutputType::ThinLinkBitcode.shorthand()))
    })format!(
2157                        "{} requested but -Zunstable-options not specified",
2158                        OutputType::ThinLinkBitcode.shorthand()
2159                    ));
2160                }
2161                output_types.insert(output_type, path);
2162            }
2163        }
2164    };
2165    if output_types.is_empty() {
2166        output_types.insert(OutputType::Exe, None);
2167    }
2168    OutputTypes(output_types)
2169}
2170
2171fn split_out_file_name(arg: &str) -> (&str, Option<OutFileName>) {
2172    match arg.split_once('=') {
2173        None => (arg, None),
2174        Some((kind, "-")) => (kind, Some(OutFileName::Stdout)),
2175        Some((kind, path)) => (kind, Some(OutFileName::Real(PathBuf::from(path)))),
2176    }
2177}
2178
2179fn should_override_cgus_and_disable_thinlto(
2180    early_dcx: &EarlyDiagCtxt,
2181    output_types: &OutputTypes,
2182    matches: &getopts::Matches,
2183    mut codegen_units: Option<usize>,
2184) -> (bool, Option<usize>) {
2185    let mut disable_local_thinlto = false;
2186    // Issue #30063: if user requests LLVM-related output to one
2187    // particular path, disable codegen-units.
2188    let incompatible: Vec<_> = output_types
2189        .0
2190        .iter()
2191        .map(|ot_path| ot_path.0)
2192        .filter(|ot| !ot.is_compatible_with_codegen_units_and_single_output_file())
2193        .map(|ot| ot.shorthand())
2194        .collect();
2195    if !incompatible.is_empty() {
2196        match codegen_units {
2197            Some(n) if n > 1 => {
2198                if matches.opt_present("o") {
2199                    for ot in &incompatible {
2200                        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!(
2201                            "`--emit={ot}` with `-o` incompatible with \
2202                                 `-C codegen-units=N` for N > 1",
2203                        ));
2204                    }
2205                    early_dcx.early_warn("resetting to default -C codegen-units=1");
2206                    codegen_units = Some(1);
2207                    disable_local_thinlto = true;
2208                }
2209            }
2210            _ => {
2211                codegen_units = Some(1);
2212                disable_local_thinlto = true;
2213            }
2214        }
2215    }
2216
2217    if codegen_units == Some(0) {
2218        early_dcx.early_fatal("value for codegen units must be a positive non-zero integer");
2219    }
2220
2221    (disable_local_thinlto, codegen_units)
2222}
2223
2224pub fn parse_target_triple(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> TargetTuple {
2225    match matches.opt_str("target") {
2226        Some(target) if target.ends_with(".json") => {
2227            let path = Path::new(&target);
2228            TargetTuple::from_path(path).unwrap_or_else(|_| {
2229                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"))
2230            })
2231        }
2232        Some(target) => TargetTuple::TargetTuple(target),
2233        _ => TargetTuple::from_tuple(host_tuple()),
2234    }
2235}
2236
2237fn parse_opt_level(
2238    early_dcx: &EarlyDiagCtxt,
2239    matches: &getopts::Matches,
2240    cg: &CodegenOptions,
2241) -> OptLevel {
2242    // The `-O` and `-C opt-level` flags specify the same setting, so we want to be able
2243    // to use them interchangeably. However, because they're technically different flags,
2244    // we need to work out manually which should take precedence if both are supplied (i.e.
2245    // the rightmost flag). We do this by finding the (rightmost) position of both flags and
2246    // comparing them. Note that if a flag is not found, its position will be `None`, which
2247    // always compared less than `Some(_)`.
2248    let max_o = matches.opt_positions("O").into_iter().max();
2249    let max_c = matches
2250        .opt_strs_pos("C")
2251        .into_iter()
2252        .flat_map(|(i, s)| {
2253            // NB: This can match a string without `=`.
2254            if let Some("opt-level") = s.split('=').next() { Some(i) } else { None }
2255        })
2256        .max();
2257    if max_o > max_c {
2258        OptLevel::Aggressive
2259    } else {
2260        match cg.opt_level.as_ref() {
2261            "0" => OptLevel::No,
2262            "1" => OptLevel::Less,
2263            "2" => OptLevel::More,
2264            "3" => OptLevel::Aggressive,
2265            "s" => OptLevel::Size,
2266            "z" => OptLevel::SizeMin,
2267            arg => {
2268                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!(
2269                    "optimization level needs to be \
2270                            between 0-3, s or z (instead was `{arg}`)"
2271                ));
2272            }
2273        }
2274    }
2275}
2276
2277fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInfo {
2278    let max_g = matches.opt_positions("g").into_iter().max();
2279    let max_c = matches
2280        .opt_strs_pos("C")
2281        .into_iter()
2282        .flat_map(|(i, s)| {
2283            // NB: This can match a string without `=`.
2284            if let Some("debuginfo") = s.split('=').next() { Some(i) } else { None }
2285        })
2286        .max();
2287    if max_g > max_c { DebugInfo::Full } else { cg.debuginfo }
2288}
2289
2290pub fn parse_externs(
2291    early_dcx: &EarlyDiagCtxt,
2292    matches: &getopts::Matches,
2293    unstable_opts: &UnstableOptions,
2294) -> Externs {
2295    let is_unstable_enabled = unstable_opts.unstable_options;
2296    let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
2297    for arg in matches.opt_strs("extern") {
2298        let ExternOpt { crate_name: name, path, options } =
2299            split_extern_opt(early_dcx, unstable_opts, &arg).unwrap_or_else(|e| e.emit());
2300
2301        let entry = externs.entry(name.to_owned());
2302
2303        use std::collections::btree_map::Entry;
2304
2305        let entry = if let Some(path) = path {
2306            // --extern prelude_name=some_file.rlib
2307            let path = CanonicalizedPath::new(path);
2308            match entry {
2309                Entry::Vacant(vacant) => {
2310                    let files = BTreeSet::from_iter(iter::once(path));
2311                    vacant.insert(ExternEntry::new(ExternLocation::ExactPaths(files)))
2312                }
2313                Entry::Occupied(occupied) => {
2314                    let ext_ent = occupied.into_mut();
2315                    match ext_ent {
2316                        ExternEntry { location: ExternLocation::ExactPaths(files), .. } => {
2317                            files.insert(path);
2318                        }
2319                        ExternEntry {
2320                            location: location @ ExternLocation::FoundInLibrarySearchDirectories,
2321                            ..
2322                        } => {
2323                            // Exact paths take precedence over search directories.
2324                            let files = BTreeSet::from_iter(iter::once(path));
2325                            *location = ExternLocation::ExactPaths(files);
2326                        }
2327                    }
2328                    ext_ent
2329                }
2330            }
2331        } else {
2332            // --extern prelude_name
2333            match entry {
2334                Entry::Vacant(vacant) => {
2335                    vacant.insert(ExternEntry::new(ExternLocation::FoundInLibrarySearchDirectories))
2336                }
2337                Entry::Occupied(occupied) => {
2338                    // Ignore if already specified.
2339                    occupied.into_mut()
2340                }
2341            }
2342        };
2343
2344        let mut is_private_dep = false;
2345        let mut add_prelude = true;
2346        let mut nounused_dep = false;
2347        let mut force = false;
2348        if let Some(opts) = options {
2349            if !is_unstable_enabled {
2350                early_dcx.early_fatal(
2351                    "the `-Z unstable-options` flag must also be passed to \
2352                     enable `--extern` options",
2353                );
2354            }
2355            for opt in opts.split(',') {
2356                match opt {
2357                    "priv" => is_private_dep = true,
2358                    "noprelude" => {
2359                        if let ExternLocation::ExactPaths(_) = &entry.location {
2360                            add_prelude = false;
2361                        } else {
2362                            early_dcx.early_fatal(
2363                                "the `noprelude` --extern option requires a file path",
2364                            );
2365                        }
2366                    }
2367                    "nounused" => nounused_dep = true,
2368                    "force" => force = true,
2369                    _ => early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown --extern option `{0}`",
                opt))
    })format!("unknown --extern option `{opt}`")),
2370                }
2371            }
2372        }
2373
2374        // Crates start out being not private, and go to being private `priv`
2375        // is specified.
2376        entry.is_private_dep |= is_private_dep;
2377        // likewise `nounused`
2378        entry.nounused_dep |= nounused_dep;
2379        // and `force`
2380        entry.force |= force;
2381        // If any flag is missing `noprelude`, then add to the prelude.
2382        entry.add_prelude |= add_prelude;
2383    }
2384    Externs(externs)
2385}
2386
2387fn parse_remap_path_prefix(
2388    early_dcx: &EarlyDiagCtxt,
2389    matches: &getopts::Matches,
2390    unstable_opts: &UnstableOptions,
2391) -> Vec<(PathBuf, PathBuf)> {
2392    let mut mapping: Vec<(PathBuf, PathBuf)> = matches
2393        .opt_strs("remap-path-prefix")
2394        .into_iter()
2395        .map(|remap| match remap.rsplit_once('=') {
2396            None => {
2397                early_dcx.early_fatal("--remap-path-prefix must contain '=' between FROM and TO")
2398            }
2399            Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)),
2400        })
2401        .collect();
2402    match &unstable_opts.remap_cwd_prefix {
2403        Some(to) => match std::env::current_dir() {
2404            Ok(cwd) => mapping.push((cwd, to.clone())),
2405            Err(_) => (),
2406        },
2407        None => (),
2408    };
2409    mapping
2410}
2411
2412fn parse_logical_env(
2413    early_dcx: &EarlyDiagCtxt,
2414    matches: &getopts::Matches,
2415) -> FxIndexMap<String, String> {
2416    let mut vars = FxIndexMap::default();
2417
2418    for arg in matches.opt_strs("env-set") {
2419        if let Some((name, val)) = arg.split_once('=') {
2420            vars.insert(name.to_string(), val.to_string());
2421        } else {
2422            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}`"));
2423        }
2424    }
2425
2426    vars
2427}
2428
2429// JUSTIFICATION: before wrapper fn is available
2430#[allow(rustc::bad_opt_access)]
2431pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::Matches) -> Options {
2432    let color = parse_color(early_dcx, matches);
2433
2434    let edition = parse_crate_edition(early_dcx, matches);
2435
2436    let crate_name = matches.opt_str("crate-name");
2437    let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
2438    let JsonConfig {
2439        json_rendered,
2440        json_color,
2441        json_artifact_notifications,
2442        json_timings,
2443        json_unused_externs,
2444        json_future_incompat,
2445    } = parse_json(early_dcx, matches);
2446
2447    let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered);
2448
2449    early_dcx.set_error_format(error_format);
2450
2451    let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
2452        early_dcx.early_fatal("`--diagnostic-width` must be an positive integer");
2453    });
2454
2455    let unparsed_crate_types = matches.opt_strs("crate-type");
2456    let crate_types = parse_crate_types_from_list(unparsed_crate_types)
2457        .unwrap_or_else(|e| early_dcx.early_fatal(e));
2458
2459    let mut target_modifiers = BTreeMap::<OptionsTargetModifiers, String>::new();
2460
2461    let mut unstable_opts = UnstableOptions::build(early_dcx, matches, &mut target_modifiers);
2462    let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches);
2463
2464    if !unstable_opts.unstable_options && json_timings {
2465        early_dcx.early_fatal("--json=timings is unstable and requires using `-Zunstable-options`");
2466    }
2467
2468    check_error_format_stability(
2469        early_dcx,
2470        &unstable_opts,
2471        unstable_features.is_nightly_build(),
2472        error_format,
2473    );
2474
2475    let output_types = parse_output_types(early_dcx, &unstable_opts, matches);
2476
2477    let mut cg = CodegenOptions::build(early_dcx, matches, &mut target_modifiers);
2478    let (disable_local_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto(
2479        early_dcx,
2480        &output_types,
2481        matches,
2482        cg.codegen_units,
2483    );
2484
2485    if unstable_opts.threads == 0 {
2486        early_dcx.early_fatal("value for threads must be a positive non-zero integer");
2487    }
2488
2489    if unstable_opts.threads == parse::MAX_THREADS_CAP {
2490        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));
2491    }
2492
2493    let incremental = cg.incremental.as_ref().map(PathBuf::from);
2494
2495    if cg.profile_generate.enabled() && cg.profile_use.is_some() {
2496        early_dcx.early_fatal("options `-C profile-generate` and `-C profile-use` are exclusive");
2497    }
2498
2499    if unstable_opts.profile_sample_use.is_some()
2500        && (cg.profile_generate.enabled() || cg.profile_use.is_some())
2501    {
2502        early_dcx.early_fatal(
2503            "option `-Z profile-sample-use` cannot be used with `-C profile-generate` or `-C profile-use`",
2504        );
2505    }
2506
2507    // Check for unstable values of `-C symbol-mangling-version`.
2508    // This is what prevents them from being used on stable compilers.
2509    match cg.symbol_mangling_version {
2510        // Stable values:
2511        None | Some(SymbolManglingVersion::V0) => {}
2512
2513        // Unstable values:
2514        Some(SymbolManglingVersion::Legacy) => {
2515            if !unstable_opts.unstable_options {
2516                early_dcx.early_fatal(
2517                    "`-C symbol-mangling-version=legacy` requires `-Z unstable-options`",
2518                );
2519            }
2520        }
2521        Some(SymbolManglingVersion::Hashed) => {
2522            if !unstable_opts.unstable_options {
2523                early_dcx.early_fatal(
2524                    "`-C symbol-mangling-version=hashed` requires `-Z unstable-options`",
2525                );
2526            }
2527        }
2528    }
2529
2530    if cg.instrument_coverage != InstrumentCoverage::No {
2531        if cg.profile_generate.enabled() || cg.profile_use.is_some() {
2532            early_dcx.early_fatal(
2533                "option `-C instrument-coverage` is not compatible with either `-C profile-use` \
2534                or `-C profile-generate`",
2535            );
2536        }
2537
2538        // `-C instrument-coverage` implies `-C symbol-mangling-version=v0` - to ensure consistent
2539        // and reversible name mangling. Note, LLVM coverage tools can analyze coverage over
2540        // multiple runs, including some changes to source code; so mangled names must be consistent
2541        // across compilations.
2542        match cg.symbol_mangling_version {
2543            None => cg.symbol_mangling_version = Some(SymbolManglingVersion::V0),
2544            Some(SymbolManglingVersion::Legacy) => {
2545                early_dcx.early_warn(
2546                    "-C instrument-coverage requires symbol mangling version `v0`, \
2547                    but `-C symbol-mangling-version=legacy` was specified",
2548                );
2549            }
2550            Some(SymbolManglingVersion::V0) => {}
2551            Some(SymbolManglingVersion::Hashed) => {
2552                early_dcx.early_warn(
2553                    "-C instrument-coverage requires symbol mangling version `v0`, \
2554                    but `-C symbol-mangling-version=hashed` was specified",
2555                );
2556            }
2557        }
2558    }
2559
2560    if let Ok(graphviz_font) = std::env::var("RUSTC_GRAPHVIZ_FONT") {
2561        // FIXME: this is only mutation of UnstableOptions here, move into
2562        // UnstableOptions::build?
2563        unstable_opts.graphviz_font = graphviz_font;
2564    }
2565
2566    if !cg.embed_bitcode {
2567        match cg.lto {
2568            LtoCli::No | LtoCli::Unspecified => {}
2569            LtoCli::Yes | LtoCli::NoParam | LtoCli::Thin | LtoCli::Fat => {
2570                early_dcx.early_fatal("options `-C embed-bitcode=no` and `-C lto` are incompatible")
2571            }
2572        }
2573    }
2574
2575    let unstable_options_enabled = nightly_options::is_unstable_enabled(matches);
2576    if !unstable_options_enabled && cg.force_frame_pointers == FramePointer::NonLeaf {
2577        early_dcx.early_fatal(
2578            "`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \
2579                and a nightly compiler",
2580        )
2581    }
2582
2583    if !nightly_options::is_unstable_enabled(matches) && !unstable_opts.offload.is_empty() {
2584        early_dcx.early_fatal(
2585            "`-Zoffload=Enable` also requires `-Zunstable-options` \
2586                and a nightly compiler",
2587        )
2588    }
2589
2590    let target_triple = parse_target_triple(early_dcx, matches);
2591
2592    // Ensure `-Z unstable-options` is required when using the unstable `-C link-self-contained` and
2593    // `-C linker-flavor` options.
2594    if !unstable_options_enabled {
2595        if let Err(error) = cg.link_self_contained.check_unstable_variants(&target_triple) {
2596            early_dcx.early_fatal(error);
2597        }
2598
2599        if let Some(flavor) = cg.linker_flavor {
2600            if flavor.is_unstable() {
2601                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!(
2602                    "the linker flavor `{}` is unstable, the `-Z unstable-options` \
2603                        flag must also be passed to use the unstable values",
2604                    flavor.desc()
2605                ));
2606            }
2607        }
2608    }
2609
2610    // Check `-C link-self-contained` for consistency: individual components cannot be both enabled
2611    // and disabled at the same time.
2612    if let Some(erroneous_components) = cg.link_self_contained.check_consistency() {
2613        let names: String = erroneous_components
2614            .into_iter()
2615            .map(|c| c.as_str().unwrap())
2616            .intersperse(", ")
2617            .collect();
2618        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!(
2619            "some `-C link-self-contained` components were both enabled and disabled: {names}"
2620        ));
2621    }
2622
2623    let prints = print_request::collect_print_requests(early_dcx, &mut cg, &unstable_opts, matches);
2624
2625    // -Zretpoline-external-thunk also requires -Zretpoline
2626    if unstable_opts.retpoline_external_thunk {
2627        unstable_opts.retpoline = true;
2628        target_modifiers.insert(
2629            OptionsTargetModifiers::UnstableOptions(UnstableOptionsTargetModifiers::retpoline),
2630            "true".to_string(),
2631        );
2632    }
2633
2634    let cg = cg;
2635
2636    let opt_level = parse_opt_level(early_dcx, matches, &cg);
2637    // The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
2638    // to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
2639    // for more details.
2640    let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
2641    let debuginfo = select_debuginfo(matches, &cg);
2642
2643    if !unstable_options_enabled {
2644        if let Err(error) = cg.linker_features.check_unstable_variants(&target_triple) {
2645            early_dcx.early_fatal(error);
2646        }
2647    }
2648
2649    if !unstable_options_enabled && cg.panic == Some(PanicStrategy::ImmediateAbort) {
2650        early_dcx.early_fatal(
2651            "`-Cpanic=immediate-abort` requires `-Zunstable-options` and a nightly compiler",
2652        )
2653    }
2654
2655    // Parse any `-l` flags, which link to native libraries.
2656    let libs = parse_native_libs(early_dcx, &unstable_opts, unstable_features, matches);
2657
2658    let test = matches.opt_present("test");
2659
2660    if !cg.remark.is_empty() && debuginfo == DebugInfo::None {
2661        early_dcx.early_warn("-C remark requires \"-C debuginfo=n\" to show source locations");
2662    }
2663
2664    if cg.remark.is_empty() && unstable_opts.remark_dir.is_some() {
2665        early_dcx
2666            .early_warn("using -Z remark-dir without enabling remarks using e.g. -C remark=all");
2667    }
2668
2669    let externs = parse_externs(early_dcx, matches, &unstable_opts);
2670
2671    let remap_path_prefix = parse_remap_path_prefix(early_dcx, matches, &unstable_opts);
2672    let remap_path_scope = parse_remap_path_scope(early_dcx, matches, &unstable_opts);
2673
2674    let pretty = parse_pretty(early_dcx, &unstable_opts);
2675
2676    // query-dep-graph is required if dump-dep-graph is given #106736
2677    if unstable_opts.dump_dep_graph && !unstable_opts.query_dep_graph {
2678        early_dcx.early_fatal("can't dump dependency graph without `-Z query-dep-graph`");
2679    }
2680
2681    let logical_env = parse_logical_env(early_dcx, matches);
2682
2683    let sysroot = Sysroot::new(matches.opt_str("sysroot").map(PathBuf::from));
2684
2685    let real_source_base_dir = |suffix: &str, confirm: &str| {
2686        let mut candidate = sysroot.path().join(suffix);
2687        if let Ok(metadata) = candidate.symlink_metadata() {
2688            // Replace the symlink bootstrap creates, with its destination.
2689            // We could try to use `fs::canonicalize` instead, but that might
2690            // produce unnecessarily verbose path.
2691            if metadata.file_type().is_symlink() {
2692                if let Ok(symlink_dest) = std::fs::read_link(&candidate) {
2693                    candidate = symlink_dest;
2694                }
2695            }
2696        }
2697
2698        // Only use this directory if it has a file we can expect to always find.
2699        candidate.join(confirm).is_file().then_some(candidate)
2700    };
2701
2702    let real_rust_source_base_dir =
2703        // This is the location used by the `rust-src` `rustup` component.
2704        real_source_base_dir("lib/rustlib/src/rust", "library/std/src/lib.rs");
2705
2706    let real_rustc_dev_source_base_dir =
2707        // This is the location used by the `rustc-dev` `rustup` component.
2708        real_source_base_dir("lib/rustlib/rustc-src/rust", "compiler/rustc/src/main.rs");
2709
2710    // We eagerly scan all files in each passed -L path. If the same directory is passed multiple
2711    // times, and the directory contains a lot of files, this can take a lot of time.
2712    // So we remove -L paths that were passed multiple times, and keep only the first occurrence.
2713    // We still have to keep the original order of the -L arguments.
2714    let search_paths: Vec<SearchPath> = {
2715        let mut seen_search_paths = FxHashSet::default();
2716        let search_path_matches: Vec<String> = matches.opt_strs("L");
2717        search_path_matches
2718            .iter()
2719            .filter(|p| seen_search_paths.insert(*p))
2720            .map(|path| {
2721                SearchPath::from_cli_opt(
2722                    sysroot.path(),
2723                    &target_triple,
2724                    early_dcx,
2725                    &path,
2726                    unstable_opts.unstable_options,
2727                )
2728            })
2729            .collect()
2730    };
2731
2732    // Ideally we would use `SourceMap::working_dir` instead, but we don't have access to it
2733    // so we manually create the potentially-remapped working directory
2734    let working_dir = {
2735        let working_dir = std::env::current_dir().unwrap_or_else(|e| {
2736            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}"));
2737        });
2738
2739        let file_mapping = file_path_mapping(remap_path_prefix.clone(), remap_path_scope);
2740        file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
2741    };
2742
2743    let verbose = matches.opt_present("verbose") || unstable_opts.verbose_internals;
2744
2745    Options {
2746        crate_types,
2747        optimize: opt_level,
2748        debuginfo,
2749        lint_opts,
2750        lint_cap,
2751        describe_lints,
2752        output_types,
2753        search_paths,
2754        sysroot,
2755        target_triple,
2756        test,
2757        incremental,
2758        untracked_state_hash: Default::default(),
2759        unstable_opts,
2760        prints,
2761        cg,
2762        error_format,
2763        diagnostic_width,
2764        externs,
2765        unstable_features,
2766        crate_name,
2767        libs,
2768        debug_assertions,
2769        actually_rustdoc: false,
2770        resolve_doc_links: ResolveDocLinks::ExportedMetadata,
2771        trimmed_def_paths: false,
2772        cli_forced_codegen_units: codegen_units,
2773        cli_forced_local_thinlto_off: disable_local_thinlto,
2774        remap_path_prefix,
2775        remap_path_scope,
2776        real_rust_source_base_dir,
2777        real_rustc_dev_source_base_dir,
2778        edition,
2779        json_artifact_notifications,
2780        json_timings,
2781        json_unused_externs,
2782        json_future_incompat,
2783        pretty,
2784        working_dir,
2785        color,
2786        logical_env,
2787        verbose,
2788        target_modifiers,
2789    }
2790}
2791
2792fn parse_pretty(early_dcx: &EarlyDiagCtxt, unstable_opts: &UnstableOptions) -> Option<PpMode> {
2793    use PpMode::*;
2794
2795    let first = match unstable_opts.unpretty.as_deref()? {
2796        "normal" => Source(PpSourceMode::Normal),
2797        "identified" => Source(PpSourceMode::Identified),
2798        "expanded" => Source(PpSourceMode::Expanded),
2799        "expanded,identified" => Source(PpSourceMode::ExpandedIdentified),
2800        "expanded,hygiene" => Source(PpSourceMode::ExpandedHygiene),
2801        "ast-tree" => AstTree,
2802        "ast-tree,expanded" => AstTreeExpanded,
2803        "hir" => Hir(PpHirMode::Normal),
2804        "hir,identified" => Hir(PpHirMode::Identified),
2805        "hir,typed" => Hir(PpHirMode::Typed),
2806        "hir-tree" => HirTree,
2807        "thir-tree" => ThirTree,
2808        "thir-flat" => ThirFlat,
2809        "mir" => Mir,
2810        "stable-mir" => StableMir,
2811        "mir-cfg" => MirCFG,
2812        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!(
2813            "argument to `unpretty` must be one of `normal`, `identified`, \
2814                            `expanded`, `expanded,identified`, `expanded,hygiene`, \
2815                            `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
2816                            `hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir`, `stable-mir`, or \
2817                            `mir-cfg`; got {name}"
2818        )),
2819    };
2820    {
    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:2820",
                        "rustc_session::config", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("compiler/rustc_session/src/config.rs"),
                        ::tracing_core::__macro_support::Option::Some(2820u32),
                        ::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:?}");
2821    Some(first)
2822}
2823
2824pub fn make_crate_type_option() -> RustcOptGroup {
2825    make_opt(
2826        OptionStability::Stable,
2827        OptionKind::Multi,
2828        "",
2829        "crate-type",
2830        "Comma separated list of types of crates
2831                                for the compiler to emit",
2832        "<bin|lib|rlib|dylib|cdylib|staticlib|proc-macro>",
2833    )
2834}
2835
2836pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> {
2837    let mut crate_types: Vec<CrateType> = Vec::new();
2838    for unparsed_crate_type in &list_list {
2839        for part in unparsed_crate_type.split(',') {
2840            let new_part = match part {
2841                "lib" => CrateType::default(),
2842                "rlib" => CrateType::Rlib,
2843                "staticlib" => CrateType::StaticLib,
2844                "dylib" => CrateType::Dylib,
2845                "cdylib" => CrateType::Cdylib,
2846                "bin" => CrateType::Executable,
2847                "proc-macro" => CrateType::ProcMacro,
2848                "sdylib" => CrateType::Sdylib,
2849                _ => {
2850                    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!(
2851                        "unknown crate type: `{part}`, expected one of: \
2852                        `lib`, `rlib`, `staticlib`, `dylib`, `cdylib`, `bin`, `proc-macro`",
2853                    ));
2854                }
2855            };
2856            if !crate_types.contains(&new_part) {
2857                crate_types.push(new_part)
2858            }
2859        }
2860    }
2861
2862    Ok(crate_types)
2863}
2864
2865pub mod nightly_options {
2866    use rustc_feature::UnstableFeatures;
2867
2868    use super::{OptionStability, RustcOptGroup};
2869    use crate::EarlyDiagCtxt;
2870
2871    pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
2872        match_is_nightly_build(matches)
2873            && matches.opt_strs("Z").iter().any(|x| *x == "unstable-options")
2874    }
2875
2876    pub fn match_is_nightly_build(matches: &getopts::Matches) -> bool {
2877        is_nightly_build(matches.opt_str("crate-name").as_deref())
2878    }
2879
2880    fn is_nightly_build(krate: Option<&str>) -> bool {
2881        UnstableFeatures::from_environment(krate).is_nightly_build()
2882    }
2883
2884    pub fn check_nightly_options(
2885        early_dcx: &EarlyDiagCtxt,
2886        matches: &getopts::Matches,
2887        flags: &[RustcOptGroup],
2888    ) {
2889        let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options");
2890        let really_allows_unstable_options = match_is_nightly_build(matches);
2891        let mut nightly_options_on_stable = 0;
2892
2893        for opt in flags.iter() {
2894            if opt.stability == OptionStability::Stable {
2895                continue;
2896            }
2897            if !matches.opt_present(opt.name) {
2898                continue;
2899            }
2900            if opt.name != "Z" && !has_z_unstable_option {
2901                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!(
2902                    "the `-Z unstable-options` flag must also be passed to enable \
2903                         the flag `{}`",
2904                    opt.name
2905                ));
2906            }
2907            if really_allows_unstable_options {
2908                continue;
2909            }
2910            match opt.stability {
2911                OptionStability::Unstable => {
2912                    nightly_options_on_stable += 1;
2913                    let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the option `{0}` is only accepted on the nightly compiler",
                opt.name))
    })format!(
2914                        "the option `{}` is only accepted on the nightly compiler",
2915                        opt.name
2916                    );
2917                    // The non-zero nightly_options_on_stable will force an early_fatal eventually.
2918                    let _ = early_dcx.early_err(msg);
2919                }
2920                OptionStability::Stable => {}
2921            }
2922        }
2923        if nightly_options_on_stable > 0 {
2924            early_dcx
2925                .early_help("consider switching to a nightly toolchain: `rustup default nightly`");
2926            early_dcx.early_note("selecting a toolchain with `+toolchain` arguments require a rustup proxy; see <https://rust-lang.github.io/rustup/concepts/index.html>");
2927            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>");
2928            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!(
2929                "{} nightly option{} were parsed",
2930                nightly_options_on_stable,
2931                if nightly_options_on_stable > 1 { "s" } else { "" }
2932            ));
2933        }
2934    }
2935}
2936
2937#[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)]
2938pub enum PpSourceMode {
2939    /// `-Zunpretty=normal`
2940    Normal,
2941    /// `-Zunpretty=expanded`
2942    Expanded,
2943    /// `-Zunpretty=identified`
2944    Identified,
2945    /// `-Zunpretty=expanded,identified`
2946    ExpandedIdentified,
2947    /// `-Zunpretty=expanded,hygiene`
2948    ExpandedHygiene,
2949}
2950
2951#[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)]
2952pub enum PpHirMode {
2953    /// `-Zunpretty=hir`
2954    Normal,
2955    /// `-Zunpretty=hir,identified`
2956    Identified,
2957    /// `-Zunpretty=hir,typed`
2958    Typed,
2959}
2960
2961#[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)]
2962/// Pretty print mode
2963pub enum PpMode {
2964    /// Options that print the source code, i.e.
2965    /// `-Zunpretty=normal` and `-Zunpretty=expanded`
2966    Source(PpSourceMode),
2967    /// `-Zunpretty=ast-tree`
2968    AstTree,
2969    /// `-Zunpretty=ast-tree,expanded`
2970    AstTreeExpanded,
2971    /// Options that print the HIR, i.e. `-Zunpretty=hir`
2972    Hir(PpHirMode),
2973    /// `-Zunpretty=hir-tree`
2974    HirTree,
2975    /// `-Zunpretty=thir-tree`
2976    ThirTree,
2977    /// `-Zunpretty=thir-flat`
2978    ThirFlat,
2979    /// `-Zunpretty=mir`
2980    Mir,
2981    /// `-Zunpretty=mir-cfg`
2982    MirCFG,
2983    /// `-Zunpretty=stable-mir`
2984    StableMir,
2985}
2986
2987impl PpMode {
2988    pub fn needs_ast_map(&self) -> bool {
2989        use PpMode::*;
2990        use PpSourceMode::*;
2991        match *self {
2992            Source(Normal | Identified) | AstTree => false,
2993
2994            Source(Expanded | ExpandedIdentified | ExpandedHygiene)
2995            | AstTreeExpanded
2996            | Hir(_)
2997            | HirTree
2998            | ThirTree
2999            | ThirFlat
3000            | Mir
3001            | MirCFG
3002            | StableMir => true,
3003        }
3004    }
3005
3006    pub fn needs_analysis(&self) -> bool {
3007        use PpMode::*;
3008        #[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)
3009    }
3010}
3011
3012#[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)]
3013pub enum WasiExecModel {
3014    Command,
3015    Reactor,
3016}
3017
3018/// Command-line arguments passed to the compiler have to be incorporated with
3019/// the dependency tracking system for incremental compilation. This module
3020/// provides some utilities to make this more convenient.
3021///
3022/// The values of all command-line arguments that are relevant for dependency
3023/// tracking are hashed into a single value that determines whether the
3024/// incremental compilation cache can be re-used or not. This hashing is done
3025/// via the `DepTrackingHash` trait defined below, since the standard `Hash`
3026/// implementation might not be suitable (e.g., arguments are stored in a `Vec`,
3027/// the hash of which is order dependent, but we might not want the order of
3028/// arguments to make a difference for the hash).
3029///
3030/// However, since the value provided by `Hash::hash` often *is* suitable,
3031/// especially for primitive types, there is the
3032/// `impl_dep_tracking_hash_via_hash!()` macro that allows to simply reuse the
3033/// `Hash` implementation for `DepTrackingHash`. It's important though that
3034/// we have an opt-in scheme here, so one is hopefully forced to think about
3035/// how the hash should be calculated when adding a new command-line argument.
3036pub(crate) mod dep_tracking {
3037    use std::collections::BTreeMap;
3038    use std::hash::Hash;
3039    use std::num::NonZero;
3040    use std::path::PathBuf;
3041
3042    use rustc_abi::Align;
3043    use rustc_data_structures::fx::FxIndexMap;
3044    use rustc_data_structures::stable_hasher::StableHasher;
3045    use rustc_errors::LanguageIdentifier;
3046    use rustc_feature::UnstableFeatures;
3047    use rustc_hashes::Hash64;
3048    use rustc_hir::attrs::CollapseMacroDebuginfo;
3049    use rustc_span::edition::Edition;
3050    use rustc_span::{RealFileName, RemapPathScopeComponents};
3051    use rustc_target::spec::{
3052        CodeModel, FramePointer, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel,
3053        RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility, TargetTuple,
3054        TlsModel,
3055    };
3056
3057    use super::{
3058        AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CoverageOptions,
3059        CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn,
3060        InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
3061        LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, OutFileName, OutputType,
3062        OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks, SourceFileHashAlgorithm,
3063        SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
3064    };
3065    use crate::lint;
3066    use crate::utils::NativeLib;
3067
3068    pub(crate) trait DepTrackingHash {
3069        fn hash(
3070            &self,
3071            hasher: &mut StableHasher,
3072            error_format: ErrorOutputType,
3073            for_crate_hash: bool,
3074        );
3075    }
3076
3077    macro_rules! impl_dep_tracking_hash_via_hash {
3078        ($($t:ty),+ $(,)?) => {$(
3079            impl DepTrackingHash for $t {
3080                fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType, _for_crate_hash: bool) {
3081                    Hash::hash(self, hasher);
3082                }
3083            }
3084        )+};
3085    }
3086
3087    impl<T: DepTrackingHash> DepTrackingHash for Option<T> {
3088        fn hash(
3089            &self,
3090            hasher: &mut StableHasher,
3091            error_format: ErrorOutputType,
3092            for_crate_hash: bool,
3093        ) {
3094            match self {
3095                Some(x) => {
3096                    Hash::hash(&1, hasher);
3097                    DepTrackingHash::hash(x, hasher, error_format, for_crate_hash);
3098                }
3099                None => Hash::hash(&0, hasher),
3100            }
3101        }
3102    }
3103
3104    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!(
3105        (),
3106        AnnotateMoves,
3107        AutoDiff,
3108        Offload,
3109        bool,
3110        usize,
3111        NonZero<usize>,
3112        u64,
3113        Hash64,
3114        String,
3115        PathBuf,
3116        lint::Level,
3117        WasiExecModel,
3118        u32,
3119        FramePointer,
3120        RelocModel,
3121        CodeModel,
3122        TlsModel,
3123        InstrumentCoverage,
3124        CoverageOptions,
3125        InstrumentXRay,
3126        CrateType,
3127        MergeFunctions,
3128        OnBrokenPipe,
3129        PanicStrategy,
3130        RelroLevel,
3131        OptLevel,
3132        LtoCli,
3133        DebugInfo,
3134        DebugInfoCompression,
3135        MirStripDebugInfo,
3136        CollapseMacroDebuginfo,
3137        UnstableFeatures,
3138        NativeLib,
3139        SanitizerSet,
3140        CFGuard,
3141        CFProtection,
3142        TargetTuple,
3143        Edition,
3144        LinkerPluginLto,
3145        ResolveDocLinks,
3146        SplitDebuginfo,
3147        SplitDwarfKind,
3148        StackProtector,
3149        SwitchWithOptPath,
3150        SymbolManglingVersion,
3151        SymbolVisibility,
3152        RemapPathScopeComponents,
3153        SourceFileHashAlgorithm,
3154        OutFileName,
3155        OutputType,
3156        RealFileName,
3157        LocationDetail,
3158        FmtDebug,
3159        BranchProtection,
3160        LanguageIdentifier,
3161        NextSolverConfig,
3162        PatchableFunctionEntry,
3163        Polonius,
3164        InliningThreshold,
3165        FunctionReturn,
3166        Align,
3167    );
3168
3169    impl<T1, T2> DepTrackingHash for (T1, T2)
3170    where
3171        T1: DepTrackingHash,
3172        T2: DepTrackingHash,
3173    {
3174        fn hash(
3175            &self,
3176            hasher: &mut StableHasher,
3177            error_format: ErrorOutputType,
3178            for_crate_hash: bool,
3179        ) {
3180            Hash::hash(&0, hasher);
3181            DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash);
3182            Hash::hash(&1, hasher);
3183            DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash);
3184        }
3185    }
3186
3187    impl<T1, T2, T3> DepTrackingHash for (T1, T2, T3)
3188    where
3189        T1: DepTrackingHash,
3190        T2: DepTrackingHash,
3191        T3: DepTrackingHash,
3192    {
3193        fn hash(
3194            &self,
3195            hasher: &mut StableHasher,
3196            error_format: ErrorOutputType,
3197            for_crate_hash: bool,
3198        ) {
3199            Hash::hash(&0, hasher);
3200            DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash);
3201            Hash::hash(&1, hasher);
3202            DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash);
3203            Hash::hash(&2, hasher);
3204            DepTrackingHash::hash(&self.2, hasher, error_format, for_crate_hash);
3205        }
3206    }
3207
3208    impl<T: DepTrackingHash> DepTrackingHash for Vec<T> {
3209        fn hash(
3210            &self,
3211            hasher: &mut StableHasher,
3212            error_format: ErrorOutputType,
3213            for_crate_hash: bool,
3214        ) {
3215            Hash::hash(&self.len(), hasher);
3216            for (index, elem) in self.iter().enumerate() {
3217                Hash::hash(&index, hasher);
3218                DepTrackingHash::hash(elem, hasher, error_format, for_crate_hash);
3219            }
3220        }
3221    }
3222
3223    impl<T: DepTrackingHash, V: DepTrackingHash> DepTrackingHash for FxIndexMap<T, V> {
3224        fn hash(
3225            &self,
3226            hasher: &mut StableHasher,
3227            error_format: ErrorOutputType,
3228            for_crate_hash: bool,
3229        ) {
3230            Hash::hash(&self.len(), hasher);
3231            for (key, value) in self.iter() {
3232                DepTrackingHash::hash(key, hasher, error_format, for_crate_hash);
3233                DepTrackingHash::hash(value, hasher, error_format, for_crate_hash);
3234            }
3235        }
3236    }
3237
3238    impl DepTrackingHash for OutputTypes {
3239        fn hash(
3240            &self,
3241            hasher: &mut StableHasher,
3242            error_format: ErrorOutputType,
3243            for_crate_hash: bool,
3244        ) {
3245            Hash::hash(&self.0.len(), hasher);
3246            for (key, val) in &self.0 {
3247                DepTrackingHash::hash(key, hasher, error_format, for_crate_hash);
3248                if !for_crate_hash {
3249                    DepTrackingHash::hash(val, hasher, error_format, for_crate_hash);
3250                }
3251            }
3252        }
3253    }
3254
3255    // This is a stable hash because BTreeMap is a sorted container
3256    pub(crate) fn stable_hash(
3257        sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>,
3258        hasher: &mut StableHasher,
3259        error_format: ErrorOutputType,
3260        for_crate_hash: bool,
3261    ) {
3262        for (key, sub_hash) in sub_hashes {
3263            // Using Hash::hash() instead of DepTrackingHash::hash() is fine for
3264            // the keys, as they are just plain strings
3265            Hash::hash(&key.len(), hasher);
3266            Hash::hash(key, hasher);
3267            sub_hash.hash(hasher, error_format, for_crate_hash);
3268        }
3269    }
3270}
3271
3272/// How to run proc-macro code when building this crate
3273#[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)]
3274pub enum ProcMacroExecutionStrategy {
3275    /// Run the proc-macro code on the same thread as the server.
3276    SameThread,
3277
3278    /// Run the proc-macro code on a different thread.
3279    CrossThread,
3280}
3281
3282/// Which format to use for `-Z dump-mono-stats`
3283#[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)]
3284pub enum DumpMonoStatsFormat {
3285    /// Pretty-print a markdown table
3286    Markdown,
3287    /// Emit structured JSON
3288    Json,
3289}
3290
3291impl DumpMonoStatsFormat {
3292    pub fn extension(self) -> &'static str {
3293        match self {
3294            Self::Markdown => "md",
3295            Self::Json => "json",
3296        }
3297    }
3298}
3299
3300/// `-Z patchable-function-entry` representation - how many nops to put before and after function
3301/// entry.
3302#[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)]
3303pub struct PatchableFunctionEntry {
3304    /// Nops before the entry
3305    prefix: u8,
3306    /// Nops after the entry
3307    entry: u8,
3308}
3309
3310impl PatchableFunctionEntry {
3311    pub fn from_total_and_prefix_nops(
3312        total_nops: u8,
3313        prefix_nops: u8,
3314    ) -> Option<PatchableFunctionEntry> {
3315        if total_nops < prefix_nops {
3316            None
3317        } else {
3318            Some(Self { prefix: prefix_nops, entry: total_nops - prefix_nops })
3319        }
3320    }
3321    pub fn prefix(&self) -> u8 {
3322        self.prefix
3323    }
3324    pub fn entry(&self) -> u8 {
3325        self.entry
3326    }
3327}
3328
3329/// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy,
3330/// or future prototype.
3331#[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)]
3332pub enum Polonius {
3333    /// The default value: disabled.
3334    #[default]
3335    Off,
3336
3337    /// Legacy version, using datalog and the `polonius-engine` crate. Historical value for `-Zpolonius`.
3338    Legacy,
3339
3340    /// In-tree prototype, extending the NLL infrastructure.
3341    Next,
3342}
3343
3344impl Polonius {
3345    /// Returns whether the legacy version of polonius is enabled
3346    pub fn is_legacy_enabled(&self) -> bool {
3347        #[allow(non_exhaustive_omitted_patterns)] match self {
    Polonius::Legacy => true,
    _ => false,
}matches!(self, Polonius::Legacy)
3348    }
3349
3350    /// Returns whether the "next" version of polonius is enabled
3351    pub fn is_next_enabled(&self) -> bool {
3352        #[allow(non_exhaustive_omitted_patterns)] match self {
    Polonius::Next => true,
    _ => false,
}matches!(self, Polonius::Next)
3353    }
3354}
3355
3356#[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)]
3357pub enum InliningThreshold {
3358    Always,
3359    Sometimes(usize),
3360    Never,
3361}
3362
3363impl Default for InliningThreshold {
3364    fn default() -> Self {
3365        Self::Sometimes(100)
3366    }
3367}
3368
3369/// The different settings that the `-Zfunction-return` flag can have.
3370#[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)]
3371pub enum FunctionReturn {
3372    /// Keep the function return unmodified.
3373    #[default]
3374    Keep,
3375
3376    /// Replace returns with jumps to thunk, without emitting the thunk.
3377    ThunkExtern,
3378}
3379
3380/// Whether extra span comments are included when dumping MIR, via the `-Z mir-include-spans` flag.
3381/// By default, only enabled in the NLL MIR dumps, and disabled in all other passes.
3382#[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)]
3383pub enum MirIncludeSpans {
3384    Off,
3385    On,
3386    /// Default: include extra comments in NLL MIR dumps only. Can be ignored and considered as
3387    /// `Off` in all other cases.
3388    #[default]
3389    Nll,
3390}
3391
3392impl MirIncludeSpans {
3393    /// Unless opting into extra comments for all passes, they can be considered disabled.
3394    /// The cases where a distinction between on/off and a per-pass value can exist will be handled
3395    /// in the passes themselves: i.e. the `Nll` value is considered off for all intents and
3396    /// purposes, except for the NLL MIR dump pass.
3397    pub fn is_enabled(self) -> bool {
3398        self == MirIncludeSpans::On
3399    }
3400}