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