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