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;
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_structures::CrateType;
30use rustc_target::spec::{
31    FramePointer, LinkSelfContainedComponents, LinkerFeatures, PanicStrategy, SplitDebuginfo,
32    Target, TargetTuple,
33};
34use tracing::debug;
35
36pub use crate::config::cfg::{Cfg, CheckCfg, ExpectedValues};
37use crate::config::native_libs::parse_native_libs;
38pub use crate::config::print_request::{
39    PrintCategory, PrintKind, PrintRequest, collect_print_requests,
40};
41use crate::diagnostics::FileWriteFail;
42use crate::macros::AllVariants;
43pub use crate::options::*;
44use crate::search_paths::SearchPath;
45use crate::utils::CanonicalizedPath;
46use crate::{EarlyDiagCtxt, Session, filesearch, lint};
47
48mod cfg;
49mod externs;
50mod native_libs;
51mod print_request;
52pub mod sigpipe;
53
54/// Special CPU name requesting the CPU of the current host.
55pub const NATIVE_CPU: &str = "native";
56
57/// The different settings that the `-C strip` flag can have.
58#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Strip { }
#[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::marker::StructuralPartialEq for Strip { }
#[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)]
59pub enum Strip {
60    /// Do not strip at all.
61    None,
62
63    /// Strip debuginfo.
64    Debuginfo,
65
66    /// Strip all symbols.
67    Symbols,
68}
69
70/// The different settings that the `-C control-flow-guard` flag can have.
71#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for CFGuard { }
#[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::marker::StructuralPartialEq for CFGuard { }
#[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)]
72pub enum CFGuard {
73    /// Do not emit Control Flow Guard metadata or checks.
74    Disabled,
75
76    /// Emit Control Flow Guard metadata but no checks.
77    NoChecks,
78
79    /// Emit Control Flow Guard metadata and checks.
80    Checks,
81}
82
83/// The different settings that the `-Z cf-protection` flag can have.
84#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for CFProtection { }
#[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::marker::StructuralPartialEq for CFProtection { }
#[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)]
85pub enum CFProtection {
86    /// Do not enable control-flow protection
87    None,
88
89    /// Emit control-flow protection for branches (enables indirect branch tracking).
90    Branch,
91
92    /// Emit control-flow protection for returns.
93    Return,
94
95    /// Emit control-flow protection for both branches and returns.
96    Full,
97}
98
99#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for OptLevel { }
#[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::marker::StructuralPartialEq for OptLevel { }
#[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);
            }
        }
    };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)]
100pub enum OptLevel {
101    /// `-Copt-level=0`
102    No,
103    /// `-Copt-level=1`
104    Less,
105    /// `-Copt-level=2`
106    More,
107    /// `-Copt-level=3` / `-O`
108    Aggressive,
109    /// `-Copt-level=s`
110    Size,
111    /// `-Copt-level=z`
112    SizeMin,
113}
114
115/// This is what the `LtoCli` values get mapped to after resolving defaults and
116/// and taking other command line options into account.
117///
118/// Note that linker plugin-based LTO is a different mechanism entirely.
119#[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::marker::StructuralPartialEq for Lto { }
#[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);
            }
        }
    };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)]
120pub enum Lto {
121    /// Don't do any LTO whatsoever.
122    No,
123
124    /// Do a full-crate-graph (inter-crate) LTO with ThinLTO.
125    Thin,
126
127    /// Do a local ThinLTO (intra-crate, over the CodeGen Units of the local crate only). This is
128    /// only relevant if multiple CGUs are used.
129    ThinLocal,
130
131    /// Do a full-crate-graph (inter-crate) LTO with "fat" LTO.
132    Fat,
133}
134
135/// The different settings that the `-C lto` flag can have.
136#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for LtoCli { }
#[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::marker::StructuralPartialEq for LtoCli { }
#[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)]
137pub enum LtoCli {
138    /// `-C lto=no`
139    No,
140    /// `-C lto=yes`
141    Yes,
142    /// `-C lto`
143    NoParam,
144    /// `-C lto=thin`
145    Thin,
146    /// `-C lto=fat`
147    Fat,
148    /// No `-C lto` flag passed
149    Unspecified,
150}
151
152/// The different settings that the `-C instrument-coverage` flag can have.
153#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for InstrumentCoverage { }
#[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::marker::StructuralPartialEq for InstrumentCoverage { }
#[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)]
154pub enum InstrumentCoverage {
155    /// `-C instrument-coverage=no` (or `off`, `false` etc.)
156    No,
157    /// `-C instrument-coverage` or `-C instrument-coverage=yes`
158    Yes,
159}
160
161/// Individual flag values controlled by `-Zcoverage-options`.
162#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for CoverageOptions { }
#[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::marker::StructuralPartialEq for CoverageOptions { }
#[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)]
163pub struct CoverageOptions {
164    pub level: CoverageLevel,
165
166    /// **(internal test-only flag)**
167    /// `-Zcoverage-options=discard-all-spans-in-codegen`: During codegen,
168    /// discard all coverage spans as though they were invalid. Needed by
169    /// regression tests for #133606, because we don't have an easy way to
170    /// reproduce it from actual source code.
171    pub discard_all_spans_in_codegen: bool,
172}
173
174/// Controls whether branch coverage is enabled.
175#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for CoverageLevel { }
#[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::marker::StructuralPartialEq for CoverageLevel { }
#[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)]
176pub enum CoverageLevel {
177    /// Instrument for coverage at the MIR block level.
178    #[default]
179    Block,
180    /// Also instrument branch points (includes block coverage).
181    Branch,
182    /// Same as branch coverage, but also adds branch instrumentation for
183    /// certain boolean expressions that are not directly used for branching.
184    ///
185    /// For example, in the following code, `b` does not directly participate
186    /// in a branch, but condition coverage will instrument it as its own
187    /// artificial branch:
188    /// ```
189    /// # let (a, b) = (false, true);
190    /// let x = a && b;
191    /// //           ^ last operand
192    /// ```
193    ///
194    /// This level is mainly intended to be a stepping-stone towards full MC/DC
195    /// instrumentation, so it might be removed in the future when MC/DC is
196    /// sufficiently complete, or if it is making MC/DC changes difficult.
197    Condition,
198}
199
200// The different settings that the `-Z offload` flag can have.
201#[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::marker::StructuralPartialEq for Offload { }
#[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)]
202pub enum Offload {
203    /// Second step in the offload pipeline, enables kernel compilation for a gpu device
204    /// Reads a manifest of required generic kernel instantiations
205    /// produced by a previous `HostMetadata` pass. An empty manifest
206    /// means there are no generic kernels at all, or that generic kernels are only
207    /// called from non-generic device entry points and never from the host, so we
208    /// don't need to track their instantiations.
209    Device(String),
210    /// Third step in the offload pipeline, generates the host code to call kernels.
211    Host(String),
212    /// Test is similar to Host, but allows testing without a device artifact.
213    Test,
214    /// First step in the offload pipeline: compile for the host but only emit a manifest of
215    /// kernel instantiations required by the host code.
216    HostMetadata(String),
217}
218
219/// The different settings that the `-Z codegen-emit-retag` flag can have.
220#[derive(#[automatically_derived]
impl ::core::marker::Copy for CodegenRetagOptions { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for CodegenRetagOptions { }
#[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::marker::StructuralPartialEq for CodegenRetagOptions { }
#[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) {
                let CodegenRetagOptions {
                        no_precise_im: ref __binding_0,
                        no_precise_pin: ref __binding_1 } = *self;
                ::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)]
221pub struct CodegenRetagOptions {
222    /// Track interior mutable data on the level of references, instead of on the byte level.
223    pub no_precise_im: bool,
224    /// Track `UnsafePinned` data on the level of references, instead of on the byte level.
225    pub no_precise_pin: bool,
226}
227
228/// The different settings that the `-Z autodiff` flag can have.
229#[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::marker::StructuralPartialEq for AutoDiff { }
#[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)]
230pub enum AutoDiff {
231    /// Enable the autodiff opt pipeline
232    Enable,
233
234    /// Print TypeAnalysis information
235    PrintTA,
236    /// Print TypeAnalysis information for a specific function
237    PrintTAFn(String),
238    /// Print ActivityAnalysis Information
239    PrintAA,
240    /// Print Performance Warnings from Enzyme
241    PrintPerf,
242    /// Print intermediate IR generation steps
243    PrintSteps,
244    /// Print the module, before running autodiff.
245    PrintModBefore,
246    /// Print the module after running autodiff.
247    PrintModAfter,
248    /// Print the module after running autodiff and optimizations.
249    PrintModFinal,
250
251    /// Print all passes scheduled by LLVM
252    PrintPasses,
253    /// Disable extra opt run after running autodiff
254    NoPostopt,
255    /// Enzyme's loose type debug helper (can cause incorrect gradients!!)
256    /// Usable in cases where Enzyme errors with `can not deduce type of X`.
257    LooseTypes,
258    /// Runs Enzyme's aggressive inlining
259    Inline,
260    /// Disable Type Tree
261    NoTT,
262}
263
264/// The different settings that the `-Z annotate-moves` flag can have.
265#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for AnnotateMoves { }
#[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::marker::StructuralPartialEq for AnnotateMoves { }
#[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)]
266pub enum AnnotateMoves {
267    /// `-Z annotate-moves=no` (or `off`, `false` etc.)
268    Disabled,
269    /// `-Z annotate-moves` or `-Z annotate-moves=yes` (use default size limit)
270    /// `-Z annotate-moves=SIZE` (use specified size limit)
271    Enabled(Option<u64>),
272}
273
274#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for InstrumentMcountOpts { }
#[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::marker::StructuralPartialEq for InstrumentMcountOpts { }
#[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)]
275pub struct InstrumentMcountOpts {
276    // Insert a nop which could be replaced by an mcount call.
277    pub no_call: bool,
278    // Record the location of the call instrument in a special linker section.
279    pub record: bool,
280}
281
282/// The different settings that the `-Z Instrument-mcount` flag can have.
283#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for InstrumentMcount { }
#[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::marker::StructuralPartialEq for InstrumentMcount { }
#[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)]
284pub enum InstrumentMcount {
285    /// `-Z instrument-mcount=no`
286    Disabled,
287    /// `-Z instrument-mcount=yes`
288    Mcount(InstrumentMcountOpts),
289    /// `-Z instrument-mcount=fentry`
290    Fentry(InstrumentMcountOpts),
291}
292
293/// Settings for `-Z instrument-xray` flag.
294#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for InstrumentXRay { }
#[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::marker::StructuralPartialEq for InstrumentXRay { }
#[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)]
295pub struct InstrumentXRay {
296    /// `-Z instrument-xray=always`, force instrumentation
297    pub always: bool,
298    /// `-Z instrument-xray=never`, disable instrumentation
299    pub never: bool,
300    /// `-Z instrument-xray=ignore-loops`, ignore presence of loops,
301    /// instrument functions based only on instruction count
302    pub ignore_loops: bool,
303    /// `-Z instrument-xray=instruction-threshold=N`, explicitly set instruction threshold
304    /// for instrumentation, or `None` to use compiler's default
305    pub instruction_threshold: Option<usize>,
306    /// `-Z instrument-xray=skip-entry`, do not instrument function entry
307    pub skip_entry: bool,
308    /// `-Z instrument-xray=skip-exit`, do not instrument function exit
309    pub skip_exit: bool,
310}
311
312#[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::marker::StructuralPartialEq for LinkerPluginLto { }
#[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)]
313pub enum LinkerPluginLto {
314    LinkerPlugin(PathBuf),
315    LinkerPluginAuto,
316    Disabled,
317}
318
319impl LinkerPluginLto {
320    pub fn enabled(&self) -> bool {
321        match *self {
322            LinkerPluginLto::LinkerPlugin(_) | LinkerPluginLto::LinkerPluginAuto => true,
323            LinkerPluginLto::Disabled => false,
324        }
325    }
326}
327
328/// The different values `-C link-self-contained` can take: a list of individually enabled or
329/// disabled components used during linking, coming from the rustc distribution, instead of being
330/// found somewhere on the host system.
331///
332/// They can be set in bulk via `-C link-self-contained=yes|y|on` or `-C
333/// link-self-contained=no|n|off`, and those boolean values are the historical defaults.
334///
335/// But each component is fine-grained, and can be unstably targeted, to use:
336/// - some CRT objects
337/// - the libc static library
338/// - libgcc/libunwind libraries
339/// - a linker we distribute
340/// - some sanitizer runtime libraries
341/// - all other MinGW libraries and Windows import libs
342///
343#[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::marker::StructuralPartialEq for LinkSelfContained { }
#[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)]
344pub struct LinkSelfContained {
345    /// Whether the user explicitly set `-C link-self-contained` on or off, the historical values.
346    /// Used for compatibility with the existing opt-in and target inference.
347    pub explicitly_set: Option<bool>,
348
349    /// The components that are enabled on the CLI, using the `+component` syntax or one of the
350    /// `true` shortcuts.
351    enabled_components: LinkSelfContainedComponents,
352
353    /// The components that are disabled on the CLI, using the `-component` syntax or one of the
354    /// `false` shortcuts.
355    disabled_components: LinkSelfContainedComponents,
356}
357
358impl LinkSelfContained {
359    /// Incorporates an enabled or disabled component as specified on the CLI, if possible.
360    /// For example: `+linker`, and `-crto`.
361    pub(crate) fn handle_cli_component(&mut self, component: &str) -> Option<()> {
362        // Note that for example `-Cself-contained=y -Cself-contained=-linker` is not an explicit
363        // set of all values like `y` or `n` used to be. Therefore, if this flag had previously been
364        // set in bulk with its historical values, then manually setting a component clears that
365        // `explicitly_set` state.
366        if let Some(component_to_enable) = component.strip_prefix('+') {
367            self.explicitly_set = None;
368            self.enabled_components
369                .insert(LinkSelfContainedComponents::from_str(component_to_enable).ok()?);
370            Some(())
371        } else if let Some(component_to_disable) = component.strip_prefix('-') {
372            self.explicitly_set = None;
373            self.disabled_components
374                .insert(LinkSelfContainedComponents::from_str(component_to_disable).ok()?);
375            Some(())
376        } else {
377            None
378        }
379    }
380
381    /// Turns all components on or off and records that this was done explicitly for compatibility
382    /// purposes.
383    pub(crate) fn set_all_explicitly(&mut self, enabled: bool) {
384        self.explicitly_set = Some(enabled);
385
386        if enabled {
387            self.enabled_components = LinkSelfContainedComponents::all();
388            self.disabled_components = LinkSelfContainedComponents::empty();
389        } else {
390            self.enabled_components = LinkSelfContainedComponents::empty();
391            self.disabled_components = LinkSelfContainedComponents::all();
392        }
393    }
394
395    /// Helper creating a fully enabled `LinkSelfContained` instance. Used in tests.
396    pub fn on() -> Self {
397        let mut on = LinkSelfContained::default();
398        on.set_all_explicitly(true);
399        on
400    }
401
402    /// To help checking CLI usage while some of the values are unstable: returns whether one of the
403    /// unstable components was set individually, for the given `TargetTuple`. This would also
404    /// require the `-Zunstable-options` flag, to be allowed.
405    fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
406        if self.explicitly_set.is_some() {
407            return Ok(());
408        }
409
410        // `-C link-self-contained=-linker` is only stable on x64 linux.
411        let has_minus_linker = self.disabled_components.is_linker_enabled();
412        if has_minus_linker && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
413            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!(
414                "`-C link-self-contained=-linker` is unstable on the `{target_tuple}` \
415                    target. The `-Z unstable-options` flag must also be passed to use it on this target",
416            ));
417        }
418
419        // Any `+linker` or other component used is unstable, and that's an error.
420        let unstable_enabled = self.enabled_components;
421        let unstable_disabled = self.disabled_components - LinkSelfContainedComponents::LINKER;
422        if !unstable_enabled.union(unstable_disabled).is_empty() {
423            return Err(String::from(
424                "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` \
425                are stable, the `-Z unstable-options` flag must also be passed to use \
426                the unstable values",
427            ));
428        }
429
430        Ok(())
431    }
432
433    /// Returns whether the self-contained linker component was enabled on the CLI, using the
434    /// `-C link-self-contained=+linker` syntax, or one of the `true` shortcuts.
435    pub fn is_linker_enabled(&self) -> bool {
436        self.enabled_components.contains(LinkSelfContainedComponents::LINKER)
437    }
438
439    /// Returns whether the self-contained linker component was disabled on the CLI, using the
440    /// `-C link-self-contained=-linker` syntax, or one of the `false` shortcuts.
441    pub fn is_linker_disabled(&self) -> bool {
442        self.disabled_components.contains(LinkSelfContainedComponents::LINKER)
443    }
444
445    /// Returns CLI inconsistencies to emit errors: individual components were both enabled and
446    /// disabled.
447    fn check_consistency(&self) -> Option<LinkSelfContainedComponents> {
448        if self.explicitly_set.is_some() {
449            None
450        } else {
451            let common = self.enabled_components.intersection(self.disabled_components);
452            if common.is_empty() { None } else { Some(common) }
453        }
454    }
455}
456
457/// The different values that `-C linker-features` can take on the CLI: a list of individually
458/// enabled or disabled features used during linking.
459///
460/// There is no need to enable or disable them in bulk. Each feature is fine-grained, and can be
461/// used to turn `LinkerFeatures` on or off, without needing to change the linker flavor:
462/// - using the system lld, or the self-contained `rust-lld` linker
463/// - using a C/C++ compiler to drive the linker (not yet exposed on the CLI)
464/// - etc.
465#[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]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for LinkerFeaturesCli { }
#[automatically_derived]
impl ::core::clone::Clone for LinkerFeaturesCli {
    #[inline]
    fn clone(&self) -> LinkerFeaturesCli {
        let _: ::core::clone::AssertParamIsClone<LinkerFeatures>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for LinkerFeaturesCli { }
#[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)]
466pub struct LinkerFeaturesCli {
467    /// The linker features that are enabled on the CLI, using the `+feature` syntax.
468    pub enabled: LinkerFeatures,
469
470    /// The linker features that are disabled on the CLI, using the `-feature` syntax.
471    pub disabled: LinkerFeatures,
472}
473
474impl LinkerFeaturesCli {
475    /// Accumulates an enabled or disabled feature as specified on the CLI, if possible.
476    /// For example: `+lld`, and `-lld`.
477    pub(crate) fn handle_cli_feature(&mut self, feature: &str) -> Option<()> {
478        // Duplicate flags are reduced as we go, the last occurrence wins:
479        // `+feature,-feature,+feature` only enables the feature, and does not record it as both
480        // enabled and disabled on the CLI.
481        // We also only expose `+/-lld` at the moment, as it's currently the only implemented linker
482        // feature and toggling `LinkerFeatures::CC` would be a noop.
483        match feature {
484            "+lld" => {
485                self.enabled.insert(LinkerFeatures::LLD);
486                self.disabled.remove(LinkerFeatures::LLD);
487                Some(())
488            }
489            "-lld" => {
490                self.disabled.insert(LinkerFeatures::LLD);
491                self.enabled.remove(LinkerFeatures::LLD);
492                Some(())
493            }
494            _ => None,
495        }
496    }
497
498    /// When *not* using `-Z unstable-options` on the CLI, ensure only stable linker features are
499    /// used, for the given `TargetTuple`. Returns `Ok` if no unstable variants are used.
500    /// The caller should ensure that e.g. `nightly_options::is_unstable_enabled()`
501    /// returns false.
502    pub(crate) fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
503        // `-C linker-features=-lld` is only stable on x64 linux.
504        let has_minus_lld = self.disabled.is_lld_enabled();
505        if has_minus_lld && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
506            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!(
507                "`-C linker-features=-lld` is unstable on the `{target_tuple}` \
508                    target. The `-Z unstable-options` flag must also be passed to use it on this target",
509            ));
510        }
511
512        // Any `+lld` or non-lld feature used is unstable, and that's an error.
513        let unstable_enabled = self.enabled;
514        let unstable_disabled = self.disabled - LinkerFeatures::LLD;
515        if !unstable_enabled.union(unstable_disabled).is_empty() {
516            let unstable_features: Vec<_> = unstable_enabled
517                .iter()
518                .map(|f| ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("+{0}", f.as_str().unwrap()))
    })format!("+{}", f.as_str().unwrap()))
519                .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())))
520                .collect();
521            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!(
522                "`-C linker-features={}` is unstable, and also requires the \
523                `-Z unstable-options` flag to be used",
524                unstable_features.join(","),
525            ));
526        }
527
528        Ok(())
529    }
530}
531
532/// Used with `-Z assert-incr-state`.
533#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for IncrementalStateAssertion { }
#[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::marker::StructuralPartialEq for IncrementalStateAssertion { }
#[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)]
534pub enum IncrementalStateAssertion {
535    /// Found and loaded an existing session directory.
536    ///
537    /// Note that this says nothing about whether any particular query
538    /// will be found to be red or green.
539    Loaded,
540    /// Did not load an existing session directory.
541    NotLoaded,
542}
543
544/// The different settings that can be enabled via the `-Z location-detail` flag.
545#[derive(#[automatically_derived]
impl ::core::marker::Copy for LocationDetail { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for LocationDetail { }
#[automatically_derived]
impl ::core::clone::Clone for LocationDetail {
    #[inline]
    fn clone(&self) -> LocationDetail {
        let _: ::core::clone::AssertParamIsClone<bool>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for LocationDetail { }
#[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)]
546pub struct LocationDetail {
547    pub file: bool,
548    pub line: bool,
549    pub column: bool,
550}
551
552impl LocationDetail {
553    pub(crate) fn all() -> Self {
554        Self { file: true, line: true, column: true }
555    }
556}
557
558/// Values for the `-Z fmt-debug` flag.
559#[derive(#[automatically_derived]
impl ::core::marker::Copy for FmtDebug { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for FmtDebug { }
#[automatically_derived]
impl ::core::clone::Clone for FmtDebug {
    #[inline]
    fn clone(&self) -> FmtDebug { *self }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for FmtDebug { }
#[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)]
560pub enum FmtDebug {
561    /// Derive fully-featured implementation
562    Full,
563    /// Print only type name, without fields
564    Shallow,
565    /// `#[derive(Debug)]` and `{:?}` are no-ops
566    None,
567}
568
569impl FmtDebug {
570    pub(crate) fn all() -> [Symbol; 3] {
571        [sym::full, sym::none, sym::shallow]
572    }
573}
574
575#[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::marker::StructuralPartialEq for SwitchWithOptPath { }
#[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)]
576pub enum SwitchWithOptPath {
577    Enabled(Option<PathBuf>),
578    Disabled,
579}
580
581impl SwitchWithOptPath {
582    pub fn enabled(&self) -> bool {
583        match *self {
584            SwitchWithOptPath::Enabled(_) => true,
585            SwitchWithOptPath::Disabled => false,
586        }
587    }
588}
589
590#[derive(#[automatically_derived]
impl ::core::marker::Copy for SymbolManglingVersion { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for SymbolManglingVersion { }
#[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::marker::StructuralPartialEq for SymbolManglingVersion { }
#[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)]
591#[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);
            }
        }
    };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)]
592pub enum SymbolManglingVersion {
593    Legacy,
594    V0,
595    Hashed,
596}
597
598#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for DebugInfo { }
#[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::marker::StructuralPartialEq for DebugInfo { }
#[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)]
599pub enum DebugInfo {
600    None,
601    LineDirectivesOnly,
602    LineTablesOnly,
603    Limited,
604    Full,
605}
606
607#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for DebugInfoCompression { }
#[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::marker::StructuralPartialEq for DebugInfoCompression { }
#[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)]
608pub enum DebugInfoCompression {
609    None,
610    Zlib,
611    Zstd,
612}
613
614#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for MirStripDebugInfo { }
#[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::marker::StructuralPartialEq for MirStripDebugInfo { }
#[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)]
615pub enum MirStripDebugInfo {
616    None,
617    LocalsInTinyFunctions,
618    AllLocals,
619}
620
621/// Split debug-information is enabled by `-C split-debuginfo`, this enum is only used if split
622/// debug-information is enabled (in either `Packed` or `Unpacked` modes), and the platform
623/// uses DWARF for debug-information.
624///
625/// Some debug-information requires link-time relocation and some does not. LLVM can partition
626/// the debuginfo into sections depending on whether or not it requires link-time relocation. Split
627/// DWARF provides a mechanism which allows the linker to skip the sections which don't require
628/// link-time relocation - either by putting those sections in DWARF object files, or by keeping
629/// them in the object file in such a way that the linker will skip them.
630#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for SplitDwarfKind { }
#[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::marker::StructuralPartialEq for SplitDwarfKind { }
#[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);
            }
        }
    };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)]
631pub enum SplitDwarfKind {
632    /// Sections which do not require relocation are written into object file but ignored by the
633    /// linker.
634    Single,
635    /// Sections which do not require relocation are written into a DWARF object (`.dwo`) file
636    /// which is ignored by the linker.
637    Split,
638}
639
640impl FromStr for SplitDwarfKind {
641    type Err = ();
642
643    fn from_str(s: &str) -> Result<Self, ()> {
644        Ok(match s {
645            "single" => SplitDwarfKind::Single,
646            "split" => SplitDwarfKind::Split,
647            _ => return Err(()),
648        })
649    }
650}
651
652macro_rules! define_output_types {
653    (
654        $(
655            $(#[doc = $doc:expr])*
656            $Variant:ident => {
657                shorthand: $shorthand:expr,
658                extension: $extension:expr,
659                description: $description:expr,
660                default_filename: $default_filename:expr,
661                is_text: $is_text:expr,
662                compatible_with_cgus_and_single_output: $compatible:expr
663            }
664        ),* $(,)?
665    ) => {
666        #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, StableHash)]
667        #[derive(Encodable, Decodable)]
668        pub enum OutputType {
669            $(
670                $(#[doc = $doc])*
671                $Variant,
672            )*
673        }
674
675        impl StableOrd for OutputType {
676            const CAN_USE_UNSTABLE_SORT: bool = true;
677
678            // Trivial C-Style enums have a stable sort order across compilation sessions.
679            const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
680        }
681
682        impl OutputType {
683            pub fn iter_all() -> impl Iterator<Item = OutputType> {
684                static ALL_VARIANTS: &[OutputType] = &[
685                    $(
686                        OutputType::$Variant,
687                    )*
688                ];
689                ALL_VARIANTS.iter().copied()
690            }
691
692            fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool {
693                match *self {
694                    $(
695                        OutputType::$Variant => $compatible,
696                    )*
697                }
698            }
699
700            pub fn shorthand(&self) -> &'static str {
701                match *self {
702                    $(
703                        OutputType::$Variant => $shorthand,
704                    )*
705                }
706            }
707
708            fn from_shorthand(shorthand: &str) -> Option<Self> {
709                match shorthand {
710                    $(
711                        s if s == $shorthand => Some(OutputType::$Variant),
712                    )*
713                    _ => None,
714                }
715            }
716
717            fn shorthands_display() -> String {
718                let shorthands = vec![
719                    $(
720                        format!("`{}`", $shorthand),
721                    )*
722                ];
723                shorthands.join(", ")
724            }
725
726            pub fn extension(&self) -> &'static str {
727                match *self {
728                    $(
729                        OutputType::$Variant => $extension,
730                    )*
731                }
732            }
733
734            pub fn is_text_output(&self) -> bool {
735                match *self {
736                    $(
737                        OutputType::$Variant => $is_text,
738                    )*
739                }
740            }
741
742            pub fn description(&self) -> &'static str {
743                match *self {
744                    $(
745                        OutputType::$Variant => $description,
746                    )*
747                }
748            }
749
750            pub fn default_filename(&self) -> &'static str {
751                match *self {
752                    $(
753                        OutputType::$Variant => $default_filename,
754                    )*
755                }
756            }
757
758
759        }
760    }
761}
762
763pub enum OutputType {
    Assembly,

    #[doc =
    "This is the optimized bitcode, which could be either pre-LTO or non-LTO bitcode,"]
    #[doc = "depending on the specific request type."]
    Bitcode,
    DepInfo,
    Exe,
    LlvmAssembly,
    Metadata,
    Mir,
    Object,

    #[doc = "This is the summary or index data part of the ThinLTO bitcode."]
    ThinLinkBitcode,
}
const _: () =
    {
        impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
            for OutputType {
            fn encode(&self, __encoder: &mut __E) {
                let disc =
                    match *self {
                        OutputType::Assembly => { 0usize }
                        OutputType::Bitcode => { 1usize }
                        OutputType::DepInfo => { 2usize }
                        OutputType::Exe => { 3usize }
                        OutputType::LlvmAssembly => { 4usize }
                        OutputType::Metadata => { 5usize }
                        OutputType::Mir => { 6usize }
                        OutputType::Object => { 7usize }
                        OutputType::ThinLinkBitcode => { 8usize }
                    };
                ::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
            }
        }
    };
const _: () =
    {
        impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
            for OutputType {
            fn decode(__decoder: &mut __D) -> Self {
                match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
                    {
                    0usize => { OutputType::Assembly }
                    1usize => { OutputType::Bitcode }
                    2usize => { OutputType::DepInfo }
                    3usize => { OutputType::Exe }
                    4usize => { OutputType::LlvmAssembly }
                    5usize => { OutputType::Metadata }
                    6usize => { OutputType::Mir }
                    7usize => { OutputType::Object }
                    8usize => { OutputType::ThinLinkBitcode }
                    n => {
                        ::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `OutputType`, expected 0..9, actual {0}",
                                n));
                    }
                }
            }
        }
    };
#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for OutputType { }
#[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! {
764    Assembly => {
765        shorthand: "asm",
766        extension: "s",
767        description: "Generates a file with the crate's assembly code",
768        default_filename: "CRATE_NAME.s",
769        is_text: true,
770        compatible_with_cgus_and_single_output: false
771    },
772    #[doc = "This is the optimized bitcode, which could be either pre-LTO or non-LTO bitcode,"]
773    #[doc = "depending on the specific request type."]
774    Bitcode => {
775        shorthand: "llvm-bc",
776        extension: "bc",
777        description: "Generates a binary file containing the LLVM bitcode",
778        default_filename: "CRATE_NAME.bc",
779        is_text: false,
780        compatible_with_cgus_and_single_output: false
781    },
782    DepInfo => {
783        shorthand: "dep-info",
784        extension: "d",
785        description: "Generates a file with Makefile syntax that indicates all the source files that were loaded to generate the crate",
786        default_filename: "CRATE_NAME.d",
787        is_text: true,
788        compatible_with_cgus_and_single_output: true
789    },
790    Exe => {
791        shorthand: "link",
792        extension: "",
793        description: "Generates the crates specified by --crate-type. This is the default if --emit is not specified",
794        default_filename: "(platform and crate-type dependent)",
795        is_text: false,
796        compatible_with_cgus_and_single_output: true
797    },
798    LlvmAssembly => {
799        shorthand: "llvm-ir",
800        extension: "ll",
801        description: "Generates a file containing LLVM IR",
802        default_filename: "CRATE_NAME.ll",
803        is_text: true,
804        compatible_with_cgus_and_single_output: false
805    },
806    Metadata => {
807        shorthand: "metadata",
808        extension: "rmeta",
809        description: "Generates a file containing metadata about the crate",
810        default_filename: "libCRATE_NAME.rmeta",
811        is_text: false,
812        compatible_with_cgus_and_single_output: true
813    },
814    Mir => {
815        shorthand: "mir",
816        extension: "mir",
817        description: "Generates a file containing rustc's mid-level intermediate representation",
818        default_filename: "CRATE_NAME.mir",
819        is_text: true,
820        compatible_with_cgus_and_single_output: false
821    },
822    Object => {
823        shorthand: "obj",
824        extension: "o",
825        description: "Generates a native object file",
826        default_filename: "CRATE_NAME.o",
827        is_text: false,
828        compatible_with_cgus_and_single_output: false
829    },
830    #[doc = "This is the summary or index data part of the ThinLTO bitcode."]
831    ThinLinkBitcode => {
832        shorthand: "thin-link-bitcode",
833        extension: "indexing.o",
834        description: "Generates the ThinLTO summary as bitcode",
835        default_filename: "CRATE_NAME.indexing.o",
836        is_text: false,
837        compatible_with_cgus_and_single_output: false
838    },
839}
840
841/// The type of diagnostics output to generate.
842#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for ErrorOutputType { }
#[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::marker::StructuralPartialEq for ErrorOutputType { }
#[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)]
843pub enum ErrorOutputType {
844    /// Output meant for the consumption of humans.
845    #[default]
846    HumanReadable {
847        kind: HumanReadableErrorType = HumanReadableErrorType { short: false, unicode: false },
848        color_config: ColorConfig = ColorConfig::Auto,
849    },
850    /// Output that's consumed by other tools such as `rustfix` or the `RLS`.
851    Json {
852        /// Render the JSON in a human readable way (with indents and newlines).
853        pretty: bool,
854        /// The JSON output includes a `rendered` field that includes the rendered
855        /// human output.
856        json_rendered: HumanReadableErrorType,
857        color_config: ColorConfig,
858    },
859}
860
861#[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)]
862pub enum ResolveDocLinks {
863    /// Do not resolve doc links.
864    None,
865    /// Resolve doc links on exported items only for crate types that have metadata.
866    ExportedMetadata,
867    /// Resolve doc links on exported items.
868    Exported,
869    /// Resolve doc links on all items.
870    All,
871}
872
873/// Use tree-based collections to cheaply get a deterministic `Hash` implementation.
874/// *Do not* switch `BTreeMap` out for an unsorted container type! That would break
875/// dependency tracking for command-line arguments. Also only hash keys, since tracking
876/// should only depend on the output types, not the paths they're written to.
877#[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) {
                let OutputTypes(ref __binding_0) = *self;
                ::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)]
878pub struct OutputTypes(BTreeMap<OutputType, Option<OutFileName>>);
879
880impl OutputTypes {
881    pub fn new(entries: &[(OutputType, Option<OutFileName>)]) -> OutputTypes {
882        OutputTypes(BTreeMap::from_iter(entries.iter().map(|&(k, ref v)| (k, v.clone()))))
883    }
884
885    pub(crate) fn get(&self, key: &OutputType) -> Option<&Option<OutFileName>> {
886        self.0.get(key)
887    }
888
889    pub fn contains_key(&self, key: &OutputType) -> bool {
890        self.0.contains_key(key)
891    }
892
893    /// Returns `true` if user specified a name and not just produced type
894    pub fn contains_explicit_name(&self, key: &OutputType) -> bool {
895        #[allow(non_exhaustive_omitted_patterns)] match self.0.get(key) {
    Some(Some(..)) => true,
    _ => false,
}matches!(self.0.get(key), Some(Some(..)))
896    }
897
898    pub fn iter(&self) -> BTreeMapIter<'_, OutputType, Option<OutFileName>> {
899        self.0.iter()
900    }
901
902    pub fn keys(&self) -> BTreeMapKeysIter<'_, OutputType, Option<OutFileName>> {
903        self.0.keys()
904    }
905
906    pub fn values(&self) -> BTreeMapValuesIter<'_, OutputType, Option<OutFileName>> {
907        self.0.values()
908    }
909
910    pub fn len(&self) -> usize {
911        self.0.len()
912    }
913
914    /// Returns `true` if any of the output types require codegen or linking.
915    pub fn should_codegen(&self) -> bool {
916        self.0.keys().any(|k| match *k {
917            OutputType::Bitcode
918            | OutputType::ThinLinkBitcode
919            | OutputType::Assembly
920            | OutputType::LlvmAssembly
921            | OutputType::Mir
922            | OutputType::Object
923            | OutputType::Exe => true,
924            OutputType::Metadata | OutputType::DepInfo => false,
925        })
926    }
927
928    /// Returns `true` if any of the output types require linking.
929    pub fn should_link(&self) -> bool {
930        self.0.keys().any(|k| match *k {
931            OutputType::Bitcode
932            | OutputType::ThinLinkBitcode
933            | OutputType::Assembly
934            | OutputType::LlvmAssembly
935            | OutputType::Mir
936            | OutputType::Metadata
937            | OutputType::Object
938            | OutputType::DepInfo => false,
939            OutputType::Exe => true,
940        })
941    }
942}
943
944/// Use tree-based collections to cheaply get a deterministic `Hash` implementation.
945/// *Do not* switch `BTreeMap` or `BTreeSet` out for an unsorted container type! That
946/// would break dependency tracking for command-line arguments.
947#[derive(#[automatically_derived]
impl ::core::clone::Clone for Externs {
    #[inline]
    fn clone(&self) -> Externs {
        Externs(::core::clone::Clone::clone(&self.0))
    }
}Clone)]
948pub struct Externs(BTreeMap<String, ExternEntry>);
949
950#[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)]
951pub struct ExternEntry {
952    pub location: ExternLocation,
953    /// Indicates this is a "private" dependency for the
954    /// `exported_private_dependencies` lint.
955    ///
956    /// This can be set with the `priv` option like
957    /// `--extern priv:name=foo.rlib`.
958    pub is_private_dep: bool,
959    /// Add the extern entry to the extern prelude.
960    ///
961    /// This can be disabled with the `noprelude` option like
962    /// `--extern noprelude:name`.
963    pub add_prelude: bool,
964    /// The extern entry shouldn't be considered for unused dependency warnings.
965    ///
966    /// `--extern nounused:std=/path/to/lib/libstd.rlib`. This is used to
967    /// suppress `unused-crate-dependencies` warnings.
968    pub nounused_dep: bool,
969    /// If the extern entry is not referenced in the crate, force it to be resolved anyway.
970    ///
971    /// Allows a dependency satisfying, for instance, a missing panic handler to be injected
972    /// without modifying source:
973    /// `--extern force:extras=/path/to/lib/libstd.rlib`
974    pub force: bool,
975}
976
977#[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)]
978pub enum ExternLocation {
979    /// Indicates to look for the library in the search paths.
980    ///
981    /// Added via `--extern name`.
982    FoundInLibrarySearchDirectories,
983    /// The locations where this extern entry must be found.
984    ///
985    /// The `CrateLoader` is responsible for loading these and figuring out
986    /// which one to use.
987    ///
988    /// Added via `--extern prelude_name=some_file.rlib`
989    ExactPaths(BTreeSet<CanonicalizedPath>),
990}
991
992impl Externs {
993    /// Used for testing.
994    pub fn new(data: BTreeMap<String, ExternEntry>) -> Externs {
995        Externs(data)
996    }
997
998    pub fn get(&self, key: &str) -> Option<&ExternEntry> {
999        self.0.get(key)
1000    }
1001
1002    pub fn iter(&self) -> BTreeMapIter<'_, String, ExternEntry> {
1003        self.0.iter()
1004    }
1005}
1006
1007impl ExternEntry {
1008    fn new(location: ExternLocation) -> ExternEntry {
1009        ExternEntry {
1010            location,
1011            is_private_dep: false,
1012            add_prelude: false,
1013            nounused_dep: false,
1014            force: false,
1015        }
1016    }
1017
1018    pub fn files(&self) -> Option<impl Iterator<Item = &CanonicalizedPath>> {
1019        match &self.location {
1020            ExternLocation::ExactPaths(set) => Some(set.iter()),
1021            _ => None,
1022        }
1023    }
1024}
1025
1026#[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]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for NextSolverConfig { }
#[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::marker::StructuralPartialEq for NextSolverConfig { }
#[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)]
1027pub struct NextSolverConfig {
1028    /// Whether the new trait solver should be enabled in coherence.
1029    pub coherence: bool = true,
1030    /// Whether the new trait solver should be enabled everywhere.
1031    /// This is only `true` if `coherence` is also enabled.
1032    pub globally: bool = false,
1033}
1034
1035// FIXME(#160895): Using -Znext-solver as default on nightly
1036// See https://github.com/rust-lang/compiler-team/issues/1014
1037impl Default for NextSolverConfig {
1038    fn default() -> Self {
1039        if ::core::option::Option::Some("1")option_env!("CFG_DEFAULT_NEXT_SOLVER_GLOBALLY").is_some() {
1040            Self { coherence: true, globally: true }
1041        } else {
1042            Self { coherence: true, globally: false }
1043        }
1044    }
1045}
1046
1047#[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)]
1048pub enum Input {
1049    /// Load source code from a file.
1050    File(PathBuf),
1051    /// Load source code from a string.
1052    Str {
1053        /// A string that is shown in place of a filename.
1054        name: FileName,
1055        /// An anonymous string containing the source code.
1056        input: String,
1057    },
1058}
1059
1060impl Input {
1061    pub fn filestem(&self) -> &str {
1062        if let Input::File(ifile) = self {
1063            // If for some reason getting the file stem as a UTF-8 string fails,
1064            // then fallback to a fixed name.
1065            if let Some(name) = ifile.file_stem().and_then(OsStr::to_str) {
1066                return name;
1067            }
1068        }
1069        "rust_out"
1070    }
1071
1072    pub fn file_name(&self, session: &Session) -> FileName {
1073        match *self {
1074            Input::File(ref ifile) => FileName::Real(
1075                session
1076                    .psess
1077                    .source_map()
1078                    .path_mapping()
1079                    .to_real_filename(session.psess.source_map().working_dir(), ifile.as_path()),
1080            ),
1081            Input::Str { ref name, .. } => name.clone(),
1082        }
1083    }
1084
1085    pub fn opt_path(&self) -> Option<&Path> {
1086        match self {
1087            Input::File(file) => Some(file),
1088            Input::Str { name, .. } => match name {
1089                FileName::Real(real) => real.local_path(),
1090                FileName::CfgSpec(_) => None,
1091                FileName::Anon(_) => None,
1092                FileName::MacroExpansion(_) => None,
1093                FileName::ProcMacroSourceCode(_) => None,
1094                FileName::CliCrateAttr(_) => None,
1095                FileName::Custom(_) => None,
1096                FileName::DocTest(path, _) => Some(path),
1097                FileName::InlineAsm(_) => None,
1098            },
1099        }
1100    }
1101}
1102
1103#[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::marker::StructuralPartialEq for OutFileName { }
#[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)]
1104pub enum OutFileName {
1105    Real(PathBuf),
1106    Stdout,
1107}
1108
1109impl OutFileName {
1110    pub fn parent(&self) -> Option<&Path> {
1111        match *self {
1112            OutFileName::Real(ref path) => path.parent(),
1113            OutFileName::Stdout => None,
1114        }
1115    }
1116
1117    pub fn filestem(&self) -> Option<&OsStr> {
1118        match *self {
1119            OutFileName::Real(ref path) => path.file_stem(),
1120            OutFileName::Stdout => Some(OsStr::new("stdout")),
1121        }
1122    }
1123
1124    pub fn is_stdout(&self) -> bool {
1125        match *self {
1126            OutFileName::Real(_) => false,
1127            OutFileName::Stdout => true,
1128        }
1129    }
1130
1131    pub fn is_tty(&self) -> bool {
1132        use std::io::IsTerminal;
1133        match *self {
1134            OutFileName::Real(_) => false,
1135            OutFileName::Stdout => std::io::stdout().is_terminal(),
1136        }
1137    }
1138
1139    pub fn as_path(&self) -> &Path {
1140        match *self {
1141            OutFileName::Real(ref path) => path.as_ref(),
1142            OutFileName::Stdout => Path::new("stdout"),
1143        }
1144    }
1145
1146    /// For a given output filename, return the actual name of the file that
1147    /// can be used to write codegen data of type `flavor`. For real-path
1148    /// output filenames, this would be trivial as we can just use the path.
1149    /// Otherwise for stdout, return a temporary path so that the codegen data
1150    /// may be later copied to stdout.
1151    pub fn file_for_writing(
1152        &self,
1153        outputs: &OutputFilenames,
1154        flavor: OutputType,
1155        codegen_unit_name: &str,
1156    ) -> PathBuf {
1157        match *self {
1158            OutFileName::Real(ref path) => path.clone(),
1159            OutFileName::Stdout => outputs.temp_path_for_cgu(flavor, codegen_unit_name),
1160        }
1161    }
1162
1163    pub fn overwrite(&self, content: &str, sess: &Session) {
1164        match self {
1165            OutFileName::Stdout => { ::std::io::_print(format_args!("{0}", content)); }print!("{content}"),
1166            OutFileName::Real(path) => {
1167                if let Err(e) = fs::write(path, content) {
1168                    sess.dcx().emit_fatal(FileWriteFail { path, err: e.to_string() });
1169                }
1170            }
1171        }
1172    }
1173}
1174
1175#[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) {
                let 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 } = *self;
                ::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)]
1176pub struct OutputFilenames {
1177    pub(crate) out_directory: PathBuf,
1178    /// Crate name. Never contains '-'.
1179    crate_stem: String,
1180    /// Typically based on `.rs` input file name. Any '-' is preserved.
1181    filestem: String,
1182    pub single_output_file: Option<OutFileName>,
1183    temps_directory: Option<PathBuf>,
1184
1185    /// A random string generated per invocation of rustc.
1186    ///
1187    /// This is prepended to all temporary files so that they do not collide
1188    /// during concurrent invocations of rustc, or past invocations that were
1189    /// preserved with a flag like `-C save-temps`, since these files may be
1190    /// hard linked.
1191    // This does not affect incr comp outputs, only where temp files are stored.
1192    #[stable_hash(ignore)]
1193    invocation_temp: Option<String>,
1194
1195    explicit_dwo_out_directory: Option<PathBuf>,
1196    pub outputs: OutputTypes,
1197}
1198
1199pub const RLINK_EXT: &str = "rlink";
1200pub const RUST_CGU_EXT: &str = "rcgu";
1201pub const DWARF_OBJECT_EXT: &str = "dwo";
1202pub const MAX_FILENAME_LENGTH: usize = 143; // ecryptfs limits filenames to 143 bytes see #49914
1203
1204/// Ensure the filename is not too long, as some filesystems have a limit.
1205/// If the filename is too long, hash part of it and append the hash to the filename.
1206/// This is a workaround for long crate names generating overly long filenames.
1207fn maybe_strip_file_name(mut path: PathBuf) -> PathBuf {
1208    if path.file_name().map_or(0, |name| name.len()) > MAX_FILENAME_LENGTH {
1209        let filename = path.file_name().unwrap().to_string_lossy();
1210        let hash_len = 64 / 4; // Hash64 is 64 bits encoded in hex
1211        let hyphen_len = 1; // the '-' we insert between hash and suffix
1212
1213        // number of bytes of suffix we can keep so that "hash-<suffix>" fits
1214        let allowed_suffix = MAX_FILENAME_LENGTH.saturating_sub(hash_len + hyphen_len);
1215
1216        // number of bytes to remove from the start
1217        let stripped_bytes = filename.len().saturating_sub(allowed_suffix);
1218
1219        // ensure we don't cut in a middle of a char
1220        let split_at = filename.ceil_char_boundary(stripped_bytes);
1221
1222        let mut hasher = StableHasher::new();
1223        filename[..split_at].hash(&mut hasher);
1224        let hash = hasher.finish::<Hash64>();
1225
1226        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..]));
1227    }
1228    path
1229}
1230impl OutputFilenames {
1231    pub fn new(
1232        out_directory: PathBuf,
1233        out_crate_name: String,
1234        out_filestem: String,
1235        single_output_file: Option<OutFileName>,
1236        temps_directory: Option<PathBuf>,
1237        invocation_temp: Option<String>,
1238        explicit_dwo_out_directory: Option<PathBuf>,
1239        extra: String,
1240        outputs: OutputTypes,
1241    ) -> Self {
1242        OutputFilenames {
1243            out_directory,
1244            single_output_file,
1245            temps_directory,
1246            invocation_temp,
1247            explicit_dwo_out_directory,
1248            outputs,
1249            crate_stem: ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1}", out_crate_name, extra))
    })format!("{out_crate_name}{extra}"),
1250            filestem: ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0}{1}", out_filestem, extra))
    })format!("{out_filestem}{extra}"),
1251        }
1252    }
1253
1254    pub fn path(&self, flavor: OutputType) -> OutFileName {
1255        self.outputs
1256            .get(&flavor)
1257            .and_then(|p| p.to_owned())
1258            .or_else(|| self.single_output_file.clone())
1259            .unwrap_or_else(|| OutFileName::Real(self.output_path(flavor)))
1260    }
1261
1262    pub fn interface_path(&self) -> PathBuf {
1263        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/0ed41eb4142dda2df61eb1145a312c1a9d62eb56/compiler/rustc_session/src/config.rs:1263",
                        "rustc_session::config", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/0ed41eb4142dda2df61eb1145a312c1a9d62eb56/compiler/rustc_session/src/config.rs"),
                        ::tracing_core::__macro_support::Option::Some(1263u32),
                        ::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);
1264        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))
1265    }
1266
1267    /// Gets the output path where a compilation artifact of the given type
1268    /// should be placed on disk.
1269    fn output_path(&self, flavor: OutputType) -> PathBuf {
1270        let extension = flavor.extension();
1271        match flavor {
1272            OutputType::Metadata => {
1273                {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/0ed41eb4142dda2df61eb1145a312c1a9d62eb56/compiler/rustc_session/src/config.rs:1273",
                        "rustc_session::config", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/0ed41eb4142dda2df61eb1145a312c1a9d62eb56/compiler/rustc_session/src/config.rs"),
                        ::tracing_core::__macro_support::Option::Some(1273u32),
                        ::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);
1274                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))
1275            }
1276            _ => self.with_directory_and_extension(&self.out_directory, extension),
1277        }
1278    }
1279
1280    /// Gets the path where a compilation artifact of the given type for the
1281    /// given codegen unit should be placed on disk. If codegen_unit_name is
1282    /// None, a path distinct from those of any codegen unit will be generated.
1283    pub fn temp_path_for_cgu(&self, flavor: OutputType, codegen_unit_name: &str) -> PathBuf {
1284        let extension = flavor.extension();
1285        self.temp_path_ext_for_cgu(extension, codegen_unit_name)
1286    }
1287
1288    /// Like `temp_path`, but specifically for dwarf objects.
1289    pub fn temp_path_dwo_for_cgu(&self, codegen_unit_name: &str) -> PathBuf {
1290        let p = self.temp_path_ext_for_cgu(DWARF_OBJECT_EXT, codegen_unit_name);
1291        if let Some(dwo_out) = &self.explicit_dwo_out_directory {
1292            let mut o = dwo_out.clone();
1293            o.push(p.file_name().unwrap());
1294            o
1295        } else {
1296            p
1297        }
1298    }
1299
1300    /// Like `temp_path`, but also supports things where there is no corresponding
1301    /// OutputType, like noopt-bitcode or lto-bitcode.
1302    pub fn temp_path_ext_for_cgu(&self, ext: &str, codegen_unit_name: &str) -> PathBuf {
1303        let mut extension = codegen_unit_name.to_string();
1304
1305        // Append `.{invocation_temp}` to ensure temporary files are unique.
1306        if let Some(rng) = &self.invocation_temp {
1307            extension.push('.');
1308            extension.push_str(rng);
1309        }
1310
1311        // FIXME: This is sketchy that we're not appending `.rcgu` when the ext is empty.
1312        // Append `.rcgu.{ext}`.
1313        if !ext.is_empty() {
1314            extension.push('.');
1315            extension.push_str(RUST_CGU_EXT);
1316            extension.push('.');
1317            extension.push_str(ext);
1318        }
1319
1320        let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
1321        maybe_strip_file_name(self.with_directory_and_extension(temps_directory, &extension))
1322    }
1323
1324    pub fn temp_path_for_diagnostic(&self, ext: &str) -> PathBuf {
1325        let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
1326        self.with_directory_and_extension(temps_directory, &ext)
1327    }
1328
1329    pub fn with_extension(&self, extension: &str) -> PathBuf {
1330        self.with_directory_and_extension(&self.out_directory, extension)
1331    }
1332
1333    pub fn with_directory_and_extension(&self, directory: &Path, extension: &str) -> PathBuf {
1334        {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/0ed41eb4142dda2df61eb1145a312c1a9d62eb56/compiler/rustc_session/src/config.rs:1334",
                        "rustc_session::config", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/0ed41eb4142dda2df61eb1145a312c1a9d62eb56/compiler/rustc_session/src/config.rs"),
                        ::tracing_core::__macro_support::Option::Some(1334u32),
                        ::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);
1335        let mut path = directory.join(&self.filestem);
1336        path.set_extension(extension);
1337        path
1338    }
1339
1340    /// Returns the path for the Split DWARF file - this can differ depending on which Split DWARF
1341    /// mode is being used, which is the logic that this function is intended to encapsulate.
1342    pub fn split_dwarf_path(
1343        &self,
1344        split_debuginfo_kind: SplitDebuginfo,
1345        split_dwarf_kind: SplitDwarfKind,
1346        cgu_name: &str,
1347    ) -> Option<PathBuf> {
1348        let obj_out = self.temp_path_for_cgu(OutputType::Object, cgu_name);
1349        let dwo_out = self.temp_path_dwo_for_cgu(cgu_name);
1350        match (split_debuginfo_kind, split_dwarf_kind) {
1351            (SplitDebuginfo::Off, SplitDwarfKind::Single | SplitDwarfKind::Split) => None,
1352            // Single mode doesn't change how DWARF is emitted, but does add Split DWARF attributes
1353            // (pointing at the path which is being determined here). Use the path to the current
1354            // object file.
1355            (SplitDebuginfo::Packed | SplitDebuginfo::Unpacked, SplitDwarfKind::Single) => {
1356                Some(obj_out)
1357            }
1358            // Split mode emits the DWARF into a different file, use that path.
1359            (SplitDebuginfo::Packed | SplitDebuginfo::Unpacked, SplitDwarfKind::Split) => {
1360                Some(dwo_out)
1361            }
1362        }
1363    }
1364}
1365
1366// pub for rustdoc
1367pub fn parse_remap_path_scope(
1368    early_dcx: &EarlyDiagCtxt,
1369    matches: &getopts::Matches,
1370    unstable_opts: &UnstableOptions,
1371) -> RemapPathScopeComponents {
1372    if let Some(v) = matches.opt_str("remap-path-scope") {
1373        let mut slot = RemapPathScopeComponents::empty();
1374        for s in v.split(',') {
1375            slot |= match s {
1376                "macro" => RemapPathScopeComponents::MACRO,
1377                "diagnostics" => RemapPathScopeComponents::DIAGNOSTICS,
1378                "documentation" => {
1379                    if !unstable_opts.unstable_options {
1380                        early_dcx.early_fatal("remapping `documentation` path scope requested but `-Zunstable-options` not specified");
1381                    }
1382
1383                    RemapPathScopeComponents::DOCUMENTATION
1384                },
1385                "debuginfo" => RemapPathScopeComponents::DEBUGINFO,
1386                "coverage" => RemapPathScopeComponents::COVERAGE,
1387                "object" => RemapPathScopeComponents::OBJECT,
1388                "all" => RemapPathScopeComponents::all(),
1389                _ => early_dcx.early_fatal("argument for `--remap-path-scope` must be a comma separated list of scopes: `macro`, `diagnostics`, `documentation`, `debuginfo`, `coverage`, `object`, `all`"),
1390            }
1391        }
1392        slot
1393    } else {
1394        RemapPathScopeComponents::all()
1395    }
1396}
1397
1398#[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)]
1399pub struct Sysroot {
1400    pub explicit: Option<PathBuf>,
1401    pub default: PathBuf,
1402}
1403
1404impl Sysroot {
1405    pub fn new(explicit: Option<PathBuf>) -> Sysroot {
1406        Sysroot { explicit, default: filesearch::default_sysroot() }
1407    }
1408
1409    /// Return explicit sysroot if it was passed with `--sysroot`, or default sysroot otherwise.
1410    pub fn path(&self) -> &Path {
1411        self.explicit.as_deref().unwrap_or(&self.default)
1412    }
1413
1414    /// Returns both explicit sysroot if it was passed with `--sysroot` and the default sysroot.
1415    pub fn all_paths(&self) -> impl Iterator<Item = &Path> {
1416        self.explicit.as_deref().into_iter().chain(iter::once(&*self.default))
1417    }
1418}
1419
1420/// Get the host triple out of the build environment. This ensures that our
1421/// idea of the host triple is the same as for the set of libraries we've
1422/// actually built. We can't just take LLVM's host triple because they
1423/// normalize all ix86 architectures to i386.
1424pub fn host_tuple() -> &'static str {
1425    // Instead of grabbing the host triple (for the current host), we grab (at
1426    // compile time) the target triple that this rustc is built with and
1427    // calling that (at runtime) the host triple.
1428    (::core::option::Option::Some("x86_64-unknown-linux-gnu")option_env!("CFG_COMPILER_HOST_TRIPLE")).expect("CFG_COMPILER_HOST_TRIPLE")
1429}
1430
1431fn file_path_mapping(
1432    remap_path_prefix: Vec<(PathBuf, PathBuf)>,
1433    remap_cwd_prefix: Option<&Path>,
1434    remap_path_scope: RemapPathScopeComponents,
1435) -> FilePathMapping {
1436    // Apply `-Zremap-cwd-prefix` here rather than in `parse_remap_path_prefix`, so the
1437    // absolute cwd is never stored in the tracked `remap_path_prefix` option (#132132).
1438    let cwd_remap = if let Some(to) = remap_cwd_prefix
1439        && let Ok(cwd) = std::env::current_dir()
1440    {
1441        Some((cwd, to.to_path_buf()))
1442    } else {
1443        None
1444    };
1445    // The cwd remapping is appended last: `map_prefix` tries entries in reverse order, so this
1446    // keeps `-Zremap-cwd-prefix` taking precedence over `--remap-path-prefix`, as documented.
1447    FilePathMapping::new(remap_path_prefix.into_iter().chain(cwd_remap).collect(), remap_path_scope)
1448}
1449
1450impl Default for Options {
1451    fn default() -> Options {
1452        let unstable_opts = UnstableOptions::default();
1453
1454        // FIXME(Urgau): This is a hack that ideally shouldn't exist, but rustdoc
1455        // currently uses this `Default` implementation, so we have no choice but
1456        // to create a default working directory.
1457        let working_dir = {
1458            let working_dir = std::env::current_dir().unwrap();
1459            let file_mapping =
1460                file_path_mapping(Vec::new(), None, RemapPathScopeComponents::empty());
1461            file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
1462        };
1463
1464        Options {
1465            crate_types: Vec::new(),
1466            optimize: OptLevel::No,
1467            debuginfo: DebugInfo::None,
1468            lint_opts: Vec::new(),
1469            lint_cap: None,
1470            describe_lints: false,
1471            output_types: OutputTypes(BTreeMap::new()),
1472            search_paths: ::alloc::vec::Vec::new()vec![],
1473            sysroot: Sysroot::new(None),
1474            target_triple: TargetTuple::from_tuple(host_tuple()),
1475            test: false,
1476            incremental: None,
1477            unstable_opts,
1478            prints: Vec::new(),
1479            cg: Default::default(),
1480            error_format: ErrorOutputType::default(),
1481            diagnostic_width: None,
1482            externs: Externs(BTreeMap::new()),
1483            crate_name: None,
1484            libs: Vec::new(),
1485            unstable_features: UnstableFeatures::Disallow,
1486            debug_assertions: true,
1487            actually_rustdoc: false,
1488            resolve_doc_links: ResolveDocLinks::None,
1489            trimmed_def_paths: false,
1490            cli_forced_codegen_units: None,
1491            cli_forced_local_thinlto_off: false,
1492            remap_path_prefix: Vec::new(),
1493            remap_path_scope: RemapPathScopeComponents::all(),
1494            real_rust_source_base_dir: None,
1495            real_rustc_dev_source_base_dir: None,
1496            edition: DEFAULT_EDITION,
1497            json_artifact_notifications: false,
1498            json_timings: false,
1499            json_unused_externs: JsonUnusedExterns::No,
1500            json_future_incompat: false,
1501            pretty: None,
1502            working_dir,
1503            color: ColorConfig::Auto,
1504            verbose: false,
1505            target_modifiers: BTreeMap::default(),
1506            mitigation_coverage_map: Default::default(),
1507            jobs: Jobs { frontend: None, backend: None, linker: LinkerJobs::Default },
1508        }
1509    }
1510}
1511
1512impl Options {
1513    /// Returns `true` if there is a reason to build the dep graph.
1514    pub fn build_dep_graph(&self) -> bool {
1515        self.incremental.is_some()
1516            || self.unstable_opts.dump_dep_graph
1517            || self.unstable_opts.query_dep_graph
1518    }
1519
1520    pub fn file_path_mapping(&self) -> FilePathMapping {
1521        file_path_mapping(
1522            self.remap_path_prefix.clone(),
1523            self.unstable_opts.remap_cwd_prefix.as_deref(),
1524            self.remap_path_scope,
1525        )
1526    }
1527
1528    /// Returns `true` if there will be an output file generated.
1529    pub fn will_create_output_file(&self) -> bool {
1530        !self.unstable_opts.parse_crate_root_only && // The file is just being parsed
1531            self.unstable_opts.ls.is_empty() // The file is just being queried
1532    }
1533
1534    #[inline]
1535    pub fn share_generics(&self) -> bool {
1536        match self.unstable_opts.share_generics {
1537            Some(setting) => setting,
1538            None => match self.optimize {
1539                OptLevel::No | OptLevel::Less | OptLevel::Size | OptLevel::SizeMin => true,
1540                OptLevel::More | OptLevel::Aggressive => false,
1541            },
1542        }
1543    }
1544
1545    pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
1546        self.cg.symbol_mangling_version.unwrap_or(SymbolManglingVersion::V0)
1547    }
1548
1549    #[inline]
1550    pub fn autodiff_enabled(&self) -> bool {
1551        self.unstable_opts.autodiff.contains(&AutoDiff::Enable)
1552    }
1553}
1554
1555impl UnstableOptions {
1556    pub fn dcx_flags(&self, can_emit_warnings: bool) -> DiagCtxtFlags {
1557        DiagCtxtFlags {
1558            can_emit_warnings,
1559            treat_err_as_bug: self.treat_err_as_bug,
1560            eagerly_emit_delayed_bugs: self.eagerly_emit_delayed_bugs,
1561            macro_backtrace: self.macro_backtrace,
1562            deduplicate_diagnostics: self.deduplicate_diagnostics,
1563            track_diagnostics: self.track_diagnostics,
1564        }
1565    }
1566
1567    pub fn src_hash_algorithm(&self, target: &Target) -> SourceFileHashAlgorithm {
1568        self.src_hash_algorithm.unwrap_or_else(|| {
1569            if target.is_like_msvc {
1570                SourceFileHashAlgorithm::Sha256
1571            } else {
1572                SourceFileHashAlgorithm::Md5
1573            }
1574        })
1575    }
1576
1577    pub fn checksum_hash_algorithm(&self) -> Option<SourceFileHashAlgorithm> {
1578        self.checksum_hash_algorithm
1579    }
1580}
1581
1582// The type of entry function, so users can have their own entry functions
1583#[derive(#[automatically_derived]
impl ::core::marker::Copy for EntryFnType { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for EntryFnType { }
#[automatically_derived]
impl ::core::clone::Clone for EntryFnType {
    #[inline]
    fn clone(&self) -> EntryFnType {
        let _: ::core::clone::AssertParamIsClone<u8>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for EntryFnType { }
#[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)]
1584pub enum EntryFnType {
1585    Main {
1586        /// Specifies what to do with `SIGPIPE` before calling `fn main()`.
1587        ///
1588        /// What values that are valid and what they mean must be in sync
1589        /// across rustc and libstd, but we don't want it public in libstd,
1590        /// so we take a bit of an unusual approach with simple constants
1591        /// and an `include!()`.
1592        sigpipe: u8,
1593    },
1594}
1595
1596#[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::marker::StructuralPartialEq for Passes { }
#[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)]
1597pub enum Passes {
1598    Some(Vec<String>),
1599    All,
1600}
1601
1602impl Passes {
1603    fn is_empty(&self) -> bool {
1604        match *self {
1605            Passes::Some(ref v) => v.is_empty(),
1606            Passes::All => false,
1607        }
1608    }
1609
1610    pub(crate) fn extend(&mut self, passes: impl IntoIterator<Item = String>) {
1611        match *self {
1612            Passes::Some(ref mut v) => v.extend(passes),
1613            Passes::All => {}
1614        }
1615    }
1616}
1617
1618#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for PAuthKey { }
#[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::marker::StructuralPartialEq for PAuthKey { }
#[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)]
1619pub enum PAuthKey {
1620    A,
1621    B,
1622}
1623
1624#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for PacRet { }
#[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::marker::StructuralPartialEq for PacRet { }
#[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)]
1625pub struct PacRet {
1626    pub leaf: bool,
1627    pub pc: bool,
1628    pub key: PAuthKey,
1629}
1630
1631#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for BranchProtection { }
#[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::marker::StructuralPartialEq for BranchProtection { }
#[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)]
1632pub struct BranchProtection {
1633    pub bti: bool,
1634    pub pac_ret: Option<PacRet>,
1635    pub gcs: bool,
1636}
1637
1638#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for PointerAuthOption { }
#[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 {
        ::core::fmt::Formatter::write_str(f,
            match self {
                PointerAuthOption::Aarch64JumpTableHardening =>
                    "Aarch64JumpTableHardening",
                PointerAuthOption::AuthTraps => "AuthTraps",
                PointerAuthOption::Calls => "Calls",
                PointerAuthOption::ElfGot => "ElfGot",
                PointerAuthOption::FunctionPointerTypeDiscrimination =>
                    "FunctionPointerTypeDiscrimination",
                PointerAuthOption::IndirectGotos => "IndirectGotos",
                PointerAuthOption::InitFini => "InitFini",
                PointerAuthOption::InitFiniAddressDiscrimination =>
                    "InitFiniAddressDiscrimination",
                PointerAuthOption::Intrinsics => "Intrinsics",
                PointerAuthOption::ReturnAddresses => "ReturnAddresses",
                PointerAuthOption::TypeInfoVTPtrDisc => "TypeInfoVTPtrDisc",
                PointerAuthOption::VTPtrAddrDisc => "VTPtrAddrDisc",
                PointerAuthOption::VTPtrTypeDisc => "VTPtrTypeDisc",
            })
    }
}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::marker::StructuralPartialEq for PointerAuthOption { }
#[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)]
1639pub enum PointerAuthOption {
1640    // See <compiler/rustc_session/src/options.rs> and Clang's command line reference:
1641    // <https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-fptrauth-auth-traps>
1642    // for the origin and meaning of the enum values.
1643    // tidy-alphabetical-start
1644    Aarch64JumpTableHardening,
1645    AuthTraps,
1646    Calls,
1647    ElfGot,
1648    FunctionPointerTypeDiscrimination,
1649    IndirectGotos,
1650    InitFini,
1651    InitFiniAddressDiscrimination,
1652    Intrinsics,
1653    ReturnAddresses,
1654    TypeInfoVTPtrDisc,
1655    VTPtrAddrDisc,
1656    VTPtrTypeDisc,
1657    // tidy-alphabetical-end
1658}
1659impl PointerAuthOption {
1660    pub fn parse(s: &str) -> Option<Self> {
1661        match s {
1662            "aarch64-jump-table-hardening" => Some(Self::Aarch64JumpTableHardening),
1663            "auth-traps" => Some(Self::AuthTraps),
1664            "calls" => Some(Self::Calls),
1665            "elf-got" => Some(Self::ElfGot),
1666            "function-pointer-type-discrimination" => Some(Self::FunctionPointerTypeDiscrimination),
1667            "indirect-gotos" => Some(Self::IndirectGotos),
1668            "init-fini" => Some(Self::InitFini),
1669            "init-fini-address-discrimination" => Some(Self::InitFiniAddressDiscrimination),
1670            "intrinsics" => Some(Self::Intrinsics),
1671            "return-addresses" => Some(Self::ReturnAddresses),
1672            "typeinfo-vt-ptr-discrimination" => Some(Self::TypeInfoVTPtrDisc),
1673            "vt-ptr-addr-discrimination" => Some(Self::VTPtrAddrDisc),
1674            "vt-ptr-type-discrimination" => Some(Self::VTPtrTypeDisc),
1675            _ => None,
1676        }
1677    }
1678}
1679
1680#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for LinkerJobs { }
#[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)]
1681pub enum LinkerJobs {
1682    /// Do not pass anything to the linker, use it's default behavior.
1683    Default,
1684    /// Pass some specific number of jobs to use to the linker.
1685    Explicit(NonZero<usize>),
1686}
1687
1688impl LinkerJobs {
1689    pub fn limit(self) -> Option<NonZero<usize>> {
1690        match self {
1691            LinkerJobs::Default => None,
1692            LinkerJobs::Explicit(n) => Some(n),
1693        }
1694    }
1695}
1696
1697/// `None` for frontend and backend means everything is single-threaded
1698/// and synchronization can be disabled.
1699#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Jobs { }
#[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)]
1700pub struct Jobs {
1701    pub frontend: Option<NonZero<usize>>,
1702    pub backend: Option<NonZero<usize>>,
1703    pub linker: LinkerJobs,
1704}
1705
1706fn parse_jobs_all(
1707    early_dcx: &EarlyDiagCtxt,
1708    matches: &getopts::Matches,
1709    zthreads: Option<&str>,
1710    zno_parallel_backend: bool,
1711    unstable: bool,
1712) -> Jobs {
1713    if zno_parallel_backend {
1714        early_dcx.early_fatal("`-Zno-parallel-backend` is removed, use `--jobs-backend=1` instead");
1715    }
1716    let mut available = None;
1717    let jobs = matches
1718        .opt_str("jobs")
1719        .map(|s| parse_jobs_one(early_dcx, "--jobs", &s, unstable, &mut available));
1720    let check_upper_limit = |value: Option<_>, opt_name| {
1721        if let Some(jobs) = jobs
1722            && value.or(NonZero::new(1)) > jobs.or(NonZero::new(1))
1723        {
1724            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`"));
1725        }
1726    };
1727    let frontend = match matches.opt_str("jobs-frontend") {
1728        Some(jobs_frontend) => {
1729            let opt_name = "--jobs-frontend";
1730            let frontend =
1731                parse_jobs_one(early_dcx, opt_name, &jobs_frontend, unstable, &mut available);
1732            check_upper_limit(frontend, opt_name);
1733            if zthreads.is_some() {
1734                early_dcx.early_fatal("cannot use both `--jobs-frontend` and `-Zthreads`");
1735            }
1736            frontend
1737        }
1738        None => match zthreads {
1739            Some(zthreads) => {
1740                let opt_name = "-Zthreads";
1741                let frontend =
1742                    parse_jobs_one(early_dcx, opt_name, zthreads, unstable, &mut available);
1743                check_upper_limit(frontend, opt_name);
1744                frontend
1745            }
1746            None => jobs.flatten(),
1747        },
1748    };
1749    let backend = match matches.opt_str("jobs-backend") {
1750        Some(jobs_backend) => {
1751            let opt_name = "--jobs-backend";
1752            let backend =
1753                parse_jobs_one(early_dcx, opt_name, &jobs_backend, unstable, &mut available);
1754            check_upper_limit(backend, opt_name);
1755            backend
1756        }
1757        None => match jobs {
1758            Some(n) => n,
1759            // Use all available parallelism as the default.
1760            None => parse_jobs_one(early_dcx, "", "0", unstable, &mut available),
1761        },
1762    };
1763    let linker = match matches.opt_str("jobs-linker") {
1764        Some(jobs_linker) => {
1765            let opt_name = "--jobs-linker";
1766            let linker =
1767                parse_jobs_one(early_dcx, opt_name, &jobs_linker, unstable, &mut available);
1768            check_upper_limit(linker, opt_name);
1769            LinkerJobs::Explicit(linker.or(NonZero::new(1)).unwrap())
1770        }
1771        None => match jobs {
1772            Some(n) => LinkerJobs::Explicit(n.or(NonZero::new(1)).unwrap()),
1773            None => LinkerJobs::Default, // back compat with lld
1774        },
1775    };
1776
1777    Jobs { frontend, backend, linker }
1778}
1779
1780// Parse a string passed to one of the `--jobs` options or `-Zthreads`.
1781fn parse_jobs_one(
1782    early_dcx: &EarlyDiagCtxt,
1783    opt_name: &str,
1784    s: &str,
1785    unstable: bool,
1786    available: &mut Option<u8>,
1787) -> Option<NonZero<usize>> {
1788    if s == "sync" {
1789        // Enable synchronization overhead for benchmarking despite only using one thread.
1790        if !unstable {
1791            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`"));
1792        }
1793        return NonZero::new(1);
1794    }
1795    // The number of jobs is capped by 255 (`u8::MAX`) to avoid arbitrary large numbers like 999999
1796    // causing compiler panics (#117638). The limit can be potentially increased, because e.g.
1797    // rustc thread pool supports up to `u16::MAX` threads in theory.
1798    let n = match u8::from_str(s) {
1799        Ok(0) => *available.get_or_insert_with(|| match thread::available_parallelism() {
1800            Ok(n) => u8::try_from(n.get()).unwrap_or(u8::MAX),
1801            Err(_) => 1,
1802        }),
1803        Ok(n) => n,
1804        Err(_) => early_dcx
1805            .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`")),
1806    };
1807    // `Jobs` uses `usize` for more convenient use, even if the actual values are limited to `u8`.
1808    (n > 1).then_some(NonZero::new(usize::from(n)).unwrap())
1809}
1810
1811pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
1812    // First disallow some configuration given on the command line
1813    cfg::disallow_cfgs(sess, &user_cfg);
1814
1815    // Then combine the configuration requested by the session (command line) with
1816    // some default and generated configuration items.
1817    user_cfg.extend(cfg::default_configuration(sess));
1818    user_cfg
1819}
1820
1821pub fn build_target_config(
1822    early_dcx: &EarlyDiagCtxt,
1823    target: &TargetTuple,
1824    sysroot: &Path,
1825    unstable_options: bool,
1826) -> Target {
1827    match Target::search(target, sysroot, unstable_options) {
1828        Ok((target, warnings)) => {
1829            for warning in warnings.warning_messages() {
1830                early_dcx.early_warn(warning)
1831            }
1832
1833            if !#[allow(non_exhaustive_omitted_patterns)] match target.pointer_width {
    16 | 32 | 64 => true,
    _ => false,
}matches!(target.pointer_width, 16 | 32 | 64) {
1834                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!(
1835                    "target specification was invalid: unrecognized target-pointer-width {}",
1836                    target.pointer_width
1837                ))
1838            }
1839            target
1840        }
1841        Err(e) => {
1842            let mut err =
1843                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}"));
1844            err.help("run `rustc --print target-list` for a list of built-in targets");
1845            let typed = target.tuple();
1846            let limit = typed.len() / 3 + 1;
1847            if let Some(suggestion) = rustc_target::spec::TARGETS
1848                .iter()
1849                .filter_map(|&t| {
1850                    rustc_span::edit_distance::edit_distance_with_substrings(typed, t, limit)
1851                        .map(|d| (d, t))
1852                })
1853                .min_by_key(|(d, _)| *d)
1854                .map(|(_, t)| t)
1855            {
1856                err.help(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("did you mean `{0}`?", suggestion))
    })format!("did you mean `{suggestion}`?"));
1857            }
1858            err.emit()
1859        }
1860    }
1861}
1862
1863#[derive(#[automatically_derived]
impl ::core::marker::Copy for OptionStability { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for OptionStability { }
#[automatically_derived]
impl ::core::clone::Clone for OptionStability {
    #[inline]
    fn clone(&self) -> OptionStability { *self }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for OptionStability { }
#[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)]
1864pub enum OptionStability {
1865    Stable,
1866    Unstable,
1867}
1868
1869#[derive(#[automatically_derived]
impl ::core::marker::Copy for OptionKind { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for OptionKind { }
#[automatically_derived]
impl ::core::clone::Clone for OptionKind {
    #[inline]
    fn clone(&self) -> OptionKind { *self }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for OptionKind { }
#[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)]
1870pub enum OptionKind {
1871    /// An option that takes a value, and cannot appear more than once (e.g. `--out-dir`).
1872    ///
1873    /// Corresponds to [`getopts::Options::optopt`].
1874    Opt,
1875
1876    /// An option that takes a value, and can appear multiple times (e.g. `--emit`).
1877    ///
1878    /// Corresponds to [`getopts::Options::optmulti`].
1879    Multi,
1880
1881    /// An option that does not take a value, and cannot appear more than once (e.g. `--help`).
1882    ///
1883    /// Corresponds to [`getopts::Options::optflag`].
1884    /// The `hint` string must be empty.
1885    Flag,
1886
1887    /// An option that does not take a value, and can appear multiple times (e.g. `-O`).
1888    ///
1889    /// Corresponds to [`getopts::Options::optflagmulti`].
1890    /// The `hint` string must be empty.
1891    FlagMulti,
1892}
1893
1894pub struct RustcOptGroup {
1895    /// The "primary" name for this option. Normally equal to `long_name`,
1896    /// except for options that don't have a long name, in which case
1897    /// `short_name` is used.
1898    ///
1899    /// This is needed when interacting with `getopts` in some situations,
1900    /// because if an option has both forms, that library treats the long name
1901    /// as primary and the short name as an alias.
1902    pub name: &'static str,
1903    stability: OptionStability,
1904    kind: OptionKind,
1905
1906    short_name: &'static str,
1907    long_name: &'static str,
1908    desc: &'static str,
1909    value_hint: &'static str,
1910
1911    /// If true, this option should not be printed by `rustc --help`, but
1912    /// should still be printed by `rustc --help -v`.
1913    pub is_verbose_help_only: bool,
1914}
1915
1916impl RustcOptGroup {
1917    pub fn is_stable(&self) -> bool {
1918        self.stability == OptionStability::Stable
1919    }
1920
1921    pub fn apply(&self, options: &mut getopts::Options) {
1922        let &Self { short_name, long_name, desc, value_hint, .. } = self;
1923        match self.kind {
1924            OptionKind::Opt => options.optopt(short_name, long_name, desc, value_hint),
1925            OptionKind::Multi => options.optmulti(short_name, long_name, desc, value_hint),
1926            OptionKind::Flag => options.optflag(short_name, long_name, desc),
1927            OptionKind::FlagMulti => options.optflagmulti(short_name, long_name, desc),
1928        };
1929    }
1930
1931    /// This is for diagnostics-only.
1932    pub fn long_name(&self) -> &str {
1933        self.long_name
1934    }
1935}
1936
1937pub fn make_opt(
1938    stability: OptionStability,
1939    kind: OptionKind,
1940    short_name: &'static str,
1941    long_name: &'static str,
1942    desc: &'static str,
1943    value_hint: &'static str,
1944) -> RustcOptGroup {
1945    // "Flag" options don't have a value, and therefore don't have a value hint.
1946    match kind {
1947        OptionKind::Opt | OptionKind::Multi => {}
1948        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, ""),
1949    }
1950    RustcOptGroup {
1951        name: cmp::max_by_key(short_name, long_name, |s| s.len()),
1952        stability,
1953        kind,
1954        short_name,
1955        long_name,
1956        desc,
1957        value_hint,
1958        is_verbose_help_only: false,
1959    }
1960}
1961
1962static EDITION_STRING: LazyLock<String> = LazyLock::new(|| {
1963    ::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!(
1964        "Specify which edition of the compiler to use when compiling code. \
1965The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE_EDITION}."
1966    )
1967});
1968
1969static EMIT_HELP: LazyLock<String> = LazyLock::new(|| {
1970    let mut result =
1971        String::from("Comma separated list of types of output for the compiler to emit.\n");
1972    result.push_str("Each TYPE has the default FILE name:\n");
1973
1974    for output in OutputType::iter_all() {
1975        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()));
1976    }
1977
1978    result
1979});
1980
1981/// Returns all rustc command line options, including metadata for
1982/// each option, such as whether the option is stable.
1983///
1984/// # Option style guidelines
1985///
1986/// - `<param>`: Indicates a required parameter
1987/// - `[param]`: Indicates an optional parameter
1988/// - `|`: Indicates a mutually exclusive option
1989/// - `*`: a list element with description
1990pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
1991    use OptionKind::{Flag, FlagMulti, Multi, Opt};
1992    use OptionStability::{Stable, Unstable};
1993
1994    use self::make_opt as opt;
1995
1996    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![
1997        opt(Stable, Flag, "h", "help", "Display this message", ""),
1998        opt(
1999            Stable,
2000            Multi,
2001            "",
2002            "cfg",
2003            "Configure the compilation environment.\n\
2004                SPEC supports the syntax `<NAME>[=\"<VALUE>\"]`.",
2005            "<SPEC>",
2006        ),
2007        opt(Stable, Multi, "", "check-cfg", "Provide list of expected cfgs for checking", "<SPEC>"),
2008        opt(
2009            Stable,
2010            Multi,
2011            "L",
2012            "",
2013            "Add a directory to the library search path. \
2014                The optional KIND can be one of <dependency|crate|native|framework|all> (default: all).",
2015            "[<KIND>=]<PATH>",
2016        ),
2017        opt(
2018            Stable,
2019            Multi,
2020            "l",
2021            "",
2022            "Link the generated crate(s) to the specified native\n\
2023                library NAME. The optional KIND can be one of\n\
2024                <static|framework|dylib> (default: dylib).\n\
2025                Optional comma separated MODIFIERS\n\
2026                <bundle|verbatim|whole-archive|as-needed>\n\
2027                may be specified each with a prefix of either '+' to\n\
2028                enable or '-' to disable.",
2029            "[<KIND>[:<MODIFIERS>]=]<NAME>[:<RENAME>]",
2030        ),
2031        make_crate_type_option(),
2032        opt(Stable, Opt, "", "crate-name", "Specify the name of the crate being built", "<NAME>"),
2033        opt(Stable, Opt, "", "edition", &EDITION_STRING, EDITION_NAME_LIST),
2034        opt(Stable, Multi, "", "emit", &EMIT_HELP, "<TYPE>[=<FILE>]"),
2035        opt(Stable, Multi, "", "print", &print_request::PRINT_HELP, "<INFO>[=<FILE>]"),
2036        opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
2037        opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=3", ""),
2038        opt(Stable, Opt, "o", "", "Write output to FILENAME", "<FILENAME>"),
2039        opt(Stable, Opt, "", "out-dir", "Write output to compiler-chosen filename in DIR", "<DIR>"),
2040        opt(
2041            Stable,
2042            Opt,
2043            "",
2044            "explain",
2045            "Provide a detailed explanation of an error message",
2046            "<OPT>",
2047        ),
2048        opt(Stable, Flag, "", "test", "Build a test harness", ""),
2049        opt(Stable, Opt, "", "target", "Target tuple for which the code is compiled", "<TARGET>"),
2050        opt(Stable, Multi, "A", "allow", "Set lint allowed", "<LINT>"),
2051        opt(Stable, Multi, "W", "warn", "Set lint warnings", "<LINT>"),
2052        opt(Stable, Multi, "", "force-warn", "Set lint force-warn", "<LINT>"),
2053        opt(Stable, Multi, "D", "deny", "Set lint denied", "<LINT>"),
2054        opt(Stable, Multi, "F", "forbid", "Set lint forbidden", "<LINT>"),
2055        opt(
2056            Stable,
2057            Multi,
2058            "",
2059            "cap-lints",
2060            "Set the most restrictive lint level. More restrictive lints are capped at this level",
2061            "<LEVEL>",
2062        ),
2063        opt(Stable, Multi, "C", "codegen", "Set a codegen option", "<OPT>[=<VALUE>]"),
2064        opt(Stable, Flag, "V", "version", "Print version info and exit", ""),
2065        opt(Stable, Flag, "v", "verbose", "Use verbose output", ""),
2066    ];
2067
2068    // Options in this list are hidden from `rustc --help` by default, but are
2069    // shown by `rustc --help -v`.
2070    let verbose_only = [
2071        opt(
2072            Stable,
2073            Multi,
2074            "",
2075            "extern",
2076            "Specify where an external rust library is located",
2077            "<NAME>[=<PATH>]",
2078        ),
2079        opt(Stable, Opt, "", "sysroot", "Override the system root", "<PATH>"),
2080        opt(Unstable, Multi, "Z", "", "Set unstable / perma-unstable options", "<FLAG>"),
2081        opt(
2082            Stable,
2083            Opt,
2084            "",
2085            "error-format",
2086            "How errors and other messages are produced",
2087            "<human|json|short>",
2088        ),
2089        opt(Stable, Multi, "", "json", "Configure the JSON output of the compiler", "<CONFIG>"),
2090        opt(
2091            Stable,
2092            Opt,
2093            "",
2094            "color",
2095            "Configure coloring of output:
2096                * auto   = colorize, if output goes to a tty (default);
2097                * always = always colorize output;
2098                * never  = never colorize output",
2099            "<auto|always|never>",
2100        ),
2101        opt(
2102            Stable,
2103            Opt,
2104            "",
2105            "diagnostic-width",
2106            "Inform rustc of the width of the output so that diagnostics can be truncated to fit",
2107            "<WIDTH>",
2108        ),
2109        opt(
2110            Stable,
2111            Multi,
2112            "",
2113            "remap-path-prefix",
2114            "Remap source names in all output (compiler messages and output files)",
2115            "<FROM>=<TO>",
2116        ),
2117        opt(
2118            Stable,
2119            Opt,
2120            "",
2121            "remap-path-scope",
2122            "Defines which scopes of paths should be remapped by `--remap-path-prefix`",
2123            "<macro,diagnostics,debuginfo,coverage,object,all>",
2124        ),
2125        opt(Unstable, Opt, "j", "jobs", "Limit on the number of used parallel jobs", "<N>"),
2126        opt(
2127            Unstable,
2128            Opt,
2129            "",
2130            "jobs-frontend",
2131            "Limit on the number of parallel jobs used by frontend",
2132            "<N>",
2133        ),
2134        opt(
2135            Unstable,
2136            Opt,
2137            "",
2138            "jobs-backend",
2139            "Limit on the number of parallel jobs used by backend",
2140            "<N>",
2141        ),
2142        opt(
2143            Unstable,
2144            Opt,
2145            "",
2146            "jobs-linker",
2147            "Limit on the number of parallel jobs used by linker",
2148            "<N>",
2149        ),
2150    ];
2151    options.extend(verbose_only.into_iter().map(|mut opt| {
2152        opt.is_verbose_help_only = true;
2153        opt
2154    }));
2155
2156    options
2157}
2158
2159pub fn get_cmd_lint_options(
2160    early_dcx: &EarlyDiagCtxt,
2161    matches: &getopts::Matches,
2162) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
2163    let mut lint_opts_with_position = ::alloc::vec::Vec::new()vec![];
2164    let mut describe_lints = false;
2165
2166    for level in [lint::Allow, lint::Warn, lint::ForceWarn, lint::Deny, lint::Forbid] {
2167        for (arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
2168            if lint_name == "help" {
2169                describe_lints = true;
2170            } else {
2171                lint_opts_with_position.push((arg_pos, lint_name.replace('-', "_"), level));
2172            }
2173        }
2174    }
2175
2176    lint_opts_with_position.sort_by_key(|x| x.0);
2177    let lint_opts = lint_opts_with_position
2178        .iter()
2179        .cloned()
2180        .map(|(_, lint_name, level)| (lint_name, level))
2181        .collect();
2182
2183    let lint_cap = matches.opt_str("cap-lints").map(|cap| {
2184        lint::Level::from_str(&cap)
2185            .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}`")))
2186    });
2187
2188    (lint_opts, describe_lints, lint_cap)
2189}
2190
2191/// Parses the `--color` flag.
2192pub fn parse_color(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> ColorConfig {
2193    match matches.opt_str("color").as_deref() {
2194        Some("auto") => ColorConfig::Auto,
2195        Some("always") => ColorConfig::Always,
2196        Some("never") => ColorConfig::Never,
2197
2198        None => ColorConfig::Auto,
2199
2200        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!(
2201            "argument for `--color` must be auto, \
2202                 always or never (instead was `{arg}`)"
2203        )),
2204    }
2205}
2206
2207/// Possible json config files
2208pub struct JsonConfig {
2209    pub json_rendered: HumanReadableErrorType,
2210    pub json_color: ColorConfig,
2211    json_artifact_notifications: bool,
2212    /// Output start and end timestamps of several high-level compilation sections
2213    /// (frontend, backend, linker).
2214    json_timings: bool,
2215    pub json_unused_externs: JsonUnusedExterns,
2216    json_future_incompat: bool,
2217}
2218
2219/// Report unused externs in event stream
2220#[derive(#[automatically_derived]
impl ::core::marker::Copy for JsonUnusedExterns { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for JsonUnusedExterns { }
#[automatically_derived]
impl ::core::clone::Clone for JsonUnusedExterns {
    #[inline]
    fn clone(&self) -> JsonUnusedExterns { *self }
}Clone)]
2221pub enum JsonUnusedExterns {
2222    /// Do not
2223    No,
2224    /// Report, but do not exit with failure status for deny/forbid
2225    Silent,
2226    /// Report, and also exit with failure status for deny/forbid
2227    Loud,
2228}
2229
2230impl JsonUnusedExterns {
2231    pub fn is_enabled(&self) -> bool {
2232        match self {
2233            JsonUnusedExterns::No => false,
2234            JsonUnusedExterns::Loud | JsonUnusedExterns::Silent => true,
2235        }
2236    }
2237
2238    pub fn is_loud(&self) -> bool {
2239        match self {
2240            JsonUnusedExterns::No | JsonUnusedExterns::Silent => false,
2241            JsonUnusedExterns::Loud => true,
2242        }
2243    }
2244}
2245
2246/// Parse the `--json` flag.
2247///
2248/// The first value returned is how to render JSON diagnostics, and the second
2249/// is whether or not artifact notifications are enabled.
2250pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> JsonConfig {
2251    let mut json_rendered = HumanReadableErrorType { short: false, unicode: false };
2252    let mut json_color = ColorConfig::Never;
2253    let mut json_artifact_notifications = false;
2254    let mut json_unused_externs = JsonUnusedExterns::No;
2255    let mut json_future_incompat = false;
2256    let mut json_timings = false;
2257    for option in matches.opt_strs("json") {
2258        // For now conservatively forbid `--color` with `--json` since `--json`
2259        // won't actually be emitting any colors and anything colorized is
2260        // embedded in a diagnostic message anyway.
2261        if matches.opt_str("color").is_some() {
2262            early_dcx.early_fatal("cannot specify the `--color` option with `--json`");
2263        }
2264
2265        for sub_option in option.split(',') {
2266            match sub_option {
2267                "diagnostic-short" => {
2268                    json_rendered = HumanReadableErrorType { short: true, unicode: false };
2269                }
2270                "diagnostic-unicode" => {
2271                    json_rendered = HumanReadableErrorType { short: false, unicode: true };
2272                }
2273                "diagnostic-rendered-ansi" => json_color = ColorConfig::Always,
2274                "artifacts" => json_artifact_notifications = true,
2275                "timings" => json_timings = true,
2276                "unused-externs" => json_unused_externs = JsonUnusedExterns::Loud,
2277                "unused-externs-silent" => json_unused_externs = JsonUnusedExterns::Silent,
2278                "future-incompat" => json_future_incompat = true,
2279                s => early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown `--json` option `{0}`", s))
    })format!("unknown `--json` option `{s}`")),
2280            }
2281        }
2282    }
2283
2284    JsonConfig {
2285        json_rendered,
2286        json_color,
2287        json_artifact_notifications,
2288        json_timings,
2289        json_unused_externs,
2290        json_future_incompat,
2291    }
2292}
2293
2294/// Parses the `--error-format` flag.
2295pub fn parse_error_format(
2296    early_dcx: &mut EarlyDiagCtxt,
2297    matches: &getopts::Matches,
2298    color_config: ColorConfig,
2299    json_color: ColorConfig,
2300    json_rendered: HumanReadableErrorType,
2301) -> ErrorOutputType {
2302    let default_kind = HumanReadableErrorType { short: false, unicode: false };
2303    // We need the `opts_present` check because the driver will send us Matches
2304    // with only stable options if no unstable options are used. Since error-format
2305    // is unstable, it will not be present. We have to use `opts_present` not
2306    // `opt_present` because the latter will panic.
2307    let error_format = if matches.opts_present(&["error-format".to_owned()]) {
2308        match matches.opt_str("error-format").as_deref() {
2309            None | Some("human") => {
2310                ErrorOutputType::HumanReadable { color_config, kind: default_kind }
2311            }
2312            Some("json") => {
2313                ErrorOutputType::Json { pretty: false, json_rendered, color_config: json_color }
2314            }
2315            Some("pretty-json") => {
2316                ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color }
2317            }
2318            Some("short") => ErrorOutputType::HumanReadable {
2319                kind: HumanReadableErrorType { short: true, unicode: false },
2320                color_config,
2321            },
2322            Some("human-unicode") => ErrorOutputType::HumanReadable {
2323                kind: HumanReadableErrorType { short: false, unicode: true },
2324                color_config,
2325            },
2326            Some(arg) => {
2327                early_dcx.set_error_format(ErrorOutputType::HumanReadable {
2328                    color_config,
2329                    kind: default_kind,
2330                });
2331                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!(
2332                    "argument for `--error-format` must be `human`, `human-unicode`, \
2333                    `json`, `pretty-json` or `short` (instead was `{arg}`)"
2334                ))
2335            }
2336        }
2337    } else {
2338        ErrorOutputType::HumanReadable { color_config, kind: default_kind }
2339    };
2340
2341    match error_format {
2342        ErrorOutputType::Json { .. } => {}
2343
2344        // Conservatively require that the `--json` argument is coupled with
2345        // `--error-format=json`. This means that `--json` is specified we
2346        // should actually be emitting JSON blobs.
2347        _ if !matches.opt_strs("json").is_empty() => {
2348            early_dcx.early_fatal("using `--json` requires also using `--error-format=json`");
2349        }
2350
2351        _ => {}
2352    }
2353
2354    error_format
2355}
2356
2357pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Edition {
2358    let edition = match matches.opt_str("edition") {
2359        Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| {
2360            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!(
2361                "argument for `--edition` must be one of: \
2362                     {EDITION_NAME_LIST}. (instead was `{arg}`)"
2363            ))
2364        }),
2365        None => DEFAULT_EDITION,
2366    };
2367
2368    if !edition.is_stable() && !nightly_options::is_unstable_enabled(matches) {
2369        let is_nightly = nightly_options::match_is_nightly_build(matches);
2370        let msg = if !is_nightly {
2371            ::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!(
2372                "the crate requires edition {edition}, but the latest edition supported by this Rust version is {LATEST_STABLE_EDITION}"
2373            )
2374        } else {
2375            ::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")
2376        };
2377        early_dcx.early_fatal(msg)
2378    }
2379
2380    edition
2381}
2382
2383fn check_error_format_stability(
2384    early_dcx: &EarlyDiagCtxt,
2385    unstable_opts: &UnstableOptions,
2386    is_nightly_build: bool,
2387    format: ErrorOutputType,
2388) {
2389    if unstable_opts.unstable_options || is_nightly_build {
2390        return;
2391    }
2392    let format = match format {
2393        ErrorOutputType::Json { pretty: true, .. } => "pretty-json",
2394        ErrorOutputType::HumanReadable { kind, .. } => match kind {
2395            HumanReadableErrorType { unicode: true, .. } => "human-unicode",
2396            _ => return,
2397        },
2398        _ => return,
2399    };
2400    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"))
2401}
2402
2403fn parse_output_types(
2404    early_dcx: &EarlyDiagCtxt,
2405    unstable_opts: &UnstableOptions,
2406    matches: &getopts::Matches,
2407) -> OutputTypes {
2408    let mut output_types = BTreeMap::new();
2409    if !unstable_opts.parse_crate_root_only {
2410        for list in matches.opt_strs("emit") {
2411            for output_type in list.split(',') {
2412                let (shorthand, path) = split_out_file_name(output_type);
2413                let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
2414                    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!(
2415                        "unknown emission type: `{shorthand}` - expected one of: {display}",
2416                        display = OutputType::shorthands_display(),
2417                    ))
2418                });
2419                if output_type == OutputType::ThinLinkBitcode && !unstable_opts.unstable_options {
2420                    early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("{0} requested but -Zunstable-options not specified",
                OutputType::ThinLinkBitcode.shorthand()))
    })format!(
2421                        "{} requested but -Zunstable-options not specified",
2422                        OutputType::ThinLinkBitcode.shorthand()
2423                    ));
2424                }
2425                output_types.insert(output_type, path);
2426            }
2427        }
2428    };
2429    if output_types.is_empty() {
2430        output_types.insert(OutputType::Exe, None);
2431    }
2432    OutputTypes(output_types)
2433}
2434
2435fn split_out_file_name(arg: &str) -> (&str, Option<OutFileName>) {
2436    match arg.split_once('=') {
2437        None => (arg, None),
2438        Some((kind, "-")) => (kind, Some(OutFileName::Stdout)),
2439        Some((kind, path)) => (kind, Some(OutFileName::Real(PathBuf::from(path)))),
2440    }
2441}
2442
2443fn should_override_cgus_and_disable_thinlto(
2444    early_dcx: &EarlyDiagCtxt,
2445    output_types: &OutputTypes,
2446    matches: &getopts::Matches,
2447    mut codegen_units: Option<usize>,
2448) -> (bool, Option<usize>) {
2449    let mut disable_local_thinlto = false;
2450    // Issue #30063: if user requests LLVM-related output to one
2451    // particular path, disable codegen-units.
2452    let incompatible: Vec<_> = output_types
2453        .0
2454        .iter()
2455        .map(|ot_path| ot_path.0)
2456        .filter(|ot| !ot.is_compatible_with_codegen_units_and_single_output_file())
2457        .map(|ot| ot.shorthand())
2458        .collect();
2459    if !incompatible.is_empty() {
2460        match codegen_units {
2461            Some(n) if n > 1 => {
2462                if matches.opt_present("o") {
2463                    for ot in &incompatible {
2464                        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!(
2465                            "`--emit={ot}` with `-o` incompatible with \
2466                                 `-C codegen-units=N` for N > 1",
2467                        ));
2468                    }
2469                    early_dcx.early_warn("resetting to default -C codegen-units=1");
2470                    codegen_units = Some(1);
2471                    disable_local_thinlto = true;
2472                }
2473            }
2474            _ => {
2475                codegen_units = Some(1);
2476                disable_local_thinlto = true;
2477            }
2478        }
2479    }
2480
2481    if codegen_units == Some(0) {
2482        early_dcx.early_fatal("value for codegen units must be a positive non-zero integer");
2483    }
2484
2485    (disable_local_thinlto, codegen_units)
2486}
2487
2488pub fn parse_target_triple(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> TargetTuple {
2489    match matches.opt_str("target") {
2490        Some(target) if target.ends_with(".json") => {
2491            let path = Path::new(&target);
2492            TargetTuple::from_path(path).unwrap_or_else(|_| {
2493                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"))
2494            })
2495        }
2496        Some(target) => TargetTuple::TargetTuple(target),
2497        _ => TargetTuple::from_tuple(host_tuple()),
2498    }
2499}
2500
2501fn parse_opt_level(
2502    early_dcx: &EarlyDiagCtxt,
2503    matches: &getopts::Matches,
2504    cg: &CodegenOptions,
2505) -> OptLevel {
2506    // The `-O` and `-C opt-level` flags specify the same setting, so we want to be able
2507    // to use them interchangeably. However, because they're technically different flags,
2508    // we need to work out manually which should take precedence if both are supplied (i.e.
2509    // the rightmost flag). We do this by finding the (rightmost) position of both flags and
2510    // comparing them. Note that if a flag is not found, its position will be `None`, which
2511    // always compared less than `Some(_)`.
2512    let max_o = matches.opt_positions("O").into_iter().max();
2513    let max_c = matches
2514        .opt_strs_pos("C")
2515        .into_iter()
2516        .flat_map(|(i, s)| {
2517            // NB: This can match a string without `=`.
2518            if let Some("opt-level") = s.split('=').next() { Some(i) } else { None }
2519        })
2520        .max();
2521    if max_o > max_c {
2522        OptLevel::Aggressive
2523    } else {
2524        match cg.opt_level.as_ref() {
2525            "0" => OptLevel::No,
2526            "1" => OptLevel::Less,
2527            "2" => OptLevel::More,
2528            "3" => OptLevel::Aggressive,
2529            "s" => OptLevel::Size,
2530            "z" => OptLevel::SizeMin,
2531            arg => {
2532                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!(
2533                    "optimization level needs to be \
2534                            between 0-3, s or z (instead was `{arg}`)"
2535                ));
2536            }
2537        }
2538    }
2539}
2540
2541fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInfo {
2542    let max_g = matches.opt_positions("g").into_iter().max();
2543    let max_c = matches
2544        .opt_strs_pos("C")
2545        .into_iter()
2546        .flat_map(|(i, s)| {
2547            // NB: This can match a string without `=`.
2548            if let Some("debuginfo") = s.split('=').next() { Some(i) } else { None }
2549        })
2550        .max();
2551    if max_g > max_c { DebugInfo::Full } else { cg.debuginfo }
2552}
2553
2554pub fn parse_externs(
2555    early_dcx: &EarlyDiagCtxt,
2556    matches: &getopts::Matches,
2557    unstable_opts: &UnstableOptions,
2558) -> Externs {
2559    let is_unstable_enabled = unstable_opts.unstable_options;
2560    let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
2561    for arg in matches.opt_strs("extern") {
2562        let ExternOpt { crate_name: name, path, options } =
2563            split_extern_opt(early_dcx, unstable_opts, &arg).unwrap_or_else(|e| e.emit());
2564
2565        let entry = externs.entry(name.to_owned());
2566
2567        use std::collections::btree_map::Entry;
2568
2569        let entry = if let Some(path) = path {
2570            // --extern prelude_name=some_file.rlib
2571            let path = CanonicalizedPath::new(path);
2572            match entry {
2573                Entry::Vacant(vacant) => {
2574                    let files = BTreeSet::from_iter(iter::once(path));
2575                    vacant.insert(ExternEntry::new(ExternLocation::ExactPaths(files)))
2576                }
2577                Entry::Occupied(occupied) => {
2578                    let ext_ent = occupied.into_mut();
2579                    match ext_ent {
2580                        ExternEntry { location: ExternLocation::ExactPaths(files), .. } => {
2581                            files.insert(path);
2582                        }
2583                        ExternEntry {
2584                            location: location @ ExternLocation::FoundInLibrarySearchDirectories,
2585                            ..
2586                        } => {
2587                            // Exact paths take precedence over search directories.
2588                            let files = BTreeSet::from_iter(iter::once(path));
2589                            *location = ExternLocation::ExactPaths(files);
2590                        }
2591                    }
2592                    ext_ent
2593                }
2594            }
2595        } else {
2596            // --extern prelude_name
2597            match entry {
2598                Entry::Vacant(vacant) => {
2599                    vacant.insert(ExternEntry::new(ExternLocation::FoundInLibrarySearchDirectories))
2600                }
2601                Entry::Occupied(occupied) => {
2602                    // Ignore if already specified.
2603                    occupied.into_mut()
2604                }
2605            }
2606        };
2607
2608        let mut is_private_dep = false;
2609        let mut add_prelude = true;
2610        let mut nounused_dep = false;
2611        let mut force = false;
2612        if let Some(opts) = options {
2613            if !is_unstable_enabled {
2614                early_dcx.early_fatal(
2615                    "the `-Z unstable-options` flag must also be passed to \
2616                     enable `--extern` options",
2617                );
2618            }
2619            for opt in opts.split(',') {
2620                match opt {
2621                    "priv" => is_private_dep = true,
2622                    "noprelude" => {
2623                        if let ExternLocation::ExactPaths(_) = &entry.location {
2624                            add_prelude = false;
2625                        } else {
2626                            early_dcx.early_fatal(
2627                                "the `noprelude` --extern option requires a file path",
2628                            );
2629                        }
2630                    }
2631                    "nounused" => nounused_dep = true,
2632                    "force" => force = true,
2633                    _ => early_dcx.early_fatal(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown --extern option `{0}`",
                opt))
    })format!("unknown --extern option `{opt}`")),
2634                }
2635            }
2636        }
2637
2638        // Crates start out being not private, and go to being private `priv`
2639        // is specified.
2640        entry.is_private_dep |= is_private_dep;
2641        // likewise `nounused`
2642        entry.nounused_dep |= nounused_dep;
2643        // and `force`
2644        entry.force |= force;
2645        // If any flag is missing `noprelude`, then add to the prelude.
2646        entry.add_prelude |= add_prelude;
2647    }
2648    Externs(externs)
2649}
2650
2651fn parse_remap_path_prefix(
2652    early_dcx: &EarlyDiagCtxt,
2653    matches: &getopts::Matches,
2654) -> Vec<(PathBuf, PathBuf)> {
2655    matches
2656        .opt_strs("remap-path-prefix")
2657        .into_iter()
2658        .map(|remap| match remap.rsplit_once('=') {
2659            None => {
2660                early_dcx.early_fatal("--remap-path-prefix must contain '=' between FROM and TO")
2661            }
2662            Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)),
2663        })
2664        .collect()
2665}
2666
2667// JUSTIFICATION: before wrapper fn is available
2668#[allow(rustc::bad_opt_access)]
2669pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::Matches) -> Options {
2670    let color = parse_color(early_dcx, matches);
2671
2672    let edition = parse_crate_edition(early_dcx, matches);
2673
2674    let crate_name = matches.opt_str("crate-name");
2675    let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
2676    let JsonConfig {
2677        json_rendered,
2678        json_color,
2679        json_artifact_notifications,
2680        json_timings,
2681        json_unused_externs,
2682        json_future_incompat,
2683    } = parse_json(early_dcx, matches);
2684
2685    let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered);
2686
2687    early_dcx.set_error_format(error_format);
2688
2689    let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
2690        early_dcx.early_fatal("`--diagnostic-width` must be an positive integer");
2691    });
2692
2693    let unparsed_crate_types = matches.opt_strs("crate-type");
2694    let crate_types = parse_crate_types_from_list(unparsed_crate_types)
2695        .unwrap_or_else(|e| early_dcx.early_fatal(e));
2696
2697    let mut collected_options = Default::default();
2698
2699    let mut unstable_opts = UnstableOptions::build(early_dcx, matches, &mut collected_options);
2700
2701    // `-Zassumptions-on-binders` requires the next trait solver globally. Normalize after
2702    // parsing so the effective config is independent of flag order and so consumers that
2703    // read `next_solver.globally` directly (e.g. feature-gate checks) see the right value.
2704    if unstable_opts.assumptions_on_binders {
2705        // `NextSolverConfig::default()` has `coherence: true`; the only way `coherence` is
2706        // false here is an explicit `-Znext-solver=no`.
2707        if !unstable_opts.next_solver.coherence {
2708            early_dcx.early_warn(
2709                "-Zassumptions-on-binders unconditionally enables the next trait solver; \
2710                 `-Znext-solver=no` is ignored",
2711            );
2712        }
2713        unstable_opts.next_solver = NextSolverConfig { coherence: true, globally: true };
2714    }
2715
2716    if unstable_opts.staticlib_hide_internal_symbols && !crate_types.contains(&CrateType::StaticLib)
2717    {
2718        early_dcx.early_warn(
2719            "-Zstaticlib-hide-internal-symbols has no effect without `--crate-type staticlib`",
2720        );
2721    }
2722
2723    if unstable_opts.staticlib_rename_internal_symbols
2724        && !crate_types.contains(&CrateType::StaticLib)
2725    {
2726        early_dcx.early_warn(
2727            "-Zstaticlib-rename-internal-symbols has no effect without `--crate-type staticlib`",
2728        );
2729    }
2730
2731    let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches);
2732
2733    if !unstable_opts.unstable_options && json_timings {
2734        early_dcx.early_fatal("--json=timings is unstable and requires using `-Zunstable-options`");
2735    }
2736
2737    check_error_format_stability(
2738        early_dcx,
2739        &unstable_opts,
2740        unstable_features.is_nightly_build(),
2741        error_format,
2742    );
2743
2744    let output_types = parse_output_types(early_dcx, &unstable_opts, matches);
2745
2746    let mut cg = CodegenOptions::build(early_dcx, matches, &mut collected_options);
2747    let (disable_local_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto(
2748        early_dcx,
2749        &output_types,
2750        matches,
2751        cg.codegen_units,
2752    );
2753
2754    let incremental = cg.incremental.as_ref().map(PathBuf::from);
2755
2756    if cg.profile_generate.enabled() && cg.profile_use.is_some() {
2757        early_dcx.early_fatal("options `-C profile-generate` and `-C profile-use` are exclusive");
2758    }
2759
2760    if cg.profile_sample_use.is_some()
2761        && (cg.profile_generate.enabled() || cg.profile_use.is_some())
2762    {
2763        early_dcx.early_fatal(
2764            "option `-C profile-sample-use` cannot be used with `-C profile-generate` or `-C profile-use`",
2765        );
2766    }
2767
2768    // Check for unstable values of `-C symbol-mangling-version`.
2769    // This is what prevents them from being used on stable compilers.
2770    match cg.symbol_mangling_version {
2771        // Stable values:
2772        None | Some(SymbolManglingVersion::V0) => {}
2773
2774        // Unstable values:
2775        Some(SymbolManglingVersion::Legacy) => {
2776            if !unstable_opts.unstable_options {
2777                early_dcx.early_fatal(
2778                    "`-C symbol-mangling-version=legacy` requires `-Z unstable-options`",
2779                );
2780            }
2781        }
2782        Some(SymbolManglingVersion::Hashed) => {
2783            if !unstable_opts.unstable_options {
2784                early_dcx.early_fatal(
2785                    "`-C symbol-mangling-version=hashed` requires `-Z unstable-options`",
2786                );
2787            }
2788        }
2789    }
2790
2791    if cg.instrument_coverage != InstrumentCoverage::No {
2792        if cg.profile_generate.enabled() || cg.profile_use.is_some() {
2793            early_dcx.early_fatal(
2794                "option `-C instrument-coverage` is not compatible with either `-C profile-use` \
2795                or `-C profile-generate`",
2796            );
2797        }
2798
2799        // `-C instrument-coverage` implies `-C symbol-mangling-version=v0` - to ensure consistent
2800        // and reversible name mangling. Note, LLVM coverage tools can analyze coverage over
2801        // multiple runs, including some changes to source code; so mangled names must be consistent
2802        // across compilations.
2803        match cg.symbol_mangling_version {
2804            None => cg.symbol_mangling_version = Some(SymbolManglingVersion::V0),
2805            Some(SymbolManglingVersion::Legacy) => {
2806                early_dcx.early_warn(
2807                    "-C instrument-coverage requires symbol mangling version `v0`, \
2808                    but `-C symbol-mangling-version=legacy` was specified",
2809                );
2810            }
2811            Some(SymbolManglingVersion::V0) => {}
2812            Some(SymbolManglingVersion::Hashed) => {
2813                early_dcx.early_warn(
2814                    "-C instrument-coverage requires symbol mangling version `v0`, \
2815                    but `-C symbol-mangling-version=hashed` was specified",
2816                );
2817            }
2818        }
2819    }
2820
2821    if let Ok(graphviz_font) = std::env::var("RUSTC_GRAPHVIZ_FONT") {
2822        // FIXME: this is only mutation of UnstableOptions here, move into
2823        // UnstableOptions::build?
2824        unstable_opts.graphviz_font = graphviz_font;
2825    }
2826
2827    if !cg.embed_bitcode {
2828        match cg.lto {
2829            LtoCli::No | LtoCli::Unspecified => {}
2830            LtoCli::Yes | LtoCli::NoParam | LtoCli::Thin | LtoCli::Fat => {
2831                early_dcx.early_fatal("options `-C embed-bitcode=no` and `-C lto` are incompatible")
2832            }
2833        }
2834    }
2835
2836    let unstable_options_enabled = nightly_options::is_unstable_enabled(matches);
2837    if !unstable_options_enabled && cg.force_frame_pointers == FramePointer::NonLeaf {
2838        early_dcx.early_fatal(
2839            "`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \
2840                and a nightly compiler",
2841        )
2842    }
2843
2844    if !nightly_options::is_unstable_enabled(matches) && !unstable_opts.offload.is_empty() {
2845        early_dcx.early_fatal(
2846            "`-Zoffload=Enable` also requires `-Zunstable-options` \
2847                and a nightly compiler",
2848        )
2849    }
2850
2851    let target_triple = parse_target_triple(early_dcx, matches);
2852
2853    // Ensure `-Z unstable-options` is required when using the unstable `-C link-self-contained` and
2854    // `-C linker-flavor` options.
2855    if !unstable_options_enabled {
2856        if let Err(error) = cg.link_self_contained.check_unstable_variants(&target_triple) {
2857            early_dcx.early_fatal(error);
2858        }
2859
2860        if let Some(flavor) = cg.linker_flavor {
2861            if flavor.is_unstable() {
2862                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!(
2863                    "the linker flavor `{}` is unstable, the `-Z unstable-options` \
2864                        flag must also be passed to use the unstable values",
2865                    flavor.desc()
2866                ));
2867            }
2868        }
2869    }
2870
2871    // Check `-C link-self-contained` for consistency: individual components cannot be both enabled
2872    // and disabled at the same time.
2873    if let Some(erroneous_components) = cg.link_self_contained.check_consistency() {
2874        let names: String = erroneous_components
2875            .into_iter()
2876            .map(|c| c.as_str().unwrap())
2877            .intersperse(", ")
2878            .collect();
2879        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!(
2880            "some `-C link-self-contained` components were both enabled and disabled: {names}"
2881        ));
2882    }
2883
2884    let prints = print_request::collect_print_requests(
2885        early_dcx,
2886        &mut cg,
2887        &unstable_opts,
2888        matches,
2889        PrintCategory::ALL_VARIANTS,
2890    );
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 sysroot = Sysroot::new(matches.opt_str("sysroot").map(PathBuf::from));
2949
2950    let real_source_base_dir = |suffix: &str, confirm: &str| {
2951        let mut candidate = sysroot.path().join(suffix);
2952        if let Ok(metadata) = candidate.symlink_metadata() {
2953            // Replace the symlink bootstrap creates, with its destination.
2954            // We could try to use `fs::canonicalize` instead, but that might
2955            // produce unnecessarily verbose path.
2956            if metadata.file_type().is_symlink() {
2957                if let Ok(symlink_dest) = std::fs::read_link(&candidate) {
2958                    candidate = symlink_dest;
2959                }
2960            }
2961        }
2962
2963        // Only use this directory if it has a file we can expect to always find.
2964        candidate.join(confirm).is_file().then_some(candidate)
2965    };
2966
2967    let real_rust_source_base_dir =
2968        // This is the location used by the `rust-src` `rustup` component.
2969        real_source_base_dir("lib/rustlib/src/rust", "library/std/src/lib.rs");
2970
2971    let real_rustc_dev_source_base_dir =
2972        // This is the location used by the `rustc-dev` `rustup` component.
2973        real_source_base_dir("lib/rustlib/rustc-src/rust", "compiler/rustc/src/main.rs");
2974
2975    // We eagerly scan all files in each passed -L path. If the same directory is passed multiple
2976    // times, and the directory contains a lot of files, this can take a lot of time.
2977    // So we remove -L paths that were passed multiple times, and keep only the first occurrence.
2978    // We still have to keep the original order of the -L arguments.
2979    let search_paths: Vec<SearchPath> = {
2980        let mut seen_search_paths = FxHashSet::default();
2981        let search_path_matches: Vec<String> = matches.opt_strs("L");
2982        search_path_matches
2983            .iter()
2984            .filter(|p| seen_search_paths.insert(*p))
2985            .map(|path| {
2986                SearchPath::from_cli_opt(
2987                    sysroot.path(),
2988                    &target_triple,
2989                    early_dcx,
2990                    &path,
2991                    unstable_opts.unstable_options,
2992                )
2993            })
2994            .collect()
2995    };
2996
2997    // Ideally we would use `SourceMap::working_dir` instead, but we don't have access to it
2998    // so we manually create the potentially-remapped working directory
2999    let working_dir = {
3000        let working_dir = std::env::current_dir().unwrap_or_else(|e| {
3001            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}"));
3002        });
3003
3004        let file_mapping = file_path_mapping(
3005            remap_path_prefix.clone(),
3006            unstable_opts.remap_cwd_prefix.as_deref(),
3007            remap_path_scope,
3008        );
3009        file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
3010    };
3011
3012    let verbose = matches.opt_present("verbose") || unstable_opts.verbose_internals;
3013
3014    let jobs = parse_jobs_all(
3015        early_dcx,
3016        matches,
3017        unstable_opts.threads.as_deref(),
3018        unstable_opts.no_parallel_backend,
3019        unstable_opts.unstable_options,
3020    );
3021
3022    Options {
3023        crate_types,
3024        optimize: opt_level,
3025        debuginfo,
3026        lint_opts,
3027        lint_cap,
3028        describe_lints,
3029        output_types,
3030        search_paths,
3031        sysroot,
3032        target_triple,
3033        test,
3034        incremental,
3035        unstable_opts,
3036        prints,
3037        cg,
3038        error_format,
3039        diagnostic_width,
3040        externs,
3041        unstable_features,
3042        crate_name,
3043        libs,
3044        debug_assertions,
3045        actually_rustdoc: false,
3046        resolve_doc_links: ResolveDocLinks::ExportedMetadata,
3047        trimmed_def_paths: false,
3048        cli_forced_codegen_units: codegen_units,
3049        cli_forced_local_thinlto_off: disable_local_thinlto,
3050        remap_path_prefix,
3051        remap_path_scope,
3052        real_rust_source_base_dir,
3053        real_rustc_dev_source_base_dir,
3054        edition,
3055        json_artifact_notifications,
3056        json_timings,
3057        json_unused_externs,
3058        json_future_incompat,
3059        pretty,
3060        working_dir,
3061        color,
3062        verbose,
3063        target_modifiers: collected_options.target_modifiers,
3064        mitigation_coverage_map: collected_options.mitigations,
3065        jobs,
3066    }
3067}
3068
3069fn parse_pretty(early_dcx: &EarlyDiagCtxt, unstable_opts: &UnstableOptions) -> Option<PpMode> {
3070    use PpMode::*;
3071
3072    let first = match unstable_opts.unpretty.as_deref()? {
3073        "normal" => Source(PpSourceMode::Normal),
3074        "expanded" => Source(PpSourceMode::Expanded),
3075        "expanded,identified" => Source(PpSourceMode::ExpandedIdentified),
3076        "expanded,hygiene" => Source(PpSourceMode::ExpandedHygiene),
3077        "ast-tree" => AstTree,
3078        "ast-tree,expanded" => AstTreeExpanded,
3079        "hir" => Hir(PpHirMode::Normal),
3080        "hir,identified" => Hir(PpHirMode::Identified),
3081        "hir,typed" => Hir(PpHirMode::Typed),
3082        "hir-tree" => HirTree,
3083        "thir-tree" => ThirTree,
3084        "thir-flat" => ThirFlat,
3085        "mir" => Mir,
3086        "stable-mir" => StableMir,
3087        "mir-cfg" => MirCFG,
3088        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!(
3089            "argument to `unpretty` must be one of `normal`, \
3090                            `expanded`, `expanded,identified`, `expanded,hygiene`, \
3091                            `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
3092                            `hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir`, `stable-mir`, or \
3093                            `mir-cfg`; got {name}"
3094        )),
3095    };
3096    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event /rustc-dev/0ed41eb4142dda2df61eb1145a312c1a9d62eb56/compiler/rustc_session/src/config.rs:3096",
                        "rustc_session::config", ::tracing::Level::DEBUG,
                        ::tracing_core::__macro_support::Option::Some("/rustc-dev/0ed41eb4142dda2df61eb1145a312c1a9d62eb56/compiler/rustc_session/src/config.rs"),
                        ::tracing_core::__macro_support::Option::Some(3096u32),
                        ::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:?}");
3097    Some(first)
3098}
3099
3100pub fn make_crate_type_option() -> RustcOptGroup {
3101    make_opt(
3102        OptionStability::Stable,
3103        OptionKind::Multi,
3104        "",
3105        "crate-type",
3106        "Comma separated list of types of crates
3107                                for the compiler to emit",
3108        "<bin|lib|rlib|dylib|cdylib|staticlib|proc-macro>",
3109    )
3110}
3111
3112pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> {
3113    let mut crate_types: Vec<CrateType> = Vec::new();
3114    for unparsed_crate_type in &list_list {
3115        for part in unparsed_crate_type.split(',') {
3116            let new_part = match part {
3117                "lib" => CrateType::default(),
3118                "rlib" => CrateType::Rlib,
3119                "staticlib" => CrateType::StaticLib,
3120                "dylib" => CrateType::Dylib,
3121                "cdylib" => CrateType::Cdylib,
3122                "bin" => CrateType::Executable,
3123                "proc-macro" => CrateType::ProcMacro,
3124                "sdylib" => CrateType::Sdylib,
3125                _ => {
3126                    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!(
3127                        "unknown crate type: `{part}`, expected one of: \
3128                        `lib`, `rlib`, `staticlib`, `dylib`, `cdylib`, `bin`, `proc-macro`",
3129                    ));
3130                }
3131            };
3132            if !crate_types.contains(&new_part) {
3133                crate_types.push(new_part)
3134            }
3135        }
3136    }
3137
3138    Ok(crate_types)
3139}
3140
3141pub mod nightly_options {
3142    use rustc_feature::UnstableFeatures;
3143
3144    use super::{OptionStability, RustcOptGroup};
3145    use crate::EarlyDiagCtxt;
3146
3147    pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
3148        match_is_nightly_build(matches)
3149            && matches.opt_strs("Z").iter().any(|x| *x == "unstable-options")
3150    }
3151
3152    pub fn match_is_nightly_build(matches: &getopts::Matches) -> bool {
3153        is_nightly_build(matches.opt_str("crate-name").as_deref())
3154    }
3155
3156    fn is_nightly_build(krate: Option<&str>) -> bool {
3157        UnstableFeatures::from_environment(krate).is_nightly_build()
3158    }
3159
3160    pub fn check_nightly_options(
3161        early_dcx: &EarlyDiagCtxt,
3162        matches: &getopts::Matches,
3163        flags: &[RustcOptGroup],
3164    ) {
3165        let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options");
3166        let really_allows_unstable_options = match_is_nightly_build(matches);
3167        let mut nightly_options_on_stable = 0;
3168
3169        for opt in flags.iter() {
3170            if opt.stability == OptionStability::Stable {
3171                continue;
3172            }
3173            if !matches.opt_present(opt.name) {
3174                continue;
3175            }
3176            if opt.name != "Z" && !has_z_unstable_option {
3177                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!(
3178                    "the `-Z unstable-options` flag must also be passed to enable \
3179                         the flag `{}`",
3180                    opt.name
3181                ));
3182            }
3183            if really_allows_unstable_options {
3184                continue;
3185            }
3186            match opt.stability {
3187                OptionStability::Unstable => {
3188                    nightly_options_on_stable += 1;
3189                    let msg = ::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("the option `{0}` is only accepted on the nightly compiler",
                opt.name))
    })format!(
3190                        "the option `{}` is only accepted on the nightly compiler",
3191                        opt.name
3192                    );
3193                    // The non-zero nightly_options_on_stable will force an early_fatal eventually.
3194                    let _ = early_dcx.early_err(msg);
3195                }
3196                OptionStability::Stable => {}
3197            }
3198        }
3199        if nightly_options_on_stable > 0 {
3200            early_dcx
3201                .early_help("consider switching to a nightly toolchain: `rustup default nightly`");
3202            early_dcx.early_note("selecting a toolchain with `+toolchain` arguments require a rustup proxy; see <https://rust-lang.github.io/rustup/concepts/index.html>");
3203            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>");
3204            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!(
3205                "{} nightly option{} were parsed",
3206                nightly_options_on_stable,
3207                if nightly_options_on_stable > 1 { "s" } else { "" }
3208            ));
3209        }
3210    }
3211}
3212
3213#[derive(#[automatically_derived]
impl ::core::marker::Copy for PpSourceMode { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for PpSourceMode { }
#[automatically_derived]
impl ::core::clone::Clone for PpSourceMode {
    #[inline]
    fn clone(&self) -> PpSourceMode { *self }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for PpSourceMode { }
#[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)]
3214pub enum PpSourceMode {
3215    /// `-Zunpretty=normal`
3216    Normal,
3217    /// `-Zunpretty=expanded`
3218    Expanded,
3219    /// `-Zunpretty=expanded,identified`
3220    ExpandedIdentified,
3221    /// `-Zunpretty=expanded,hygiene`
3222    ExpandedHygiene,
3223}
3224
3225#[derive(#[automatically_derived]
impl ::core::marker::Copy for PpHirMode { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for PpHirMode { }
#[automatically_derived]
impl ::core::clone::Clone for PpHirMode {
    #[inline]
    fn clone(&self) -> PpHirMode { *self }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for PpHirMode { }
#[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)]
3226pub enum PpHirMode {
3227    /// `-Zunpretty=hir`
3228    Normal,
3229    /// `-Zunpretty=hir,identified`
3230    Identified,
3231    /// `-Zunpretty=hir,typed`
3232    Typed,
3233}
3234
3235#[derive(#[automatically_derived]
impl ::core::marker::Copy for PpMode { }Copy, #[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for PpMode { }
#[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::marker::StructuralPartialEq for PpMode { }
#[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)]
3236/// Pretty print mode
3237pub enum PpMode {
3238    /// Options that print the source code, i.e.
3239    /// `-Zunpretty=normal` and `-Zunpretty=expanded`
3240    Source(PpSourceMode),
3241    /// `-Zunpretty=ast-tree`
3242    AstTree,
3243    /// `-Zunpretty=ast-tree,expanded`
3244    AstTreeExpanded,
3245    /// Options that print the HIR, i.e. `-Zunpretty=hir`
3246    Hir(PpHirMode),
3247    /// `-Zunpretty=hir-tree`
3248    HirTree,
3249    /// `-Zunpretty=thir-tree`
3250    ThirTree,
3251    /// `-Zunpretty=thir-flat`
3252    ThirFlat,
3253    /// `-Zunpretty=mir`
3254    Mir,
3255    /// `-Zunpretty=mir-cfg`
3256    MirCFG,
3257    /// `-Zunpretty=stable-mir`
3258    StableMir,
3259}
3260
3261impl PpMode {
3262    pub fn needs_ast_map(&self) -> bool {
3263        use PpMode::*;
3264        use PpSourceMode::*;
3265        match *self {
3266            Source(Normal) | AstTree => false,
3267
3268            Source(Expanded | ExpandedIdentified | ExpandedHygiene)
3269            | AstTreeExpanded
3270            | Hir(_)
3271            | HirTree
3272            | ThirTree
3273            | ThirFlat
3274            | Mir
3275            | MirCFG
3276            | StableMir => true,
3277        }
3278    }
3279
3280    pub fn needs_analysis(&self) -> bool {
3281        use PpMode::*;
3282        #[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)
3283    }
3284}
3285
3286#[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::marker::StructuralPartialEq for WasiExecModel { }
#[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)]
3287pub enum WasiExecModel {
3288    Command,
3289    Reactor,
3290}
3291
3292/// Command-line arguments passed to the compiler have to be incorporated with
3293/// the dependency tracking system for incremental compilation. This module
3294/// provides some utilities to make this more convenient.
3295///
3296/// The values of all command-line arguments that are relevant for dependency
3297/// tracking are hashed into a single value that determines whether the
3298/// incremental compilation cache can be re-used or not. This hashing is done
3299/// via the `DepTrackingHash` trait defined below, since the standard `Hash`
3300/// implementation might not be suitable (e.g., arguments are stored in a `Vec`,
3301/// the hash of which is order dependent, but we might not want the order of
3302/// arguments to make a difference for the hash).
3303///
3304/// However, since the value provided by `Hash::hash` often *is* suitable,
3305/// especially for primitive types, there is the
3306/// `impl_dep_tracking_hash_via_hash!()` macro that allows to simply reuse the
3307/// `Hash` implementation for `DepTrackingHash`. It's important though that
3308/// we have an opt-in scheme here, so one is hopefully forced to think about
3309/// how the hash should be calculated when adding a new command-line argument.
3310pub(crate) mod dep_tracking {
3311    use std::collections::BTreeMap;
3312    use std::hash::Hash;
3313    use std::num::NonZero;
3314    use std::path::PathBuf;
3315
3316    use rustc_abi::Align;
3317    use rustc_ast::attr::version::RustcVersion;
3318    use rustc_data_structures::fx::FxIndexMap;
3319    use rustc_data_structures::stable_hash::StableHasher;
3320    use rustc_errors::LanguageIdentifier;
3321    use rustc_feature::UnstableFeatures;
3322    use rustc_hashes::Hash64;
3323    use rustc_span::edition::Edition;
3324    use rustc_span::{RealFileName, RemapPathScopeComponents};
3325    use rustc_structures::CollapseMacroDebuginfo;
3326    use rustc_target::spec::{
3327        CodeModel, FramePointer, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel,
3328        RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility, TargetTuple,
3329        TlsModel,
3330    };
3331
3332    use super::{
3333        AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CodegenRetagOptions,
3334        CoverageOptions, CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug,
3335        FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentMcount,
3336        InstrumentMcountOpts, InstrumentXRay, LinkerPluginLto, LocationDetail, LtoCli,
3337        MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, OutFileName, OutputType,
3338        OutputTypes, PatchableFunctionEntry, PointerAuthOption, Polonius, ResolveDocLinks,
3339        SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
3340        WasiExecModel,
3341    };
3342    use crate::lint;
3343    use crate::utils::NativeLib;
3344
3345    pub(crate) trait DepTrackingHash {
3346        fn hash(
3347            &self,
3348            hasher: &mut StableHasher,
3349            error_format: ErrorOutputType,
3350            for_crate_hash: bool,
3351        );
3352    }
3353
3354    macro_rules! impl_dep_tracking_hash_via_hash {
3355        ($($t:ty),+ $(,)?) => {$(
3356            impl DepTrackingHash for $t {
3357                fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType, _for_crate_hash: bool) {
3358                    Hash::hash(self, hasher);
3359                }
3360            }
3361        )+};
3362    }
3363
3364    impl<T: DepTrackingHash> DepTrackingHash for Option<T> {
3365        fn hash(
3366            &self,
3367            hasher: &mut StableHasher,
3368            error_format: ErrorOutputType,
3369            for_crate_hash: bool,
3370        ) {
3371            match self {
3372                Some(x) => {
3373                    Hash::hash(&1, hasher);
3374                    DepTrackingHash::hash(x, hasher, error_format, for_crate_hash);
3375                }
3376                None => Hash::hash(&0, hasher),
3377            }
3378        }
3379    }
3380
3381    impl DepTrackingHash for () {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for AnnotateMoves {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for AutoDiff {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for Offload {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for bool {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for usize {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for NonZero<usize> {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for u64 {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for Hash64 {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for String {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for PathBuf {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for lint::Level {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for WasiExecModel {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for u32 {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for FramePointer {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for RelocModel {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for CodeModel {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for TlsModel {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for InstrumentCoverage {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for CoverageOptions {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for InstrumentMcount {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for InstrumentMcountOpts {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for InstrumentXRay {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for CrateType {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for MergeFunctions {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for OnBrokenPipe {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for PanicStrategy {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for RelroLevel {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for OptLevel {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for LtoCli {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for DebugInfo {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for DebugInfoCompression {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for MirStripDebugInfo {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for CollapseMacroDebuginfo {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for UnstableFeatures {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for NativeLib {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for SanitizerSet {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for CFGuard {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for CFProtection {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for TargetTuple {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for Edition {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for LinkerPluginLto {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for ResolveDocLinks {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for SplitDebuginfo {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for SplitDwarfKind {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for StackProtector {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for SwitchWithOptPath {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for SymbolManglingVersion {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for SymbolVisibility {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for RemapPathScopeComponents {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for SourceFileHashAlgorithm {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for OutFileName {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for OutputType {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for RealFileName {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for LocationDetail {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for FmtDebug {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for BranchProtection {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for LanguageIdentifier {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for NextSolverConfig {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for PatchableFunctionEntry {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for Polonius {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for InliningThreshold {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for FunctionReturn {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for Align {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for CodegenRetagOptions {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
impl DepTrackingHash for RustcVersion {
    fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
        _for_crate_hash: bool) {
        Hash::hash(self, hasher);
    }
}
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!(
3382        (),
3383        AnnotateMoves,
3384        AutoDiff,
3385        Offload,
3386        bool,
3387        usize,
3388        NonZero<usize>,
3389        u64,
3390        Hash64,
3391        String,
3392        PathBuf,
3393        lint::Level,
3394        WasiExecModel,
3395        u32,
3396        FramePointer,
3397        RelocModel,
3398        CodeModel,
3399        TlsModel,
3400        InstrumentCoverage,
3401        CoverageOptions,
3402        InstrumentMcount,
3403        InstrumentMcountOpts,
3404        InstrumentXRay,
3405        CrateType,
3406        MergeFunctions,
3407        OnBrokenPipe,
3408        PanicStrategy,
3409        RelroLevel,
3410        OptLevel,
3411        LtoCli,
3412        DebugInfo,
3413        DebugInfoCompression,
3414        MirStripDebugInfo,
3415        CollapseMacroDebuginfo,
3416        UnstableFeatures,
3417        NativeLib,
3418        SanitizerSet,
3419        CFGuard,
3420        CFProtection,
3421        TargetTuple,
3422        Edition,
3423        LinkerPluginLto,
3424        ResolveDocLinks,
3425        SplitDebuginfo,
3426        SplitDwarfKind,
3427        StackProtector,
3428        SwitchWithOptPath,
3429        SymbolManglingVersion,
3430        SymbolVisibility,
3431        RemapPathScopeComponents,
3432        SourceFileHashAlgorithm,
3433        OutFileName,
3434        OutputType,
3435        RealFileName,
3436        LocationDetail,
3437        FmtDebug,
3438        BranchProtection,
3439        LanguageIdentifier,
3440        NextSolverConfig,
3441        PatchableFunctionEntry,
3442        Polonius,
3443        InliningThreshold,
3444        FunctionReturn,
3445        Align,
3446        CodegenRetagOptions,
3447        RustcVersion,
3448        PointerAuthOption,
3449    );
3450
3451    impl<T1, T2> DepTrackingHash for (T1, T2)
3452    where
3453        T1: DepTrackingHash,
3454        T2: DepTrackingHash,
3455    {
3456        fn hash(
3457            &self,
3458            hasher: &mut StableHasher,
3459            error_format: ErrorOutputType,
3460            for_crate_hash: bool,
3461        ) {
3462            Hash::hash(&0, hasher);
3463            DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash);
3464            Hash::hash(&1, hasher);
3465            DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash);
3466        }
3467    }
3468
3469    impl<T1, T2, T3> DepTrackingHash for (T1, T2, T3)
3470    where
3471        T1: DepTrackingHash,
3472        T2: DepTrackingHash,
3473        T3: DepTrackingHash,
3474    {
3475        fn hash(
3476            &self,
3477            hasher: &mut StableHasher,
3478            error_format: ErrorOutputType,
3479            for_crate_hash: bool,
3480        ) {
3481            Hash::hash(&0, hasher);
3482            DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash);
3483            Hash::hash(&1, hasher);
3484            DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash);
3485            Hash::hash(&2, hasher);
3486            DepTrackingHash::hash(&self.2, hasher, error_format, for_crate_hash);
3487        }
3488    }
3489
3490    impl<T: DepTrackingHash> DepTrackingHash for Vec<T> {
3491        fn hash(
3492            &self,
3493            hasher: &mut StableHasher,
3494            error_format: ErrorOutputType,
3495            for_crate_hash: bool,
3496        ) {
3497            Hash::hash(&self.len(), hasher);
3498            for (index, elem) in self.iter().enumerate() {
3499                Hash::hash(&index, hasher);
3500                DepTrackingHash::hash(elem, hasher, error_format, for_crate_hash);
3501            }
3502        }
3503    }
3504
3505    impl<T: DepTrackingHash, V: DepTrackingHash> DepTrackingHash for FxIndexMap<T, V> {
3506        fn hash(
3507            &self,
3508            hasher: &mut StableHasher,
3509            error_format: ErrorOutputType,
3510            for_crate_hash: bool,
3511        ) {
3512            Hash::hash(&self.len(), hasher);
3513            for (key, value) in self.iter() {
3514                DepTrackingHash::hash(key, hasher, error_format, for_crate_hash);
3515                DepTrackingHash::hash(value, hasher, error_format, for_crate_hash);
3516            }
3517        }
3518    }
3519
3520    impl DepTrackingHash for OutputTypes {
3521        fn hash(
3522            &self,
3523            hasher: &mut StableHasher,
3524            error_format: ErrorOutputType,
3525            for_crate_hash: bool,
3526        ) {
3527            Hash::hash(&self.0.len(), hasher);
3528            for (key, val) in &self.0 {
3529                DepTrackingHash::hash(key, hasher, error_format, for_crate_hash);
3530                if !for_crate_hash {
3531                    DepTrackingHash::hash(val, hasher, error_format, for_crate_hash);
3532                }
3533            }
3534        }
3535    }
3536
3537    // This is a stable hash because BTreeMap is a sorted container
3538    pub(crate) fn stable_hash(
3539        sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>,
3540        hasher: &mut StableHasher,
3541        error_format: ErrorOutputType,
3542        for_crate_hash: bool,
3543    ) {
3544        for (key, sub_hash) in sub_hashes {
3545            // Using Hash::hash() instead of DepTrackingHash::hash() is fine for
3546            // the keys, as they are just plain strings
3547            Hash::hash(&key.len(), hasher);
3548            Hash::hash(key, hasher);
3549            sub_hash.hash(hasher, error_format, for_crate_hash);
3550        }
3551    }
3552}
3553
3554/// How to run proc-macro code when building this crate
3555#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for ProcMacroExecutionStrategy { }
#[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::marker::StructuralPartialEq for ProcMacroExecutionStrategy { }
#[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)]
3556pub enum ProcMacroExecutionStrategy {
3557    /// Run the proc-macro code on the same thread as the server.
3558    SameThread,
3559
3560    /// Run the proc-macro code on a different thread.
3561    CrossThread,
3562}
3563
3564/// Which format to use for `-Z dump-mono-stats`
3565#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for DumpMonoStatsFormat { }
#[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::marker::StructuralPartialEq for DumpMonoStatsFormat { }
#[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)]
3566pub enum DumpMonoStatsFormat {
3567    /// Pretty-print a markdown table
3568    Markdown,
3569    /// Emit structured JSON
3570    Json,
3571}
3572
3573impl DumpMonoStatsFormat {
3574    pub fn extension(self) -> &'static str {
3575        match self {
3576            Self::Markdown => "md",
3577            Self::Json => "json",
3578        }
3579    }
3580}
3581
3582/// `-Z patchable-function-entry` representation - how many nops to put before and after function
3583/// entry.
3584#[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::marker::StructuralPartialEq for PatchableFunctionEntry { }
#[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)]
3585pub struct PatchableFunctionEntry {
3586    /// Nops before the entry
3587    prefix: u8,
3588    /// Nops after the entry
3589    entry: u8,
3590    /// An optional section name to record the entry location
3591    section: Option<String>,
3592}
3593
3594impl PatchableFunctionEntry {
3595    pub fn from_parts(
3596        total_nops: u8,
3597        prefix_nops: u8,
3598        section: Option<String>,
3599    ) -> Option<PatchableFunctionEntry> {
3600        if total_nops < prefix_nops {
3601            None
3602        // Section name cannot contain null characters.
3603        } else if section.as_ref().map(|x| x.contains('\0') || x.is_empty()).unwrap_or(false) {
3604            None
3605        } else {
3606            Some(Self { prefix: prefix_nops, entry: total_nops - prefix_nops, section })
3607        }
3608    }
3609    pub fn prefix(&self) -> u8 {
3610        self.prefix
3611    }
3612    pub fn entry(&self) -> u8 {
3613        self.entry
3614    }
3615    pub fn section(&self) -> Option<&str> {
3616        self.section.as_ref().map(|x| x.as_str())
3617    }
3618}
3619
3620/// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy,
3621/// or future prototype.
3622#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for Polonius { }
#[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::marker::StructuralPartialEq for Polonius { }
#[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)]
3623pub enum Polonius {
3624    /// Polonius is disabled, only use NLL.
3625    Off,
3626
3627    /// Legacy version, using datalog and the `polonius-engine` crate. Historical value for `-Zpolonius`.
3628    Legacy,
3629
3630    /// In-tree prototype, extending the NLL infrastructure.
3631    Next,
3632}
3633
3634impl Default for Polonius {
3635    fn default() -> Self {
3636        Self::DEFAULT
3637    }
3638}
3639
3640impl Polonius {
3641    pub(crate) const DEFAULT: Self =
3642        if ::core::option::Option::Some("1")option_env!("CFG_DEFAULT_POLONIUS_NEXT").is_some() { Self::Next } else { Self::Off };
3643
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]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for InliningThreshold { }
#[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::marker::StructuralPartialEq for InliningThreshold { }
#[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]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for FunctionReturn { }
#[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::marker::StructuralPartialEq for FunctionReturn { }
#[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]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for MirIncludeSpans { }
#[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::marker::StructuralPartialEq for MirIncludeSpans { }
#[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}