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