1use std::collections::btree_map::{
5 Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
6};
7use std::collections::{BTreeMap, BTreeSet};
8use std::ffi::OsStr;
9use std::hash::Hash;
10use std::path::{Path, PathBuf};
11use std::str::{self, FromStr};
12use std::sync::LazyLock;
13use std::{cmp, fs, iter};
14
15use externs::{ExternOpt, split_extern_opt};
16use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
17use rustc_data_structures::stable_hasher::{StableHasher, StableOrd, ToStableHashKey};
18use rustc_errors::emitter::HumanReadableErrorType;
19use rustc_errors::{ColorConfig, DiagCtxtFlags};
20use rustc_feature::UnstableFeatures;
21use rustc_hashes::Hash64;
22use rustc_macros::{BlobDecodable, Decodable, Encodable, HashStable_Generic};
23use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION};
24use rustc_span::source_map::FilePathMapping;
25use rustc_span::{
26 FileName, HashStableContext, RealFileName, RemapPathScopeComponents, SourceFileHashAlgorithm,
27 Symbol, sym,
28};
29use rustc_target::spec::{
30 FramePointer, LinkSelfContainedComponents, LinkerFeatures, PanicStrategy, SplitDebuginfo,
31 Target, TargetTuple,
32};
33use tracing::debug;
34
35pub use crate::config::cfg::{Cfg, CheckCfg, ExpectedValues};
36use crate::config::native_libs::parse_native_libs;
37pub use crate::config::print_request::{PrintKind, PrintRequest};
38use crate::errors::FileWriteFail;
39pub use crate::options::*;
40use crate::search_paths::SearchPath;
41use crate::utils::CanonicalizedPath;
42use crate::{EarlyDiagCtxt, Session, filesearch, lint};
43
44mod cfg;
45mod externs;
46mod native_libs;
47mod print_request;
48pub mod sigpipe;
49
50#[derive(#[automatically_derived]
impl ::core::clone::Clone for Strip {
#[inline]
fn clone(&self) -> Strip { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Strip { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for Strip {
#[inline]
fn eq(&self, other: &Strip) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for Strip {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Strip {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
Strip::None => "None",
Strip::Debuginfo => "Debuginfo",
Strip::Symbols => "Symbols",
})
}
}Debug)]
52pub enum Strip {
53 None,
55
56 Debuginfo,
58
59 Symbols,
61}
62
63#[derive(#[automatically_derived]
impl ::core::clone::Clone for CFGuard {
#[inline]
fn clone(&self) -> CFGuard { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CFGuard { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for CFGuard {
#[inline]
fn eq(&self, other: &CFGuard) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for CFGuard {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for CFGuard {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
CFGuard::Disabled => "Disabled",
CFGuard::NoChecks => "NoChecks",
CFGuard::Checks => "Checks",
})
}
}Debug)]
65pub enum CFGuard {
66 Disabled,
68
69 NoChecks,
71
72 Checks,
74}
75
76#[derive(#[automatically_derived]
impl ::core::clone::Clone for CFProtection {
#[inline]
fn clone(&self) -> CFProtection { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CFProtection { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for CFProtection {
#[inline]
fn eq(&self, other: &CFProtection) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for CFProtection {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for CFProtection {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
CFProtection::None => "None",
CFProtection::Branch => "Branch",
CFProtection::Return => "Return",
CFProtection::Full => "Full",
})
}
}Debug)]
78pub enum CFProtection {
79 None,
81
82 Branch,
84
85 Return,
87
88 Full,
90}
91
92#[derive(#[automatically_derived]
impl ::core::clone::Clone for OptLevel {
#[inline]
fn clone(&self) -> OptLevel { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for OptLevel { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for OptLevel {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
OptLevel::No => "No",
OptLevel::Less => "Less",
OptLevel::More => "More",
OptLevel::Aggressive => "Aggressive",
OptLevel::Size => "Size",
OptLevel::SizeMin => "SizeMin",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for OptLevel {
#[inline]
fn eq(&self, other: &OptLevel) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for OptLevel {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, const _: () =
{
impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
for OptLevel where __CTX: ::rustc_span::HashStableContext {
#[inline]
fn hash_stable(&self, __hcx: &mut __CTX,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
match *self {
OptLevel::No => {}
OptLevel::Less => {}
OptLevel::More => {}
OptLevel::Aggressive => {}
OptLevel::Size => {}
OptLevel::SizeMin => {}
}
}
}
};HashStable_Generic, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for OptLevel {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
OptLevel::No => { 0usize }
OptLevel::Less => { 1usize }
OptLevel::More => { 2usize }
OptLevel::Aggressive => { 3usize }
OptLevel::Size => { 4usize }
OptLevel::SizeMin => { 5usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
OptLevel::No => {}
OptLevel::Less => {}
OptLevel::More => {}
OptLevel::Aggressive => {}
OptLevel::Size => {}
OptLevel::SizeMin => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for OptLevel {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { OptLevel::No }
1usize => { OptLevel::Less }
2usize => { OptLevel::More }
3usize => { OptLevel::Aggressive }
4usize => { OptLevel::Size }
5usize => { OptLevel::SizeMin }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `OptLevel`, expected 0..6, actual {0}",
n));
}
}
}
}
};Decodable)]
93pub enum OptLevel {
94 No,
96 Less,
98 More,
100 Aggressive,
102 Size,
104 SizeMin,
106}
107
108#[derive(#[automatically_derived]
impl ::core::clone::Clone for Lto {
#[inline]
fn clone(&self) -> Lto {
match self {
Lto::No => Lto::No,
Lto::Thin => Lto::Thin,
Lto::ThinLocal => Lto::ThinLocal,
Lto::Fat => Lto::Fat,
}
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Lto {
#[inline]
fn eq(&self, other: &Lto) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for Lto {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
Lto::No => { 0usize }
Lto::Thin => { 1usize }
Lto::ThinLocal => { 2usize }
Lto::Fat => { 3usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
Lto::No => {}
Lto::Thin => {}
Lto::ThinLocal => {}
Lto::Fat => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for Lto {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { Lto::No }
1usize => { Lto::Thin }
2usize => { Lto::ThinLocal }
3usize => { Lto::Fat }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Lto`, expected 0..4, actual {0}",
n));
}
}
}
}
};Decodable)]
113pub enum Lto {
114 No,
116
117 Thin,
119
120 ThinLocal,
123
124 Fat,
126}
127
128#[derive(#[automatically_derived]
impl ::core::clone::Clone for LtoCli {
#[inline]
fn clone(&self) -> LtoCli { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for LtoCli { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for LtoCli {
#[inline]
fn eq(&self, other: &LtoCli) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for LtoCli {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for LtoCli {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
LtoCli::No => "No",
LtoCli::Yes => "Yes",
LtoCli::NoParam => "NoParam",
LtoCli::Thin => "Thin",
LtoCli::Fat => "Fat",
LtoCli::Unspecified => "Unspecified",
})
}
}Debug)]
130pub enum LtoCli {
131 No,
133 Yes,
135 NoParam,
137 Thin,
139 Fat,
141 Unspecified,
143}
144
145#[derive(#[automatically_derived]
impl ::core::clone::Clone for InstrumentCoverage {
#[inline]
fn clone(&self) -> InstrumentCoverage { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for InstrumentCoverage { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for InstrumentCoverage {
#[inline]
fn eq(&self, other: &InstrumentCoverage) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for InstrumentCoverage {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for InstrumentCoverage {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
InstrumentCoverage::No => "No",
InstrumentCoverage::Yes => "Yes",
})
}
}Debug)]
147pub enum InstrumentCoverage {
148 No,
150 Yes,
152}
153
154#[derive(#[automatically_derived]
impl ::core::clone::Clone for CoverageOptions {
#[inline]
fn clone(&self) -> CoverageOptions {
let _: ::core::clone::AssertParamIsClone<CoverageLevel>;
let _: ::core::clone::AssertParamIsClone<bool>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CoverageOptions { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for CoverageOptions {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"CoverageOptions", "level", &self.level,
"discard_all_spans_in_codegen",
&&self.discard_all_spans_in_codegen)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for CoverageOptions {
#[inline]
fn eq(&self, other: &CoverageOptions) -> bool {
self.discard_all_spans_in_codegen ==
other.discard_all_spans_in_codegen &&
self.level == other.level
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for CoverageOptions {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<CoverageLevel>;
let _: ::core::cmp::AssertParamIsEq<bool>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for CoverageOptions {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.level, state);
::core::hash::Hash::hash(&self.discard_all_spans_in_codegen, state)
}
}Hash, #[automatically_derived]
impl ::core::default::Default for CoverageOptions {
#[inline]
fn default() -> CoverageOptions {
CoverageOptions {
level: ::core::default::Default::default(),
discard_all_spans_in_codegen: ::core::default::Default::default(),
}
}
}Default)]
156pub struct CoverageOptions {
157 pub level: CoverageLevel,
158
159 pub discard_all_spans_in_codegen: bool,
165}
166
167#[derive(#[automatically_derived]
impl ::core::clone::Clone for CoverageLevel {
#[inline]
fn clone(&self) -> CoverageLevel { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CoverageLevel { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for CoverageLevel {
#[inline]
fn eq(&self, other: &CoverageLevel) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for CoverageLevel {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for CoverageLevel {
#[inline]
fn partial_cmp(&self, other: &CoverageLevel)
-> ::core::option::Option<::core::cmp::Ordering> {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::PartialOrd::partial_cmp(&__self_discr, &__arg1_discr)
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for CoverageLevel {
#[inline]
fn cmp(&self, other: &CoverageLevel) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
}
}Ord, #[automatically_derived]
impl ::core::hash::Hash for CoverageLevel {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for CoverageLevel {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
CoverageLevel::Block => "Block",
CoverageLevel::Branch => "Branch",
CoverageLevel::Condition => "Condition",
})
}
}Debug, #[automatically_derived]
impl ::core::default::Default for CoverageLevel {
#[inline]
fn default() -> CoverageLevel { Self::Block }
}Default)]
169pub enum CoverageLevel {
170 #[default]
172 Block,
173 Branch,
175 Condition,
191}
192
193#[derive(#[automatically_derived]
impl ::core::clone::Clone for Offload {
#[inline]
fn clone(&self) -> Offload {
match self {
Offload::Device => Offload::Device,
Offload::Host(__self_0) =>
Offload::Host(::core::clone::Clone::clone(__self_0)),
Offload::Test => Offload::Test,
}
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Offload {
#[inline]
fn eq(&self, other: &Offload) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(Offload::Host(__self_0), Offload::Host(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for Offload {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
Offload::Host(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
_ => {}
}
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Offload {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Offload::Device => ::core::fmt::Formatter::write_str(f, "Device"),
Offload::Host(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Host",
&__self_0),
Offload::Test => ::core::fmt::Formatter::write_str(f, "Test"),
}
}
}Debug, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for Offload {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
Offload::Device => { 0usize }
Offload::Host(ref __binding_0) => { 1usize }
Offload::Test => { 2usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
Offload::Device => {}
Offload::Host(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
Offload::Test => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for Offload {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { Offload::Device }
1usize => {
Offload::Host(::rustc_serialize::Decodable::decode(__decoder))
}
2usize => { Offload::Test }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Offload`, expected 0..3, actual {0}",
n));
}
}
}
}
};Decodable)]
195pub enum Offload {
196 Device,
198 Host(String),
200 Test,
202}
203
204#[derive(#[automatically_derived]
impl ::core::clone::Clone for AutoDiff {
#[inline]
fn clone(&self) -> AutoDiff {
match self {
AutoDiff::Enable => AutoDiff::Enable,
AutoDiff::PrintTA => AutoDiff::PrintTA,
AutoDiff::PrintTAFn(__self_0) =>
AutoDiff::PrintTAFn(::core::clone::Clone::clone(__self_0)),
AutoDiff::PrintAA => AutoDiff::PrintAA,
AutoDiff::PrintPerf => AutoDiff::PrintPerf,
AutoDiff::PrintSteps => AutoDiff::PrintSteps,
AutoDiff::PrintModBefore => AutoDiff::PrintModBefore,
AutoDiff::PrintModAfter => AutoDiff::PrintModAfter,
AutoDiff::PrintModFinal => AutoDiff::PrintModFinal,
AutoDiff::PrintPasses => AutoDiff::PrintPasses,
AutoDiff::NoPostopt => AutoDiff::NoPostopt,
AutoDiff::LooseTypes => AutoDiff::LooseTypes,
AutoDiff::Inline => AutoDiff::Inline,
AutoDiff::NoTT => AutoDiff::NoTT,
}
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for AutoDiff {
#[inline]
fn eq(&self, other: &AutoDiff) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(AutoDiff::PrintTAFn(__self_0), AutoDiff::PrintTAFn(__arg1_0))
=> __self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for AutoDiff {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
AutoDiff::PrintTAFn(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
_ => {}
}
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for AutoDiff {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
AutoDiff::Enable =>
::core::fmt::Formatter::write_str(f, "Enable"),
AutoDiff::PrintTA =>
::core::fmt::Formatter::write_str(f, "PrintTA"),
AutoDiff::PrintTAFn(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"PrintTAFn", &__self_0),
AutoDiff::PrintAA =>
::core::fmt::Formatter::write_str(f, "PrintAA"),
AutoDiff::PrintPerf =>
::core::fmt::Formatter::write_str(f, "PrintPerf"),
AutoDiff::PrintSteps =>
::core::fmt::Formatter::write_str(f, "PrintSteps"),
AutoDiff::PrintModBefore =>
::core::fmt::Formatter::write_str(f, "PrintModBefore"),
AutoDiff::PrintModAfter =>
::core::fmt::Formatter::write_str(f, "PrintModAfter"),
AutoDiff::PrintModFinal =>
::core::fmt::Formatter::write_str(f, "PrintModFinal"),
AutoDiff::PrintPasses =>
::core::fmt::Formatter::write_str(f, "PrintPasses"),
AutoDiff::NoPostopt =>
::core::fmt::Formatter::write_str(f, "NoPostopt"),
AutoDiff::LooseTypes =>
::core::fmt::Formatter::write_str(f, "LooseTypes"),
AutoDiff::Inline =>
::core::fmt::Formatter::write_str(f, "Inline"),
AutoDiff::NoTT => ::core::fmt::Formatter::write_str(f, "NoTT"),
}
}
}Debug, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for AutoDiff {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
AutoDiff::Enable => { 0usize }
AutoDiff::PrintTA => { 1usize }
AutoDiff::PrintTAFn(ref __binding_0) => { 2usize }
AutoDiff::PrintAA => { 3usize }
AutoDiff::PrintPerf => { 4usize }
AutoDiff::PrintSteps => { 5usize }
AutoDiff::PrintModBefore => { 6usize }
AutoDiff::PrintModAfter => { 7usize }
AutoDiff::PrintModFinal => { 8usize }
AutoDiff::PrintPasses => { 9usize }
AutoDiff::NoPostopt => { 10usize }
AutoDiff::LooseTypes => { 11usize }
AutoDiff::Inline => { 12usize }
AutoDiff::NoTT => { 13usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
AutoDiff::Enable => {}
AutoDiff::PrintTA => {}
AutoDiff::PrintTAFn(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
AutoDiff::PrintAA => {}
AutoDiff::PrintPerf => {}
AutoDiff::PrintSteps => {}
AutoDiff::PrintModBefore => {}
AutoDiff::PrintModAfter => {}
AutoDiff::PrintModFinal => {}
AutoDiff::PrintPasses => {}
AutoDiff::NoPostopt => {}
AutoDiff::LooseTypes => {}
AutoDiff::Inline => {}
AutoDiff::NoTT => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for AutoDiff {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { AutoDiff::Enable }
1usize => { AutoDiff::PrintTA }
2usize => {
AutoDiff::PrintTAFn(::rustc_serialize::Decodable::decode(__decoder))
}
3usize => { AutoDiff::PrintAA }
4usize => { AutoDiff::PrintPerf }
5usize => { AutoDiff::PrintSteps }
6usize => { AutoDiff::PrintModBefore }
7usize => { AutoDiff::PrintModAfter }
8usize => { AutoDiff::PrintModFinal }
9usize => { AutoDiff::PrintPasses }
10usize => { AutoDiff::NoPostopt }
11usize => { AutoDiff::LooseTypes }
12usize => { AutoDiff::Inline }
13usize => { AutoDiff::NoTT }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `AutoDiff`, expected 0..14, actual {0}",
n));
}
}
}
}
};Decodable)]
206pub enum AutoDiff {
207 Enable,
209
210 PrintTA,
212 PrintTAFn(String),
214 PrintAA,
216 PrintPerf,
218 PrintSteps,
220 PrintModBefore,
222 PrintModAfter,
224 PrintModFinal,
226
227 PrintPasses,
229 NoPostopt,
231 LooseTypes,
234 Inline,
236 NoTT,
238}
239
240#[derive(#[automatically_derived]
impl ::core::clone::Clone for AnnotateMoves {
#[inline]
fn clone(&self) -> AnnotateMoves {
let _: ::core::clone::AssertParamIsClone<Option<u64>>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for AnnotateMoves { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for AnnotateMoves {
#[inline]
fn eq(&self, other: &AnnotateMoves) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(AnnotateMoves::Enabled(__self_0),
AnnotateMoves::Enabled(__arg1_0)) => __self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for AnnotateMoves {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
AnnotateMoves::Enabled(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
_ => {}
}
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for AnnotateMoves {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
AnnotateMoves::Disabled =>
::core::fmt::Formatter::write_str(f, "Disabled"),
AnnotateMoves::Enabled(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Enabled", &__self_0),
}
}
}Debug)]
242pub enum AnnotateMoves {
243 Disabled,
245 Enabled(Option<u64>),
248}
249
250#[derive(#[automatically_derived]
impl ::core::clone::Clone for InstrumentXRay {
#[inline]
fn clone(&self) -> InstrumentXRay {
let _: ::core::clone::AssertParamIsClone<bool>;
let _: ::core::clone::AssertParamIsClone<Option<usize>>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for InstrumentXRay { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for InstrumentXRay {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let names: &'static _ =
&["always", "never", "ignore_loops", "instruction_threshold",
"skip_entry", "skip_exit"];
let values: &[&dyn ::core::fmt::Debug] =
&[&self.always, &self.never, &self.ignore_loops,
&self.instruction_threshold, &self.skip_entry,
&&self.skip_exit];
::core::fmt::Formatter::debug_struct_fields_finish(f,
"InstrumentXRay", names, values)
}
}Debug, #[automatically_derived]
impl ::core::default::Default for InstrumentXRay {
#[inline]
fn default() -> InstrumentXRay {
InstrumentXRay {
always: ::core::default::Default::default(),
never: ::core::default::Default::default(),
ignore_loops: ::core::default::Default::default(),
instruction_threshold: ::core::default::Default::default(),
skip_entry: ::core::default::Default::default(),
skip_exit: ::core::default::Default::default(),
}
}
}Default, #[automatically_derived]
impl ::core::cmp::PartialEq for InstrumentXRay {
#[inline]
fn eq(&self, other: &InstrumentXRay) -> bool {
self.always == other.always && self.never == other.never &&
self.ignore_loops == other.ignore_loops &&
self.skip_entry == other.skip_entry &&
self.skip_exit == other.skip_exit &&
self.instruction_threshold == other.instruction_threshold
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for InstrumentXRay {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<bool>;
let _: ::core::cmp::AssertParamIsEq<Option<usize>>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for InstrumentXRay {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.always, state);
::core::hash::Hash::hash(&self.never, state);
::core::hash::Hash::hash(&self.ignore_loops, state);
::core::hash::Hash::hash(&self.instruction_threshold, state);
::core::hash::Hash::hash(&self.skip_entry, state);
::core::hash::Hash::hash(&self.skip_exit, state)
}
}Hash)]
252pub struct InstrumentXRay {
253 pub always: bool,
255 pub never: bool,
257 pub ignore_loops: bool,
260 pub instruction_threshold: Option<usize>,
263 pub skip_entry: bool,
265 pub skip_exit: bool,
267}
268
269#[derive(#[automatically_derived]
impl ::core::clone::Clone for LinkerPluginLto {
#[inline]
fn clone(&self) -> LinkerPluginLto {
match self {
LinkerPluginLto::LinkerPlugin(__self_0) =>
LinkerPluginLto::LinkerPlugin(::core::clone::Clone::clone(__self_0)),
LinkerPluginLto::LinkerPluginAuto =>
LinkerPluginLto::LinkerPluginAuto,
LinkerPluginLto::Disabled => LinkerPluginLto::Disabled,
}
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for LinkerPluginLto {
#[inline]
fn eq(&self, other: &LinkerPluginLto) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(LinkerPluginLto::LinkerPlugin(__self_0),
LinkerPluginLto::LinkerPlugin(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for LinkerPluginLto {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
LinkerPluginLto::LinkerPlugin(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
_ => {}
}
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for LinkerPluginLto {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
LinkerPluginLto::LinkerPlugin(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"LinkerPlugin", &__self_0),
LinkerPluginLto::LinkerPluginAuto =>
::core::fmt::Formatter::write_str(f, "LinkerPluginAuto"),
LinkerPluginLto::Disabled =>
::core::fmt::Formatter::write_str(f, "Disabled"),
}
}
}Debug)]
270pub enum LinkerPluginLto {
271 LinkerPlugin(PathBuf),
272 LinkerPluginAuto,
273 Disabled,
274}
275
276impl LinkerPluginLto {
277 pub fn enabled(&self) -> bool {
278 match *self {
279 LinkerPluginLto::LinkerPlugin(_) | LinkerPluginLto::LinkerPluginAuto => true,
280 LinkerPluginLto::Disabled => false,
281 }
282 }
283}
284
285#[derive(#[automatically_derived]
impl ::core::default::Default for LinkSelfContained {
#[inline]
fn default() -> LinkSelfContained {
LinkSelfContained {
explicitly_set: ::core::default::Default::default(),
enabled_components: ::core::default::Default::default(),
disabled_components: ::core::default::Default::default(),
}
}
}Default, #[automatically_derived]
impl ::core::clone::Clone for LinkSelfContained {
#[inline]
fn clone(&self) -> LinkSelfContained {
LinkSelfContained {
explicitly_set: ::core::clone::Clone::clone(&self.explicitly_set),
enabled_components: ::core::clone::Clone::clone(&self.enabled_components),
disabled_components: ::core::clone::Clone::clone(&self.disabled_components),
}
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for LinkSelfContained {
#[inline]
fn eq(&self, other: &LinkSelfContained) -> bool {
self.explicitly_set == other.explicitly_set &&
self.enabled_components == other.enabled_components &&
self.disabled_components == other.disabled_components
}
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for LinkSelfContained {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"LinkSelfContained", "explicitly_set", &self.explicitly_set,
"enabled_components", &self.enabled_components,
"disabled_components", &&self.disabled_components)
}
}Debug)]
301pub struct LinkSelfContained {
302 pub explicitly_set: Option<bool>,
305
306 enabled_components: LinkSelfContainedComponents,
309
310 disabled_components: LinkSelfContainedComponents,
313}
314
315impl LinkSelfContained {
316 pub(crate) fn handle_cli_component(&mut self, component: &str) -> Option<()> {
319 if let Some(component_to_enable) = component.strip_prefix('+') {
324 self.explicitly_set = None;
325 self.enabled_components
326 .insert(LinkSelfContainedComponents::from_str(component_to_enable).ok()?);
327 Some(())
328 } else if let Some(component_to_disable) = component.strip_prefix('-') {
329 self.explicitly_set = None;
330 self.disabled_components
331 .insert(LinkSelfContainedComponents::from_str(component_to_disable).ok()?);
332 Some(())
333 } else {
334 None
335 }
336 }
337
338 pub(crate) fn set_all_explicitly(&mut self, enabled: bool) {
341 self.explicitly_set = Some(enabled);
342
343 if enabled {
344 self.enabled_components = LinkSelfContainedComponents::all();
345 self.disabled_components = LinkSelfContainedComponents::empty();
346 } else {
347 self.enabled_components = LinkSelfContainedComponents::empty();
348 self.disabled_components = LinkSelfContainedComponents::all();
349 }
350 }
351
352 pub fn on() -> Self {
354 let mut on = LinkSelfContained::default();
355 on.set_all_explicitly(true);
356 on
357 }
358
359 fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
363 if self.explicitly_set.is_some() {
364 return Ok(());
365 }
366
367 let has_minus_linker = self.disabled_components.is_linker_enabled();
369 if has_minus_linker && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
370 return Err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`-C link-self-contained=-linker` is unstable on the `{0}` target. The `-Z unstable-options` flag must also be passed to use it on this target",
target_tuple))
})format!(
371 "`-C link-self-contained=-linker` is unstable on the `{target_tuple}` \
372 target. The `-Z unstable-options` flag must also be passed to use it on this target",
373 ));
374 }
375
376 let unstable_enabled = self.enabled_components;
378 let unstable_disabled = self.disabled_components - LinkSelfContainedComponents::LINKER;
379 if !unstable_enabled.union(unstable_disabled).is_empty() {
380 return Err(String::from(
381 "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` \
382 are stable, the `-Z unstable-options` flag must also be passed to use \
383 the unstable values",
384 ));
385 }
386
387 Ok(())
388 }
389
390 pub fn is_linker_enabled(&self) -> bool {
393 self.enabled_components.contains(LinkSelfContainedComponents::LINKER)
394 }
395
396 pub fn is_linker_disabled(&self) -> bool {
399 self.disabled_components.contains(LinkSelfContainedComponents::LINKER)
400 }
401
402 fn check_consistency(&self) -> Option<LinkSelfContainedComponents> {
405 if self.explicitly_set.is_some() {
406 None
407 } else {
408 let common = self.enabled_components.intersection(self.disabled_components);
409 if common.is_empty() { None } else { Some(common) }
410 }
411 }
412}
413
414#[derive(#[automatically_derived]
impl ::core::default::Default for LinkerFeaturesCli {
#[inline]
fn default() -> LinkerFeaturesCli {
LinkerFeaturesCli {
enabled: ::core::default::Default::default(),
disabled: ::core::default::Default::default(),
}
}
}Default, #[automatically_derived]
impl ::core::marker::Copy for LinkerFeaturesCli { }Copy, #[automatically_derived]
impl ::core::clone::Clone for LinkerFeaturesCli {
#[inline]
fn clone(&self) -> LinkerFeaturesCli {
let _: ::core::clone::AssertParamIsClone<LinkerFeatures>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for LinkerFeaturesCli {
#[inline]
fn eq(&self, other: &LinkerFeaturesCli) -> bool {
self.enabled == other.enabled && self.disabled == other.disabled
}
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for LinkerFeaturesCli {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"LinkerFeaturesCli", "enabled", &self.enabled, "disabled",
&&self.disabled)
}
}Debug)]
423pub struct LinkerFeaturesCli {
424 pub enabled: LinkerFeatures,
426
427 pub disabled: LinkerFeatures,
429}
430
431impl LinkerFeaturesCli {
432 pub(crate) fn handle_cli_feature(&mut self, feature: &str) -> Option<()> {
435 match feature {
441 "+lld" => {
442 self.enabled.insert(LinkerFeatures::LLD);
443 self.disabled.remove(LinkerFeatures::LLD);
444 Some(())
445 }
446 "-lld" => {
447 self.disabled.insert(LinkerFeatures::LLD);
448 self.enabled.remove(LinkerFeatures::LLD);
449 Some(())
450 }
451 _ => None,
452 }
453 }
454
455 pub(crate) fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
460 let has_minus_lld = self.disabled.is_lld_enabled();
462 if has_minus_lld && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
463 return Err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`-C linker-features=-lld` is unstable on the `{0}` target. The `-Z unstable-options` flag must also be passed to use it on this target",
target_tuple))
})format!(
464 "`-C linker-features=-lld` is unstable on the `{target_tuple}` \
465 target. The `-Z unstable-options` flag must also be passed to use it on this target",
466 ));
467 }
468
469 let unstable_enabled = self.enabled;
471 let unstable_disabled = self.disabled - LinkerFeatures::LLD;
472 if !unstable_enabled.union(unstable_disabled).is_empty() {
473 let unstable_features: Vec<_> = unstable_enabled
474 .iter()
475 .map(|f| ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("+{0}", f.as_str().unwrap()))
})format!("+{}", f.as_str().unwrap()))
476 .chain(unstable_disabled.iter().map(|f| ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("-{0}", f.as_str().unwrap()))
})format!("-{}", f.as_str().unwrap())))
477 .collect();
478 return Err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`-C linker-features={0}` is unstable, and also requires the `-Z unstable-options` flag to be used",
unstable_features.join(",")))
})format!(
479 "`-C linker-features={}` is unstable, and also requires the \
480 `-Z unstable-options` flag to be used",
481 unstable_features.join(","),
482 ));
483 }
484
485 Ok(())
486 }
487}
488
489#[derive(#[automatically_derived]
impl ::core::clone::Clone for IncrementalStateAssertion {
#[inline]
fn clone(&self) -> IncrementalStateAssertion { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for IncrementalStateAssertion { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for IncrementalStateAssertion {
#[inline]
fn eq(&self, other: &IncrementalStateAssertion) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for IncrementalStateAssertion {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for IncrementalStateAssertion {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
IncrementalStateAssertion::Loaded => "Loaded",
IncrementalStateAssertion::NotLoaded => "NotLoaded",
})
}
}Debug)]
491pub enum IncrementalStateAssertion {
492 Loaded,
497 NotLoaded,
499}
500
501#[derive(#[automatically_derived]
impl ::core::marker::Copy for LocationDetail { }Copy, #[automatically_derived]
impl ::core::clone::Clone for LocationDetail {
#[inline]
fn clone(&self) -> LocationDetail {
let _: ::core::clone::AssertParamIsClone<bool>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for LocationDetail {
#[inline]
fn eq(&self, other: &LocationDetail) -> bool {
self.file == other.file && self.line == other.line &&
self.column == other.column
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for LocationDetail {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.file, state);
::core::hash::Hash::hash(&self.line, state);
::core::hash::Hash::hash(&self.column, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for LocationDetail {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"LocationDetail", "file", &self.file, "line", &self.line,
"column", &&self.column)
}
}Debug)]
503pub struct LocationDetail {
504 pub file: bool,
505 pub line: bool,
506 pub column: bool,
507}
508
509impl LocationDetail {
510 pub(crate) fn all() -> Self {
511 Self { file: true, line: true, column: true }
512 }
513}
514
515#[derive(#[automatically_derived]
impl ::core::marker::Copy for FmtDebug { }Copy, #[automatically_derived]
impl ::core::clone::Clone for FmtDebug {
#[inline]
fn clone(&self) -> FmtDebug { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for FmtDebug {
#[inline]
fn eq(&self, other: &FmtDebug) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for FmtDebug {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for FmtDebug {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
FmtDebug::Full => "Full",
FmtDebug::Shallow => "Shallow",
FmtDebug::None => "None",
})
}
}Debug)]
517pub enum FmtDebug {
518 Full,
520 Shallow,
522 None,
524}
525
526impl FmtDebug {
527 pub(crate) fn all() -> [Symbol; 3] {
528 [sym::full, sym::none, sym::shallow]
529 }
530}
531
532#[derive(#[automatically_derived]
impl ::core::clone::Clone for SwitchWithOptPath {
#[inline]
fn clone(&self) -> SwitchWithOptPath {
match self {
SwitchWithOptPath::Enabled(__self_0) =>
SwitchWithOptPath::Enabled(::core::clone::Clone::clone(__self_0)),
SwitchWithOptPath::Disabled => SwitchWithOptPath::Disabled,
}
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for SwitchWithOptPath {
#[inline]
fn eq(&self, other: &SwitchWithOptPath) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(SwitchWithOptPath::Enabled(__self_0),
SwitchWithOptPath::Enabled(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for SwitchWithOptPath {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
SwitchWithOptPath::Enabled(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
_ => {}
}
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for SwitchWithOptPath {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
SwitchWithOptPath::Enabled(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Enabled", &__self_0),
SwitchWithOptPath::Disabled =>
::core::fmt::Formatter::write_str(f, "Disabled"),
}
}
}Debug, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for SwitchWithOptPath {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
SwitchWithOptPath::Enabled(ref __binding_0) => { 0usize }
SwitchWithOptPath::Disabled => { 1usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
SwitchWithOptPath::Enabled(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
SwitchWithOptPath::Disabled => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for SwitchWithOptPath {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => {
SwitchWithOptPath::Enabled(::rustc_serialize::Decodable::decode(__decoder))
}
1usize => { SwitchWithOptPath::Disabled }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `SwitchWithOptPath`, expected 0..2, actual {0}",
n));
}
}
}
}
};Decodable)]
533pub enum SwitchWithOptPath {
534 Enabled(Option<PathBuf>),
535 Disabled,
536}
537
538impl SwitchWithOptPath {
539 pub fn enabled(&self) -> bool {
540 match *self {
541 SwitchWithOptPath::Enabled(_) => true,
542 SwitchWithOptPath::Disabled => false,
543 }
544 }
545}
546
547#[derive(#[automatically_derived]
impl ::core::marker::Copy for SymbolManglingVersion { }Copy, #[automatically_derived]
impl ::core::clone::Clone for SymbolManglingVersion {
#[inline]
fn clone(&self) -> SymbolManglingVersion { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for SymbolManglingVersion {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
SymbolManglingVersion::Legacy => "Legacy",
SymbolManglingVersion::V0 => "V0",
SymbolManglingVersion::Hashed => "Hashed",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for SymbolManglingVersion {
#[inline]
fn eq(&self, other: &SymbolManglingVersion) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for SymbolManglingVersion {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for SymbolManglingVersion {
#[inline]
fn partial_cmp(&self, other: &SymbolManglingVersion)
-> ::core::option::Option<::core::cmp::Ordering> {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::PartialOrd::partial_cmp(&__self_discr, &__arg1_discr)
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for SymbolManglingVersion {
#[inline]
fn cmp(&self, other: &SymbolManglingVersion) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
}
}Ord, #[automatically_derived]
impl ::core::hash::Hash for SymbolManglingVersion {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, const _: () =
{
impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
for SymbolManglingVersion where
__CTX: ::rustc_span::HashStableContext {
#[inline]
fn hash_stable(&self, __hcx: &mut __CTX,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
match *self {
SymbolManglingVersion::Legacy => {}
SymbolManglingVersion::V0 => {}
SymbolManglingVersion::Hashed => {}
}
}
}
};HashStable_Generic)]
548#[derive(const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for SymbolManglingVersion {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
SymbolManglingVersion::Legacy => { 0usize }
SymbolManglingVersion::V0 => { 1usize }
SymbolManglingVersion::Hashed => { 2usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
SymbolManglingVersion::Legacy => {}
SymbolManglingVersion::V0 => {}
SymbolManglingVersion::Hashed => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::BlobDecoder> ::rustc_serialize::Decodable<__D>
for SymbolManglingVersion {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { SymbolManglingVersion::Legacy }
1usize => { SymbolManglingVersion::V0 }
2usize => { SymbolManglingVersion::Hashed }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `SymbolManglingVersion`, expected 0..3, actual {0}",
n));
}
}
}
}
};BlobDecodable)]
549pub enum SymbolManglingVersion {
550 Legacy,
551 V0,
552 Hashed,
553}
554
555#[derive(#[automatically_derived]
impl ::core::clone::Clone for DebugInfo {
#[inline]
fn clone(&self) -> DebugInfo { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for DebugInfo { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for DebugInfo {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
DebugInfo::None => "None",
DebugInfo::LineDirectivesOnly => "LineDirectivesOnly",
DebugInfo::LineTablesOnly => "LineTablesOnly",
DebugInfo::Limited => "Limited",
DebugInfo::Full => "Full",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for DebugInfo {
#[inline]
fn eq(&self, other: &DebugInfo) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for DebugInfo {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash)]
556pub enum DebugInfo {
557 None,
558 LineDirectivesOnly,
559 LineTablesOnly,
560 Limited,
561 Full,
562}
563
564#[derive(#[automatically_derived]
impl ::core::clone::Clone for DebugInfoCompression {
#[inline]
fn clone(&self) -> DebugInfoCompression { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for DebugInfoCompression { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for DebugInfoCompression {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
DebugInfoCompression::None => "None",
DebugInfoCompression::Zlib => "Zlib",
DebugInfoCompression::Zstd => "Zstd",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for DebugInfoCompression {
#[inline]
fn eq(&self, other: &DebugInfoCompression) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for DebugInfoCompression {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash)]
565pub enum DebugInfoCompression {
566 None,
567 Zlib,
568 Zstd,
569}
570
571#[derive(#[automatically_derived]
impl ::core::clone::Clone for MirStripDebugInfo {
#[inline]
fn clone(&self) -> MirStripDebugInfo { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for MirStripDebugInfo { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for MirStripDebugInfo {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
MirStripDebugInfo::None => "None",
MirStripDebugInfo::LocalsInTinyFunctions =>
"LocalsInTinyFunctions",
MirStripDebugInfo::AllLocals => "AllLocals",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for MirStripDebugInfo {
#[inline]
fn eq(&self, other: &MirStripDebugInfo) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for MirStripDebugInfo {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash)]
572pub enum MirStripDebugInfo {
573 None,
574 LocalsInTinyFunctions,
575 AllLocals,
576}
577
578#[derive(#[automatically_derived]
impl ::core::clone::Clone for SplitDwarfKind {
#[inline]
fn clone(&self) -> SplitDwarfKind { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for SplitDwarfKind { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for SplitDwarfKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
SplitDwarfKind::Single => "Single",
SplitDwarfKind::Split => "Split",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for SplitDwarfKind {
#[inline]
fn eq(&self, other: &SplitDwarfKind) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for SplitDwarfKind {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for SplitDwarfKind {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
SplitDwarfKind::Single => { 0usize }
SplitDwarfKind::Split => { 1usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
SplitDwarfKind::Single => {}
SplitDwarfKind::Split => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for SplitDwarfKind {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { SplitDwarfKind::Single }
1usize => { SplitDwarfKind::Split }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `SplitDwarfKind`, expected 0..2, actual {0}",
n));
}
}
}
}
};Decodable)]
588pub enum SplitDwarfKind {
589 Single,
592 Split,
595}
596
597impl FromStr for SplitDwarfKind {
598 type Err = ();
599
600 fn from_str(s: &str) -> Result<Self, ()> {
601 Ok(match s {
602 "single" => SplitDwarfKind::Single,
603 "split" => SplitDwarfKind::Split,
604 _ => return Err(()),
605 })
606 }
607}
608
609macro_rules! define_output_types {
610 (
611 $(
612 $(#[doc = $doc:expr])*
613 $Variant:ident => {
614 shorthand: $shorthand:expr,
615 extension: $extension:expr,
616 description: $description:expr,
617 default_filename: $default_filename:expr,
618 is_text: $is_text:expr,
619 compatible_with_cgus_and_single_output: $compatible:expr
620 }
621 ),* $(,)?
622 ) => {
623 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, HashStable_Generic)]
624 #[derive(Encodable, Decodable)]
625 pub enum OutputType {
626 $(
627 $(#[doc = $doc])*
628 $Variant,
629 )*
630 }
631
632
633 impl StableOrd for OutputType {
634 const CAN_USE_UNSTABLE_SORT: bool = true;
635
636 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
638 }
639
640 impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for OutputType {
641 type KeyType = Self;
642
643 fn to_stable_hash_key(&self, _: &mut Hcx) -> Self::KeyType {
644 *self
645 }
646 }
647
648
649 impl OutputType {
650 pub fn iter_all() -> impl Iterator<Item = OutputType> {
651 static ALL_VARIANTS: &[OutputType] = &[
652 $(
653 OutputType::$Variant,
654 )*
655 ];
656 ALL_VARIANTS.iter().copied()
657 }
658
659 fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool {
660 match *self {
661 $(
662 OutputType::$Variant => $compatible,
663 )*
664 }
665 }
666
667 pub fn shorthand(&self) -> &'static str {
668 match *self {
669 $(
670 OutputType::$Variant => $shorthand,
671 )*
672 }
673 }
674
675 fn from_shorthand(shorthand: &str) -> Option<Self> {
676 match shorthand {
677 $(
678 s if s == $shorthand => Some(OutputType::$Variant),
679 )*
680 _ => None,
681 }
682 }
683
684 fn shorthands_display() -> String {
685 let shorthands = vec![
686 $(
687 format!("`{}`", $shorthand),
688 )*
689 ];
690 shorthands.join(", ")
691 }
692
693 pub fn extension(&self) -> &'static str {
694 match *self {
695 $(
696 OutputType::$Variant => $extension,
697 )*
698 }
699 }
700
701 pub fn is_text_output(&self) -> bool {
702 match *self {
703 $(
704 OutputType::$Variant => $is_text,
705 )*
706 }
707 }
708
709 pub fn description(&self) -> &'static str {
710 match *self {
711 $(
712 OutputType::$Variant => $description,
713 )*
714 }
715 }
716
717 pub fn default_filename(&self) -> &'static str {
718 match *self {
719 $(
720 OutputType::$Variant => $default_filename,
721 )*
722 }
723 }
724
725
726 }
727 }
728}
729
730#[automatically_derived]
impl ::core::clone::Clone for OutputType {
#[inline]
fn clone(&self) -> OutputType { *self }
}
#[automatically_derived]
impl ::core::marker::Copy for OutputType { }
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for OutputType { }
#[automatically_derived]
impl ::core::cmp::PartialEq for OutputType {
#[inline]
fn eq(&self, other: &OutputType) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}
#[automatically_derived]
impl ::core::cmp::Eq for OutputType {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}
#[automatically_derived]
impl ::core::hash::Hash for OutputType {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}
#[automatically_derived]
impl ::core::fmt::Debug for OutputType {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
OutputType::Assembly => "Assembly",
OutputType::Bitcode => "Bitcode",
OutputType::DepInfo => "DepInfo",
OutputType::Exe => "Exe",
OutputType::LlvmAssembly => "LlvmAssembly",
OutputType::Metadata => "Metadata",
OutputType::Mir => "Mir",
OutputType::Object => "Object",
OutputType::ThinLinkBitcode => "ThinLinkBitcode",
})
}
}
#[automatically_derived]
impl ::core::cmp::PartialOrd for OutputType {
#[inline]
fn partial_cmp(&self, other: &OutputType)
-> ::core::option::Option<::core::cmp::Ordering> {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::PartialOrd::partial_cmp(&__self_discr, &__arg1_discr)
}
}
#[automatically_derived]
impl ::core::cmp::Ord for OutputType {
#[inline]
fn cmp(&self, other: &OutputType) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
}
}
const _: () =
{
impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
for OutputType where __CTX: ::rustc_span::HashStableContext {
#[inline]
fn hash_stable(&self, __hcx: &mut __CTX,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
match *self {
OutputType::Assembly => {}
OutputType::Bitcode => {}
OutputType::DepInfo => {}
OutputType::Exe => {}
OutputType::LlvmAssembly => {}
OutputType::Metadata => {}
OutputType::Mir => {}
OutputType::Object => {}
OutputType::ThinLinkBitcode => {}
}
}
}
};
impl StableOrd for OutputType {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}
impl<Hcx: HashStableContext> ToStableHashKey<Hcx> for OutputType {
type KeyType = Self;
fn to_stable_hash_key(&self, _: &mut Hcx) -> Self::KeyType { *self }
}
impl OutputType {
pub fn iter_all() -> impl Iterator<Item = OutputType> {
static ALL_VARIANTS: &[OutputType] =
&[OutputType::Assembly, OutputType::Bitcode, OutputType::DepInfo,
OutputType::Exe, OutputType::LlvmAssembly,
OutputType::Metadata, OutputType::Mir, OutputType::Object,
OutputType::ThinLinkBitcode];
ALL_VARIANTS.iter().copied()
}
fn is_compatible_with_codegen_units_and_single_output_file(&self)
-> bool {
match *self {
OutputType::Assembly => false,
OutputType::Bitcode => false,
OutputType::DepInfo => true,
OutputType::Exe => true,
OutputType::LlvmAssembly => false,
OutputType::Metadata => true,
OutputType::Mir => false,
OutputType::Object => false,
OutputType::ThinLinkBitcode => false,
}
}
pub fn shorthand(&self) -> &'static str {
match *self {
OutputType::Assembly => "asm",
OutputType::Bitcode => "llvm-bc",
OutputType::DepInfo => "dep-info",
OutputType::Exe => "link",
OutputType::LlvmAssembly => "llvm-ir",
OutputType::Metadata => "metadata",
OutputType::Mir => "mir",
OutputType::Object => "obj",
OutputType::ThinLinkBitcode => "thin-link-bitcode",
}
}
fn from_shorthand(shorthand: &str) -> Option<Self> {
match shorthand {
s if s == "asm" => Some(OutputType::Assembly),
s if s == "llvm-bc" => Some(OutputType::Bitcode),
s if s == "dep-info" => Some(OutputType::DepInfo),
s if s == "link" => Some(OutputType::Exe),
s if s == "llvm-ir" => Some(OutputType::LlvmAssembly),
s if s == "metadata" => Some(OutputType::Metadata),
s if s == "mir" => Some(OutputType::Mir),
s if s == "obj" => Some(OutputType::Object),
s if s == "thin-link-bitcode" =>
Some(OutputType::ThinLinkBitcode),
_ => None,
}
}
fn shorthands_display() -> String {
let shorthands =
::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "asm"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "llvm-bc"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "dep-info"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "link"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "llvm-ir"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "metadata"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "mir"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "obj"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`",
"thin-link-bitcode"))
})]));
shorthands.join(", ")
}
pub fn extension(&self) -> &'static str {
match *self {
OutputType::Assembly => "s",
OutputType::Bitcode => "bc",
OutputType::DepInfo => "d",
OutputType::Exe => "",
OutputType::LlvmAssembly => "ll",
OutputType::Metadata => "rmeta",
OutputType::Mir => "mir",
OutputType::Object => "o",
OutputType::ThinLinkBitcode => "indexing.o",
}
}
pub fn is_text_output(&self) -> bool {
match *self {
OutputType::Assembly => true,
OutputType::Bitcode => false,
OutputType::DepInfo => true,
OutputType::Exe => false,
OutputType::LlvmAssembly => true,
OutputType::Metadata => false,
OutputType::Mir => true,
OutputType::Object => false,
OutputType::ThinLinkBitcode => false,
}
}
pub fn description(&self) -> &'static str {
match *self {
OutputType::Assembly =>
"Generates a file with the crate's assembly code",
OutputType::Bitcode =>
"Generates a binary file containing the LLVM bitcode",
OutputType::DepInfo =>
"Generates a file with Makefile syntax that indicates all the source files that were loaded to generate the crate",
OutputType::Exe =>
"Generates the crates specified by --crate-type. This is the default if --emit is not specified",
OutputType::LlvmAssembly => "Generates a file containing LLVM IR",
OutputType::Metadata =>
"Generates a file containing metadata about the crate",
OutputType::Mir =>
"Generates a file containing rustc's mid-level intermediate representation",
OutputType::Object => "Generates a native object file",
OutputType::ThinLinkBitcode =>
"Generates the ThinLTO summary as bitcode",
}
}
pub fn default_filename(&self) -> &'static str {
match *self {
OutputType::Assembly => "CRATE_NAME.s",
OutputType::Bitcode => "CRATE_NAME.bc",
OutputType::DepInfo => "CRATE_NAME.d",
OutputType::Exe => "(platform and crate-type dependent)",
OutputType::LlvmAssembly => "CRATE_NAME.ll",
OutputType::Metadata => "libCRATE_NAME.rmeta",
OutputType::Mir => "CRATE_NAME.mir",
OutputType::Object => "CRATE_NAME.o",
OutputType::ThinLinkBitcode => "CRATE_NAME.indexing.o",
}
}
}define_output_types! {
731 Assembly => {
732 shorthand: "asm",
733 extension: "s",
734 description: "Generates a file with the crate's assembly code",
735 default_filename: "CRATE_NAME.s",
736 is_text: true,
737 compatible_with_cgus_and_single_output: false
738 },
739 #[doc = "This is the optimized bitcode, which could be either pre-LTO or non-LTO bitcode,"]
740 #[doc = "depending on the specific request type."]
741 Bitcode => {
742 shorthand: "llvm-bc",
743 extension: "bc",
744 description: "Generates a binary file containing the LLVM bitcode",
745 default_filename: "CRATE_NAME.bc",
746 is_text: false,
747 compatible_with_cgus_and_single_output: false
748 },
749 DepInfo => {
750 shorthand: "dep-info",
751 extension: "d",
752 description: "Generates a file with Makefile syntax that indicates all the source files that were loaded to generate the crate",
753 default_filename: "CRATE_NAME.d",
754 is_text: true,
755 compatible_with_cgus_and_single_output: true
756 },
757 Exe => {
758 shorthand: "link",
759 extension: "",
760 description: "Generates the crates specified by --crate-type. This is the default if --emit is not specified",
761 default_filename: "(platform and crate-type dependent)",
762 is_text: false,
763 compatible_with_cgus_and_single_output: true
764 },
765 LlvmAssembly => {
766 shorthand: "llvm-ir",
767 extension: "ll",
768 description: "Generates a file containing LLVM IR",
769 default_filename: "CRATE_NAME.ll",
770 is_text: true,
771 compatible_with_cgus_and_single_output: false
772 },
773 Metadata => {
774 shorthand: "metadata",
775 extension: "rmeta",
776 description: "Generates a file containing metadata about the crate",
777 default_filename: "libCRATE_NAME.rmeta",
778 is_text: false,
779 compatible_with_cgus_and_single_output: true
780 },
781 Mir => {
782 shorthand: "mir",
783 extension: "mir",
784 description: "Generates a file containing rustc's mid-level intermediate representation",
785 default_filename: "CRATE_NAME.mir",
786 is_text: true,
787 compatible_with_cgus_and_single_output: false
788 },
789 Object => {
790 shorthand: "obj",
791 extension: "o",
792 description: "Generates a native object file",
793 default_filename: "CRATE_NAME.o",
794 is_text: false,
795 compatible_with_cgus_and_single_output: false
796 },
797 #[doc = "This is the summary or index data part of the ThinLTO bitcode."]
798 ThinLinkBitcode => {
799 shorthand: "thin-link-bitcode",
800 extension: "indexing.o",
801 description: "Generates the ThinLTO summary as bitcode",
802 default_filename: "CRATE_NAME.indexing.o",
803 is_text: false,
804 compatible_with_cgus_and_single_output: false
805 },
806}
807
808#[derive(#[automatically_derived]
impl ::core::clone::Clone for ErrorOutputType {
#[inline]
fn clone(&self) -> ErrorOutputType {
let _: ::core::clone::AssertParamIsClone<HumanReadableErrorType>;
let _: ::core::clone::AssertParamIsClone<ColorConfig>;
let _: ::core::clone::AssertParamIsClone<bool>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for ErrorOutputType { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for ErrorOutputType {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ErrorOutputType::HumanReadable {
kind: __self_0, color_config: __self_1 } =>
::core::fmt::Formatter::debug_struct_field2_finish(f,
"HumanReadable", "kind", __self_0, "color_config",
&__self_1),
ErrorOutputType::Json {
pretty: __self_0,
json_rendered: __self_1,
color_config: __self_2 } =>
::core::fmt::Formatter::debug_struct_field3_finish(f, "Json",
"pretty", __self_0, "json_rendered", __self_1,
"color_config", &__self_2),
}
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for ErrorOutputType {
#[inline]
fn eq(&self, other: &ErrorOutputType) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(ErrorOutputType::HumanReadable {
kind: __self_0, color_config: __self_1 },
ErrorOutputType::HumanReadable {
kind: __arg1_0, color_config: __arg1_1 }) =>
__self_0 == __arg1_0 && __self_1 == __arg1_1,
(ErrorOutputType::Json {
pretty: __self_0,
json_rendered: __self_1,
color_config: __self_2 }, ErrorOutputType::Json {
pretty: __arg1_0,
json_rendered: __arg1_1,
color_config: __arg1_2 }) =>
__self_0 == __arg1_0 && __self_1 == __arg1_1 &&
__self_2 == __arg1_2,
_ => unsafe { ::core::intrinsics::unreachable() }
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for ErrorOutputType {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<HumanReadableErrorType>;
let _: ::core::cmp::AssertParamIsEq<ColorConfig>;
let _: ::core::cmp::AssertParamIsEq<bool>;
}
}Eq, #[automatically_derived]
impl ::core::default::Default for ErrorOutputType {
#[inline]
fn default() -> ErrorOutputType {
Self::HumanReadable {
kind: const HumanReadableErrorType {
short: false,
unicode: false,
},
color_config: const ColorConfig::Auto,
}
}
}Default)]
810pub enum ErrorOutputType {
811 #[default]
813 HumanReadable {
814 kind: HumanReadableErrorType = HumanReadableErrorType { short: false, unicode: false },
815 color_config: ColorConfig = ColorConfig::Auto,
816 },
817 Json {
819 pretty: bool,
821 json_rendered: HumanReadableErrorType,
824 color_config: ColorConfig,
825 },
826}
827
828#[derive(#[automatically_derived]
impl ::core::clone::Clone for ResolveDocLinks {
#[inline]
fn clone(&self) -> ResolveDocLinks {
match self {
ResolveDocLinks::None => ResolveDocLinks::None,
ResolveDocLinks::ExportedMetadata =>
ResolveDocLinks::ExportedMetadata,
ResolveDocLinks::Exported => ResolveDocLinks::Exported,
ResolveDocLinks::All => ResolveDocLinks::All,
}
}
}Clone, #[automatically_derived]
impl ::core::hash::Hash for ResolveDocLinks {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for ResolveDocLinks {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
ResolveDocLinks::None => "None",
ResolveDocLinks::ExportedMetadata => "ExportedMetadata",
ResolveDocLinks::Exported => "Exported",
ResolveDocLinks::All => "All",
})
}
}Debug)]
829pub enum ResolveDocLinks {
830 None,
832 ExportedMetadata,
834 Exported,
836 All,
838}
839
840#[derive(#[automatically_derived]
impl ::core::clone::Clone for OutputTypes {
#[inline]
fn clone(&self) -> OutputTypes {
OutputTypes(::core::clone::Clone::clone(&self.0))
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for OutputTypes {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "OutputTypes",
&&self.0)
}
}Debug, #[automatically_derived]
impl ::core::hash::Hash for OutputTypes {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, const _: () =
{
impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
for OutputTypes where __CTX: ::rustc_span::HashStableContext {
#[inline]
fn hash_stable(&self, __hcx: &mut __CTX,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
match *self {
OutputTypes(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable_Generic, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for OutputTypes {
fn encode(&self, __encoder: &mut __E) {
match *self {
OutputTypes(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for OutputTypes {
fn decode(__decoder: &mut __D) -> Self {
OutputTypes(::rustc_serialize::Decodable::decode(__decoder))
}
}
};Decodable)]
845pub struct OutputTypes(BTreeMap<OutputType, Option<OutFileName>>);
846
847impl OutputTypes {
848 pub fn new(entries: &[(OutputType, Option<OutFileName>)]) -> OutputTypes {
849 OutputTypes(BTreeMap::from_iter(entries.iter().map(|&(k, ref v)| (k, v.clone()))))
850 }
851
852 pub(crate) fn get(&self, key: &OutputType) -> Option<&Option<OutFileName>> {
853 self.0.get(key)
854 }
855
856 pub fn contains_key(&self, key: &OutputType) -> bool {
857 self.0.contains_key(key)
858 }
859
860 pub fn contains_explicit_name(&self, key: &OutputType) -> bool {
862 #[allow(non_exhaustive_omitted_patterns)] match self.0.get(key) {
Some(Some(..)) => true,
_ => false,
}matches!(self.0.get(key), Some(Some(..)))
863 }
864
865 pub fn iter(&self) -> BTreeMapIter<'_, OutputType, Option<OutFileName>> {
866 self.0.iter()
867 }
868
869 pub fn keys(&self) -> BTreeMapKeysIter<'_, OutputType, Option<OutFileName>> {
870 self.0.keys()
871 }
872
873 pub fn values(&self) -> BTreeMapValuesIter<'_, OutputType, Option<OutFileName>> {
874 self.0.values()
875 }
876
877 pub fn len(&self) -> usize {
878 self.0.len()
879 }
880
881 pub fn should_codegen(&self) -> bool {
883 self.0.keys().any(|k| match *k {
884 OutputType::Bitcode
885 | OutputType::ThinLinkBitcode
886 | OutputType::Assembly
887 | OutputType::LlvmAssembly
888 | OutputType::Mir
889 | OutputType::Object
890 | OutputType::Exe => true,
891 OutputType::Metadata | OutputType::DepInfo => false,
892 })
893 }
894
895 pub fn should_link(&self) -> bool {
897 self.0.keys().any(|k| match *k {
898 OutputType::Bitcode
899 | OutputType::ThinLinkBitcode
900 | OutputType::Assembly
901 | OutputType::LlvmAssembly
902 | OutputType::Mir
903 | OutputType::Metadata
904 | OutputType::Object
905 | OutputType::DepInfo => false,
906 OutputType::Exe => true,
907 })
908 }
909}
910
911#[derive(#[automatically_derived]
impl ::core::clone::Clone for Externs {
#[inline]
fn clone(&self) -> Externs {
Externs(::core::clone::Clone::clone(&self.0))
}
}Clone)]
915pub struct Externs(BTreeMap<String, ExternEntry>);
916
917#[derive(#[automatically_derived]
impl ::core::clone::Clone for ExternEntry {
#[inline]
fn clone(&self) -> ExternEntry {
ExternEntry {
location: ::core::clone::Clone::clone(&self.location),
is_private_dep: ::core::clone::Clone::clone(&self.is_private_dep),
add_prelude: ::core::clone::Clone::clone(&self.add_prelude),
nounused_dep: ::core::clone::Clone::clone(&self.nounused_dep),
force: ::core::clone::Clone::clone(&self.force),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for ExternEntry {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field5_finish(f, "ExternEntry",
"location", &self.location, "is_private_dep",
&self.is_private_dep, "add_prelude", &self.add_prelude,
"nounused_dep", &self.nounused_dep, "force", &&self.force)
}
}Debug)]
918pub struct ExternEntry {
919 pub location: ExternLocation,
920 pub is_private_dep: bool,
926 pub add_prelude: bool,
931 pub nounused_dep: bool,
936 pub force: bool,
942}
943
944#[derive(#[automatically_derived]
impl ::core::clone::Clone for ExternLocation {
#[inline]
fn clone(&self) -> ExternLocation {
match self {
ExternLocation::FoundInLibrarySearchDirectories =>
ExternLocation::FoundInLibrarySearchDirectories,
ExternLocation::ExactPaths(__self_0) =>
ExternLocation::ExactPaths(::core::clone::Clone::clone(__self_0)),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for ExternLocation {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
ExternLocation::FoundInLibrarySearchDirectories =>
::core::fmt::Formatter::write_str(f,
"FoundInLibrarySearchDirectories"),
ExternLocation::ExactPaths(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"ExactPaths", &__self_0),
}
}
}Debug)]
945pub enum ExternLocation {
946 FoundInLibrarySearchDirectories,
950 ExactPaths(BTreeSet<CanonicalizedPath>),
957}
958
959impl Externs {
960 pub fn new(data: BTreeMap<String, ExternEntry>) -> Externs {
962 Externs(data)
963 }
964
965 pub fn get(&self, key: &str) -> Option<&ExternEntry> {
966 self.0.get(key)
967 }
968
969 pub fn iter(&self) -> BTreeMapIter<'_, String, ExternEntry> {
970 self.0.iter()
971 }
972}
973
974impl ExternEntry {
975 fn new(location: ExternLocation) -> ExternEntry {
976 ExternEntry {
977 location,
978 is_private_dep: false,
979 add_prelude: false,
980 nounused_dep: false,
981 force: false,
982 }
983 }
984
985 pub fn files(&self) -> Option<impl Iterator<Item = &CanonicalizedPath>> {
986 match &self.location {
987 ExternLocation::ExactPaths(set) => Some(set.iter()),
988 _ => None,
989 }
990 }
991}
992
993#[derive(#[automatically_derived]
impl ::core::fmt::Debug for NextSolverConfig {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"NextSolverConfig", "coherence", &self.coherence, "globally",
&&self.globally)
}
}Debug, #[automatically_derived]
impl ::core::marker::Copy for NextSolverConfig { }Copy, #[automatically_derived]
impl ::core::clone::Clone for NextSolverConfig {
#[inline]
fn clone(&self) -> NextSolverConfig {
let _: ::core::clone::AssertParamIsClone<bool>;
*self
}
}Clone, #[automatically_derived]
impl ::core::hash::Hash for NextSolverConfig {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.coherence, state);
::core::hash::Hash::hash(&self.globally, state)
}
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for NextSolverConfig {
#[inline]
fn eq(&self, other: &NextSolverConfig) -> bool {
self.coherence == other.coherence && self.globally == other.globally
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for NextSolverConfig {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<bool>;
}
}Eq, #[automatically_derived]
impl ::core::default::Default for NextSolverConfig {
#[inline]
fn default() -> NextSolverConfig {
NextSolverConfig { coherence: const true, globally: const false }
}
}Default)]
994pub struct NextSolverConfig {
995 pub coherence: bool = true,
997 pub globally: bool = false,
1000}
1001
1002#[derive(#[automatically_derived]
impl ::core::clone::Clone for Input {
#[inline]
fn clone(&self) -> Input {
match self {
Input::File(__self_0) =>
Input::File(::core::clone::Clone::clone(__self_0)),
Input::Str { name: __self_0, input: __self_1 } =>
Input::Str {
name: ::core::clone::Clone::clone(__self_0),
input: ::core::clone::Clone::clone(__self_1),
},
}
}
}Clone)]
1003pub enum Input {
1004 File(PathBuf),
1006 Str {
1008 name: FileName,
1010 input: String,
1012 },
1013}
1014
1015impl Input {
1016 pub fn filestem(&self) -> &str {
1017 if let Input::File(ifile) = self {
1018 if let Some(name) = ifile.file_stem().and_then(OsStr::to_str) {
1021 return name;
1022 }
1023 }
1024 "rust_out"
1025 }
1026
1027 pub fn file_name(&self, session: &Session) -> FileName {
1028 match *self {
1029 Input::File(ref ifile) => FileName::Real(
1030 session
1031 .psess
1032 .source_map()
1033 .path_mapping()
1034 .to_real_filename(session.psess.source_map().working_dir(), ifile.as_path()),
1035 ),
1036 Input::Str { ref name, .. } => name.clone(),
1037 }
1038 }
1039
1040 pub fn opt_path(&self) -> Option<&Path> {
1041 match self {
1042 Input::File(file) => Some(file),
1043 Input::Str { name, .. } => match name {
1044 FileName::Real(real) => real.local_path(),
1045 FileName::CfgSpec(_) => None,
1046 FileName::Anon(_) => None,
1047 FileName::MacroExpansion(_) => None,
1048 FileName::ProcMacroSourceCode(_) => None,
1049 FileName::CliCrateAttr(_) => None,
1050 FileName::Custom(_) => None,
1051 FileName::DocTest(path, _) => Some(path),
1052 FileName::InlineAsm(_) => None,
1053 },
1054 }
1055 }
1056}
1057
1058#[derive(#[automatically_derived]
impl ::core::clone::Clone for OutFileName {
#[inline]
fn clone(&self) -> OutFileName {
match self {
OutFileName::Real(__self_0) =>
OutFileName::Real(::core::clone::Clone::clone(__self_0)),
OutFileName::Stdout => OutFileName::Stdout,
}
}
}Clone, #[automatically_derived]
impl ::core::hash::Hash for OutFileName {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
OutFileName::Real(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
_ => {}
}
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for OutFileName {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
OutFileName::Real(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Real",
&__self_0),
OutFileName::Stdout =>
::core::fmt::Formatter::write_str(f, "Stdout"),
}
}
}Debug, const _: () =
{
impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
for OutFileName where __CTX: ::rustc_span::HashStableContext {
#[inline]
fn hash_stable(&self, __hcx: &mut __CTX,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
match *self {
OutFileName::Real(ref __binding_0) => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
OutFileName::Stdout => {}
}
}
}
};HashStable_Generic, #[automatically_derived]
impl ::core::cmp::PartialEq for OutFileName {
#[inline]
fn eq(&self, other: &OutFileName) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(OutFileName::Real(__self_0), OutFileName::Real(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for OutFileName {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<PathBuf>;
}
}Eq, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for OutFileName {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
OutFileName::Real(ref __binding_0) => { 0usize }
OutFileName::Stdout => { 1usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
OutFileName::Real(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
OutFileName::Stdout => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for OutFileName {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => {
OutFileName::Real(::rustc_serialize::Decodable::decode(__decoder))
}
1usize => { OutFileName::Stdout }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `OutFileName`, expected 0..2, actual {0}",
n));
}
}
}
}
};Decodable)]
1059pub enum OutFileName {
1060 Real(PathBuf),
1061 Stdout,
1062}
1063
1064impl OutFileName {
1065 pub fn parent(&self) -> Option<&Path> {
1066 match *self {
1067 OutFileName::Real(ref path) => path.parent(),
1068 OutFileName::Stdout => None,
1069 }
1070 }
1071
1072 pub fn filestem(&self) -> Option<&OsStr> {
1073 match *self {
1074 OutFileName::Real(ref path) => path.file_stem(),
1075 OutFileName::Stdout => Some(OsStr::new("stdout")),
1076 }
1077 }
1078
1079 pub fn is_stdout(&self) -> bool {
1080 match *self {
1081 OutFileName::Real(_) => false,
1082 OutFileName::Stdout => true,
1083 }
1084 }
1085
1086 pub fn is_tty(&self) -> bool {
1087 use std::io::IsTerminal;
1088 match *self {
1089 OutFileName::Real(_) => false,
1090 OutFileName::Stdout => std::io::stdout().is_terminal(),
1091 }
1092 }
1093
1094 pub fn as_path(&self) -> &Path {
1095 match *self {
1096 OutFileName::Real(ref path) => path.as_ref(),
1097 OutFileName::Stdout => Path::new("stdout"),
1098 }
1099 }
1100
1101 pub fn file_for_writing(
1107 &self,
1108 outputs: &OutputFilenames,
1109 flavor: OutputType,
1110 codegen_unit_name: &str,
1111 invocation_temp: Option<&str>,
1112 ) -> PathBuf {
1113 match *self {
1114 OutFileName::Real(ref path) => path.clone(),
1115 OutFileName::Stdout => {
1116 outputs.temp_path_for_cgu(flavor, codegen_unit_name, invocation_temp)
1117 }
1118 }
1119 }
1120
1121 pub fn overwrite(&self, content: &str, sess: &Session) {
1122 match self {
1123 OutFileName::Stdout => { ::std::io::_print(format_args!("{0}", content)); }print!("{content}"),
1124 OutFileName::Real(path) => {
1125 if let Err(e) = fs::write(path, content) {
1126 sess.dcx().emit_fatal(FileWriteFail { path, err: e.to_string() });
1127 }
1128 }
1129 }
1130 }
1131}
1132
1133#[derive(#[automatically_derived]
impl ::core::clone::Clone for OutputFilenames {
#[inline]
fn clone(&self) -> OutputFilenames {
OutputFilenames {
out_directory: ::core::clone::Clone::clone(&self.out_directory),
crate_stem: ::core::clone::Clone::clone(&self.crate_stem),
filestem: ::core::clone::Clone::clone(&self.filestem),
single_output_file: ::core::clone::Clone::clone(&self.single_output_file),
temps_directory: ::core::clone::Clone::clone(&self.temps_directory),
explicit_dwo_out_directory: ::core::clone::Clone::clone(&self.explicit_dwo_out_directory),
outputs: ::core::clone::Clone::clone(&self.outputs),
}
}
}Clone, #[automatically_derived]
impl ::core::hash::Hash for OutputFilenames {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.out_directory, state);
::core::hash::Hash::hash(&self.crate_stem, state);
::core::hash::Hash::hash(&self.filestem, state);
::core::hash::Hash::hash(&self.single_output_file, state);
::core::hash::Hash::hash(&self.temps_directory, state);
::core::hash::Hash::hash(&self.explicit_dwo_out_directory, state);
::core::hash::Hash::hash(&self.outputs, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for OutputFilenames {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let names: &'static _ =
&["out_directory", "crate_stem", "filestem", "single_output_file",
"temps_directory", "explicit_dwo_out_directory", "outputs"];
let values: &[&dyn ::core::fmt::Debug] =
&[&self.out_directory, &self.crate_stem, &self.filestem,
&self.single_output_file, &self.temps_directory,
&self.explicit_dwo_out_directory, &&self.outputs];
::core::fmt::Formatter::debug_struct_fields_finish(f,
"OutputFilenames", names, values)
}
}Debug, const _: () =
{
impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
for OutputFilenames where __CTX: ::rustc_span::HashStableContext {
#[inline]
fn hash_stable(&self, __hcx: &mut __CTX,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
match *self {
OutputFilenames {
out_directory: ref __binding_0,
crate_stem: ref __binding_1,
filestem: ref __binding_2,
single_output_file: ref __binding_3,
temps_directory: ref __binding_4,
explicit_dwo_out_directory: ref __binding_5,
outputs: ref __binding_6 } => {
{ __binding_0.hash_stable(__hcx, __hasher); }
{ __binding_1.hash_stable(__hcx, __hasher); }
{ __binding_2.hash_stable(__hcx, __hasher); }
{ __binding_3.hash_stable(__hcx, __hasher); }
{ __binding_4.hash_stable(__hcx, __hasher); }
{ __binding_5.hash_stable(__hcx, __hasher); }
{ __binding_6.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable_Generic, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for OutputFilenames {
fn encode(&self, __encoder: &mut __E) {
match *self {
OutputFilenames {
out_directory: ref __binding_0,
crate_stem: ref __binding_1,
filestem: ref __binding_2,
single_output_file: ref __binding_3,
temps_directory: ref __binding_4,
explicit_dwo_out_directory: ref __binding_5,
outputs: ref __binding_6 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_2,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_3,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_4,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_5,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_6,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for OutputFilenames {
fn decode(__decoder: &mut __D) -> Self {
OutputFilenames {
out_directory: ::rustc_serialize::Decodable::decode(__decoder),
crate_stem: ::rustc_serialize::Decodable::decode(__decoder),
filestem: ::rustc_serialize::Decodable::decode(__decoder),
single_output_file: ::rustc_serialize::Decodable::decode(__decoder),
temps_directory: ::rustc_serialize::Decodable::decode(__decoder),
explicit_dwo_out_directory: ::rustc_serialize::Decodable::decode(__decoder),
outputs: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable)]
1134pub struct OutputFilenames {
1135 pub(crate) out_directory: PathBuf,
1136 crate_stem: String,
1138 filestem: String,
1140 pub single_output_file: Option<OutFileName>,
1141 temps_directory: Option<PathBuf>,
1142 explicit_dwo_out_directory: Option<PathBuf>,
1143 pub outputs: OutputTypes,
1144}
1145
1146pub const RLINK_EXT: &str = "rlink";
1147pub const RUST_CGU_EXT: &str = "rcgu";
1148pub const DWARF_OBJECT_EXT: &str = "dwo";
1149pub const MAX_FILENAME_LENGTH: usize = 143; fn maybe_strip_file_name(mut path: PathBuf) -> PathBuf {
1155 if path.file_name().map_or(0, |name| name.len()) > MAX_FILENAME_LENGTH {
1156 let filename = path.file_name().unwrap().to_string_lossy();
1157 let hash_len = 64 / 4; let hyphen_len = 1; let allowed_suffix = MAX_FILENAME_LENGTH.saturating_sub(hash_len + hyphen_len);
1162
1163 let stripped_bytes = filename.len().saturating_sub(allowed_suffix);
1165
1166 let split_at = filename.ceil_char_boundary(stripped_bytes);
1168
1169 let mut hasher = StableHasher::new();
1170 filename[..split_at].hash(&mut hasher);
1171 let hash = hasher.finish::<Hash64>();
1172
1173 path.set_file_name(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0:x}-{1}", hash,
&filename[split_at..]))
})format!("{:x}-{}", hash, &filename[split_at..]));
1174 }
1175 path
1176}
1177impl OutputFilenames {
1178 pub fn new(
1179 out_directory: PathBuf,
1180 out_crate_name: String,
1181 out_filestem: String,
1182 single_output_file: Option<OutFileName>,
1183 temps_directory: Option<PathBuf>,
1184 explicit_dwo_out_directory: Option<PathBuf>,
1185 extra: String,
1186 outputs: OutputTypes,
1187 ) -> Self {
1188 OutputFilenames {
1189 out_directory,
1190 single_output_file,
1191 temps_directory,
1192 explicit_dwo_out_directory,
1193 outputs,
1194 crate_stem: ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}{1}", out_crate_name, extra))
})format!("{out_crate_name}{extra}"),
1195 filestem: ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}{1}", out_filestem, extra))
})format!("{out_filestem}{extra}"),
1196 }
1197 }
1198
1199 pub fn path(&self, flavor: OutputType) -> OutFileName {
1200 self.outputs
1201 .get(&flavor)
1202 .and_then(|p| p.to_owned())
1203 .or_else(|| self.single_output_file.clone())
1204 .unwrap_or_else(|| OutFileName::Real(self.output_path(flavor)))
1205 }
1206
1207 pub fn interface_path(&self) -> PathBuf {
1208 self.out_directory.join(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("lib{0}.rs", self.crate_stem))
})format!("lib{}.rs", self.crate_stem))
1209 }
1210
1211 fn output_path(&self, flavor: OutputType) -> PathBuf {
1214 let extension = flavor.extension();
1215 match flavor {
1216 OutputType::Metadata => {
1217 self.out_directory.join(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("lib{0}.{1}", self.crate_stem,
extension))
})format!("lib{}.{}", self.crate_stem, extension))
1218 }
1219 _ => self.with_directory_and_extension(&self.out_directory, extension),
1220 }
1221 }
1222
1223 pub fn temp_path_for_cgu(
1227 &self,
1228 flavor: OutputType,
1229 codegen_unit_name: &str,
1230 invocation_temp: Option<&str>,
1231 ) -> PathBuf {
1232 let extension = flavor.extension();
1233 self.temp_path_ext_for_cgu(extension, codegen_unit_name, invocation_temp)
1234 }
1235
1236 pub fn temp_path_dwo_for_cgu(
1238 &self,
1239 codegen_unit_name: &str,
1240 invocation_temp: Option<&str>,
1241 ) -> PathBuf {
1242 let p = self.temp_path_ext_for_cgu(DWARF_OBJECT_EXT, codegen_unit_name, invocation_temp);
1243 if let Some(dwo_out) = &self.explicit_dwo_out_directory {
1244 let mut o = dwo_out.clone();
1245 o.push(p.file_name().unwrap());
1246 o
1247 } else {
1248 p
1249 }
1250 }
1251
1252 pub fn temp_path_ext_for_cgu(
1255 &self,
1256 ext: &str,
1257 codegen_unit_name: &str,
1258 invocation_temp: Option<&str>,
1259 ) -> PathBuf {
1260 let mut extension = codegen_unit_name.to_string();
1261
1262 if let Some(rng) = invocation_temp {
1264 extension.push('.');
1265 extension.push_str(rng);
1266 }
1267
1268 if !ext.is_empty() {
1271 extension.push('.');
1272 extension.push_str(RUST_CGU_EXT);
1273 extension.push('.');
1274 extension.push_str(ext);
1275 }
1276
1277 let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
1278 maybe_strip_file_name(self.with_directory_and_extension(temps_directory, &extension))
1279 }
1280
1281 pub fn temp_path_for_diagnostic(&self, ext: &str) -> PathBuf {
1282 let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
1283 self.with_directory_and_extension(temps_directory, &ext)
1284 }
1285
1286 pub fn with_extension(&self, extension: &str) -> PathBuf {
1287 self.with_directory_and_extension(&self.out_directory, extension)
1288 }
1289
1290 pub fn with_directory_and_extension(&self, directory: &Path, extension: &str) -> PathBuf {
1291 let mut path = directory.join(&self.filestem);
1292 path.set_extension(extension);
1293 path
1294 }
1295
1296 pub fn split_dwarf_path(
1299 &self,
1300 split_debuginfo_kind: SplitDebuginfo,
1301 split_dwarf_kind: SplitDwarfKind,
1302 cgu_name: &str,
1303 invocation_temp: Option<&str>,
1304 ) -> Option<PathBuf> {
1305 let obj_out = self.temp_path_for_cgu(OutputType::Object, cgu_name, invocation_temp);
1306 let dwo_out = self.temp_path_dwo_for_cgu(cgu_name, invocation_temp);
1307 match (split_debuginfo_kind, split_dwarf_kind) {
1308 (SplitDebuginfo::Off, SplitDwarfKind::Single | SplitDwarfKind::Split) => None,
1309 (SplitDebuginfo::Packed | SplitDebuginfo::Unpacked, SplitDwarfKind::Single) => {
1313 Some(obj_out)
1314 }
1315 (SplitDebuginfo::Packed | SplitDebuginfo::Unpacked, SplitDwarfKind::Split) => {
1317 Some(dwo_out)
1318 }
1319 }
1320 }
1321}
1322
1323pub(crate) fn parse_remap_path_scope(
1324 early_dcx: &EarlyDiagCtxt,
1325 matches: &getopts::Matches,
1326 unstable_opts: &UnstableOptions,
1327) -> RemapPathScopeComponents {
1328 if let Some(v) = matches.opt_str("remap-path-scope") {
1329 let mut slot = RemapPathScopeComponents::empty();
1330 for s in v.split(',') {
1331 slot |= match s {
1332 "macro" => RemapPathScopeComponents::MACRO,
1333 "diagnostics" => RemapPathScopeComponents::DIAGNOSTICS,
1334 "documentation" => {
1335 if !unstable_opts.unstable_options {
1336 early_dcx.early_fatal("remapping `documentation` path scope requested but `-Zunstable-options` not specified");
1337 }
1338
1339 RemapPathScopeComponents::DOCUMENTATION
1340 },
1341 "debuginfo" => RemapPathScopeComponents::DEBUGINFO,
1342 "coverage" => RemapPathScopeComponents::COVERAGE,
1343 "object" => RemapPathScopeComponents::OBJECT,
1344 "all" => RemapPathScopeComponents::all(),
1345 _ => early_dcx.early_fatal("argument for `--remap-path-scope` must be a comma separated list of scopes: `macro`, `diagnostics`, `documentation`, `debuginfo`, `coverage`, `object`, `all`"),
1346 }
1347 }
1348 slot
1349 } else {
1350 RemapPathScopeComponents::all()
1351 }
1352}
1353
1354#[derive(#[automatically_derived]
impl ::core::clone::Clone for Sysroot {
#[inline]
fn clone(&self) -> Sysroot {
Sysroot {
explicit: ::core::clone::Clone::clone(&self.explicit),
default: ::core::clone::Clone::clone(&self.default),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for Sysroot {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f, "Sysroot",
"explicit", &self.explicit, "default", &&self.default)
}
}Debug)]
1355pub struct Sysroot {
1356 pub explicit: Option<PathBuf>,
1357 pub default: PathBuf,
1358}
1359
1360impl Sysroot {
1361 pub fn new(explicit: Option<PathBuf>) -> Sysroot {
1362 Sysroot { explicit, default: filesearch::default_sysroot() }
1363 }
1364
1365 pub fn path(&self) -> &Path {
1367 self.explicit.as_deref().unwrap_or(&self.default)
1368 }
1369
1370 pub fn all_paths(&self) -> impl Iterator<Item = &Path> {
1372 self.explicit.as_deref().into_iter().chain(iter::once(&*self.default))
1373 }
1374}
1375
1376pub fn host_tuple() -> &'static str {
1377 (::core::option::Option::Some("x86_64-unknown-linux-gnu")option_env!("CFG_COMPILER_HOST_TRIPLE")).expect("CFG_COMPILER_HOST_TRIPLE")
1386}
1387
1388fn file_path_mapping(
1389 remap_path_prefix: Vec<(PathBuf, PathBuf)>,
1390 remap_path_scope: RemapPathScopeComponents,
1391) -> FilePathMapping {
1392 FilePathMapping::new(remap_path_prefix.clone(), remap_path_scope)
1393}
1394
1395impl Default for Options {
1396 fn default() -> Options {
1397 let unstable_opts = UnstableOptions::default();
1398
1399 let working_dir = {
1403 let working_dir = std::env::current_dir().unwrap();
1404 let file_mapping = file_path_mapping(Vec::new(), RemapPathScopeComponents::empty());
1405 file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
1406 };
1407
1408 Options {
1409 crate_types: Vec::new(),
1410 optimize: OptLevel::No,
1411 debuginfo: DebugInfo::None,
1412 lint_opts: Vec::new(),
1413 lint_cap: None,
1414 describe_lints: false,
1415 output_types: OutputTypes(BTreeMap::new()),
1416 search_paths: ::alloc::vec::Vec::new()vec![],
1417 sysroot: Sysroot::new(None),
1418 target_triple: TargetTuple::from_tuple(host_tuple()),
1419 test: false,
1420 incremental: None,
1421 untracked_state_hash: Default::default(),
1422 unstable_opts,
1423 prints: Vec::new(),
1424 cg: Default::default(),
1425 error_format: ErrorOutputType::default(),
1426 diagnostic_width: None,
1427 externs: Externs(BTreeMap::new()),
1428 crate_name: None,
1429 libs: Vec::new(),
1430 unstable_features: UnstableFeatures::Disallow,
1431 debug_assertions: true,
1432 actually_rustdoc: false,
1433 resolve_doc_links: ResolveDocLinks::None,
1434 trimmed_def_paths: false,
1435 cli_forced_codegen_units: None,
1436 cli_forced_local_thinlto_off: false,
1437 remap_path_prefix: Vec::new(),
1438 remap_path_scope: RemapPathScopeComponents::all(),
1439 real_rust_source_base_dir: None,
1440 real_rustc_dev_source_base_dir: None,
1441 edition: DEFAULT_EDITION,
1442 json_artifact_notifications: false,
1443 json_timings: false,
1444 json_unused_externs: JsonUnusedExterns::No,
1445 json_future_incompat: false,
1446 pretty: None,
1447 working_dir,
1448 color: ColorConfig::Auto,
1449 logical_env: FxIndexMap::default(),
1450 verbose: false,
1451 target_modifiers: BTreeMap::default(),
1452 }
1453 }
1454}
1455
1456impl Options {
1457 pub fn build_dep_graph(&self) -> bool {
1459 self.incremental.is_some()
1460 || self.unstable_opts.dump_dep_graph
1461 || self.unstable_opts.query_dep_graph
1462 }
1463
1464 pub fn file_path_mapping(&self) -> FilePathMapping {
1465 file_path_mapping(self.remap_path_prefix.clone(), self.remap_path_scope)
1466 }
1467
1468 pub fn will_create_output_file(&self) -> bool {
1470 !self.unstable_opts.parse_crate_root_only && self.unstable_opts.ls.is_empty() }
1473
1474 #[inline]
1475 pub fn share_generics(&self) -> bool {
1476 match self.unstable_opts.share_generics {
1477 Some(setting) => setting,
1478 None => match self.optimize {
1479 OptLevel::No | OptLevel::Less | OptLevel::Size | OptLevel::SizeMin => true,
1480 OptLevel::More | OptLevel::Aggressive => false,
1481 },
1482 }
1483 }
1484
1485 pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
1486 self.cg.symbol_mangling_version.unwrap_or(if self.unstable_features.is_nightly_build() {
1487 SymbolManglingVersion::V0
1488 } else {
1489 SymbolManglingVersion::Legacy
1490 })
1491 }
1492
1493 #[inline]
1494 pub fn autodiff_enabled(&self) -> bool {
1495 self.unstable_opts.autodiff.contains(&AutoDiff::Enable)
1496 }
1497}
1498
1499impl UnstableOptions {
1500 pub fn dcx_flags(&self, can_emit_warnings: bool) -> DiagCtxtFlags {
1501 DiagCtxtFlags {
1502 can_emit_warnings,
1503 treat_err_as_bug: self.treat_err_as_bug,
1504 eagerly_emit_delayed_bugs: self.eagerly_emit_delayed_bugs,
1505 macro_backtrace: self.macro_backtrace,
1506 deduplicate_diagnostics: self.deduplicate_diagnostics,
1507 track_diagnostics: self.track_diagnostics,
1508 }
1509 }
1510
1511 pub fn src_hash_algorithm(&self, target: &Target) -> SourceFileHashAlgorithm {
1512 self.src_hash_algorithm.unwrap_or_else(|| {
1513 if target.is_like_msvc {
1514 SourceFileHashAlgorithm::Sha256
1515 } else {
1516 SourceFileHashAlgorithm::Md5
1517 }
1518 })
1519 }
1520
1521 pub fn checksum_hash_algorithm(&self) -> Option<SourceFileHashAlgorithm> {
1522 self.checksum_hash_algorithm
1523 }
1524}
1525
1526#[derive(#[automatically_derived]
impl ::core::marker::Copy for EntryFnType { }Copy, #[automatically_derived]
impl ::core::clone::Clone for EntryFnType {
#[inline]
fn clone(&self) -> EntryFnType {
let _: ::core::clone::AssertParamIsClone<u8>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for EntryFnType {
#[inline]
fn eq(&self, other: &EntryFnType) -> bool {
match (self, other) {
(EntryFnType::Main { sigpipe: __self_0 }, EntryFnType::Main {
sigpipe: __arg1_0 }) => __self_0 == __arg1_0,
}
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for EntryFnType {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
match self {
EntryFnType::Main { sigpipe: __self_0 } =>
::core::hash::Hash::hash(__self_0, state),
}
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for EntryFnType {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
EntryFnType::Main { sigpipe: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Main",
"sigpipe", &__self_0),
}
}
}Debug, const _: () =
{
impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
for EntryFnType where __CTX: ::rustc_span::HashStableContext {
#[inline]
fn hash_stable(&self, __hcx: &mut __CTX,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
::std::mem::discriminant(self).hash_stable(__hcx, __hasher);
match *self {
EntryFnType::Main { sigpipe: ref __binding_0 } => {
{ __binding_0.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable_Generic)]
1528pub enum EntryFnType {
1529 Main {
1530 sigpipe: u8,
1537 },
1538}
1539
1540pub use rustc_hir::attrs::CrateType;
1541
1542#[derive(#[automatically_derived]
impl ::core::clone::Clone for Passes {
#[inline]
fn clone(&self) -> Passes {
match self {
Passes::Some(__self_0) =>
Passes::Some(::core::clone::Clone::clone(__self_0)),
Passes::All => Passes::All,
}
}
}Clone, #[automatically_derived]
impl ::core::hash::Hash for Passes {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
Passes::Some(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
_ => {}
}
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Passes {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
Passes::Some(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Some",
&__self_0),
Passes::All => ::core::fmt::Formatter::write_str(f, "All"),
}
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for Passes {
#[inline]
fn eq(&self, other: &Passes) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(Passes::Some(__self_0), Passes::Some(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Passes {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Vec<String>>;
}
}Eq, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for Passes {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
Passes::Some(ref __binding_0) => { 0usize }
Passes::All => { 1usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
Passes::Some(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
Passes::All => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for Passes {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => {
Passes::Some(::rustc_serialize::Decodable::decode(__decoder))
}
1usize => { Passes::All }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Passes`, expected 0..2, actual {0}",
n));
}
}
}
}
};Decodable)]
1543pub enum Passes {
1544 Some(Vec<String>),
1545 All,
1546}
1547
1548impl Passes {
1549 fn is_empty(&self) -> bool {
1550 match *self {
1551 Passes::Some(ref v) => v.is_empty(),
1552 Passes::All => false,
1553 }
1554 }
1555
1556 pub(crate) fn extend(&mut self, passes: impl IntoIterator<Item = String>) {
1557 match *self {
1558 Passes::Some(ref mut v) => v.extend(passes),
1559 Passes::All => {}
1560 }
1561 }
1562}
1563
1564#[derive(#[automatically_derived]
impl ::core::clone::Clone for PAuthKey {
#[inline]
fn clone(&self) -> PAuthKey { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for PAuthKey { }Copy, #[automatically_derived]
impl ::core::hash::Hash for PAuthKey {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for PAuthKey {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self { PAuthKey::A => "A", PAuthKey::B => "B", })
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for PAuthKey {
#[inline]
fn eq(&self, other: &PAuthKey) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq)]
1565pub enum PAuthKey {
1566 A,
1567 B,
1568}
1569
1570#[derive(#[automatically_derived]
impl ::core::clone::Clone for PacRet {
#[inline]
fn clone(&self) -> PacRet {
let _: ::core::clone::AssertParamIsClone<bool>;
let _: ::core::clone::AssertParamIsClone<PAuthKey>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for PacRet { }Copy, #[automatically_derived]
impl ::core::hash::Hash for PacRet {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.leaf, state);
::core::hash::Hash::hash(&self.pc, state);
::core::hash::Hash::hash(&self.key, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for PacRet {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f, "PacRet",
"leaf", &self.leaf, "pc", &self.pc, "key", &&self.key)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for PacRet {
#[inline]
fn eq(&self, other: &PacRet) -> bool {
self.leaf == other.leaf && self.pc == other.pc &&
self.key == other.key
}
}PartialEq)]
1571pub struct PacRet {
1572 pub leaf: bool,
1573 pub pc: bool,
1574 pub key: PAuthKey,
1575}
1576
1577#[derive(#[automatically_derived]
impl ::core::clone::Clone for BranchProtection {
#[inline]
fn clone(&self) -> BranchProtection {
let _: ::core::clone::AssertParamIsClone<bool>;
let _: ::core::clone::AssertParamIsClone<Option<PacRet>>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for BranchProtection { }Copy, #[automatically_derived]
impl ::core::hash::Hash for BranchProtection {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.bti, state);
::core::hash::Hash::hash(&self.pac_ret, state);
::core::hash::Hash::hash(&self.gcs, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for BranchProtection {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"BranchProtection", "bti", &self.bti, "pac_ret", &self.pac_ret,
"gcs", &&self.gcs)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for BranchProtection {
#[inline]
fn eq(&self, other: &BranchProtection) -> bool {
self.bti == other.bti && self.gcs == other.gcs &&
self.pac_ret == other.pac_ret
}
}PartialEq, #[automatically_derived]
impl ::core::default::Default for BranchProtection {
#[inline]
fn default() -> BranchProtection {
BranchProtection {
bti: ::core::default::Default::default(),
pac_ret: ::core::default::Default::default(),
gcs: ::core::default::Default::default(),
}
}
}Default)]
1578pub struct BranchProtection {
1579 pub bti: bool,
1580 pub pac_ret: Option<PacRet>,
1581 pub gcs: bool,
1582}
1583
1584pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
1585 cfg::disallow_cfgs(sess, &user_cfg);
1587
1588 user_cfg.extend(cfg::default_configuration(sess));
1591 user_cfg
1592}
1593
1594pub fn build_target_config(
1595 early_dcx: &EarlyDiagCtxt,
1596 target: &TargetTuple,
1597 sysroot: &Path,
1598 unstable_options: bool,
1599) -> Target {
1600 match Target::search(target, sysroot, unstable_options) {
1601 Ok((target, warnings)) => {
1602 for warning in warnings.warning_messages() {
1603 early_dcx.early_warn(warning)
1604 }
1605
1606 if !#[allow(non_exhaustive_omitted_patterns)] match target.pointer_width {
16 | 32 | 64 => true,
_ => false,
}matches!(target.pointer_width, 16 | 32 | 64) {
1607 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("target specification was invalid: unrecognized target-pointer-width {0}",
target.pointer_width))
})format!(
1608 "target specification was invalid: unrecognized target-pointer-width {}",
1609 target.pointer_width
1610 ))
1611 }
1612 target
1613 }
1614 Err(e) => {
1615 let mut err =
1616 early_dcx.early_struct_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("error loading target specification: {0}",
e))
})format!("error loading target specification: {e}"));
1617 err.help("run `rustc --print target-list` for a list of built-in targets");
1618 err.emit()
1619 }
1620 }
1621}
1622
1623#[derive(#[automatically_derived]
impl ::core::marker::Copy for OptionStability { }Copy, #[automatically_derived]
impl ::core::clone::Clone for OptionStability {
#[inline]
fn clone(&self) -> OptionStability { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for OptionStability {
#[inline]
fn eq(&self, other: &OptionStability) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for OptionStability {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for OptionStability {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
OptionStability::Stable => "Stable",
OptionStability::Unstable => "Unstable",
})
}
}Debug)]
1624pub enum OptionStability {
1625 Stable,
1626 Unstable,
1627}
1628
1629#[derive(#[automatically_derived]
impl ::core::marker::Copy for OptionKind { }Copy, #[automatically_derived]
impl ::core::clone::Clone for OptionKind {
#[inline]
fn clone(&self) -> OptionKind { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for OptionKind {
#[inline]
fn eq(&self, other: &OptionKind) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for OptionKind {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for OptionKind {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
OptionKind::Opt => "Opt",
OptionKind::Multi => "Multi",
OptionKind::Flag => "Flag",
OptionKind::FlagMulti => "FlagMulti",
})
}
}Debug)]
1630pub enum OptionKind {
1631 Opt,
1635
1636 Multi,
1640
1641 Flag,
1646
1647 FlagMulti,
1652}
1653
1654pub struct RustcOptGroup {
1655 pub name: &'static str,
1663 stability: OptionStability,
1664 kind: OptionKind,
1665
1666 short_name: &'static str,
1667 long_name: &'static str,
1668 desc: &'static str,
1669 value_hint: &'static str,
1670
1671 pub is_verbose_help_only: bool,
1674}
1675
1676impl RustcOptGroup {
1677 pub fn is_stable(&self) -> bool {
1678 self.stability == OptionStability::Stable
1679 }
1680
1681 pub fn apply(&self, options: &mut getopts::Options) {
1682 let &Self { short_name, long_name, desc, value_hint, .. } = self;
1683 match self.kind {
1684 OptionKind::Opt => options.optopt(short_name, long_name, desc, value_hint),
1685 OptionKind::Multi => options.optmulti(short_name, long_name, desc, value_hint),
1686 OptionKind::Flag => options.optflag(short_name, long_name, desc),
1687 OptionKind::FlagMulti => options.optflagmulti(short_name, long_name, desc),
1688 };
1689 }
1690
1691 pub fn long_name(&self) -> &str {
1693 self.long_name
1694 }
1695}
1696
1697pub fn make_opt(
1698 stability: OptionStability,
1699 kind: OptionKind,
1700 short_name: &'static str,
1701 long_name: &'static str,
1702 desc: &'static str,
1703 value_hint: &'static str,
1704) -> RustcOptGroup {
1705 match kind {
1707 OptionKind::Opt | OptionKind::Multi => {}
1708 OptionKind::Flag | OptionKind::FlagMulti => match (&value_hint, &"") {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val, &*right_val,
::core::option::Option::None);
}
}
}assert_eq!(value_hint, ""),
1709 }
1710 RustcOptGroup {
1711 name: cmp::max_by_key(short_name, long_name, |s| s.len()),
1712 stability,
1713 kind,
1714 short_name,
1715 long_name,
1716 desc,
1717 value_hint,
1718 is_verbose_help_only: false,
1719 }
1720}
1721
1722static EDITION_STRING: LazyLock<String> = LazyLock::new(|| {
1723 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Specify which edition of the compiler to use when compiling code. The default is {0} and the latest stable edition is {1}.",
DEFAULT_EDITION, LATEST_STABLE_EDITION))
})format!(
1724 "Specify which edition of the compiler to use when compiling code. \
1725The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE_EDITION}."
1726 )
1727});
1728
1729static EMIT_HELP: LazyLock<String> = LazyLock::new(|| {
1730 let mut result =
1731 String::from("Comma separated list of types of output for the compiler to emit.\n");
1732 result.push_str("Each TYPE has the default FILE name:\n");
1733
1734 for output in OutputType::iter_all() {
1735 result.push_str(&::alloc::__export::must_use({
::alloc::fmt::format(format_args!("* {0} - {1}\n",
output.shorthand(), output.default_filename()))
})format!("* {} - {}\n", output.shorthand(), output.default_filename()));
1736 }
1737
1738 result
1739});
1740
1741pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
1751 use OptionKind::{Flag, FlagMulti, Multi, Opt};
1752 use OptionStability::{Stable, Unstable};
1753
1754 use self::make_opt as opt;
1755
1756 let mut options = ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[opt(Stable, Flag, "h", "help", "Display this message", ""),
opt(Stable, Multi, "", "cfg",
"Configure the compilation environment.\n\
SPEC supports the syntax `<NAME>[=\"<VALUE>\"]`.",
"<SPEC>"),
opt(Stable, Multi, "", "check-cfg",
"Provide list of expected cfgs for checking", "<SPEC>"),
opt(Stable, Multi, "L", "",
"Add a directory to the library search path. \
The optional KIND can be one of <dependency|crate|native|framework|all> (default: all).",
"[<KIND>=]<PATH>"),
opt(Stable, Multi, "l", "",
"Link the generated crate(s) to the specified native\n\
library NAME. The optional KIND can be one of\n\
<static|framework|dylib> (default: dylib).\n\
Optional comma separated MODIFIERS\n\
<bundle|verbatim|whole-archive|as-needed>\n\
may be specified each with a prefix of either '+' to\n\
enable or '-' to disable.",
"[<KIND>[:<MODIFIERS>]=]<NAME>[:<RENAME>]"),
make_crate_type_option(),
opt(Stable, Opt, "", "crate-name",
"Specify the name of the crate being built", "<NAME>"),
opt(Stable, Opt, "", "edition", &EDITION_STRING,
EDITION_NAME_LIST),
opt(Stable, Multi, "", "emit", &EMIT_HELP, "<TYPE>[=<FILE>]"),
opt(Stable, Multi, "", "print", &print_request::PRINT_HELP,
"<INFO>[=<FILE>]"),
opt(Stable, FlagMulti, "g", "",
"Equivalent to -C debuginfo=2", ""),
opt(Stable, FlagMulti, "O", "",
"Equivalent to -C opt-level=3", ""),
opt(Stable, Opt, "o", "", "Write output to FILENAME",
"<FILENAME>"),
opt(Stable, Opt, "", "out-dir",
"Write output to compiler-chosen filename in DIR", "<DIR>"),
opt(Stable, Opt, "", "explain",
"Provide a detailed explanation of an error message",
"<OPT>"),
opt(Stable, Flag, "", "test", "Build a test harness", ""),
opt(Stable, Opt, "", "target",
"Target tuple for which the code is compiled", "<TARGET>"),
opt(Stable, Multi, "A", "allow", "Set lint allowed",
"<LINT>"),
opt(Stable, Multi, "W", "warn", "Set lint warnings",
"<LINT>"),
opt(Stable, Multi, "", "force-warn", "Set lint force-warn",
"<LINT>"),
opt(Stable, Multi, "D", "deny", "Set lint denied", "<LINT>"),
opt(Stable, Multi, "F", "forbid", "Set lint forbidden",
"<LINT>"),
opt(Stable, Multi, "", "cap-lints",
"Set the most restrictive lint level. More restrictive lints are capped at this level",
"<LEVEL>"),
opt(Stable, Multi, "C", "codegen", "Set a codegen option",
"<OPT>[=<VALUE>]"),
opt(Stable, Flag, "V", "version",
"Print version info and exit", ""),
opt(Stable, Flag, "v", "verbose", "Use verbose output", "")]))vec![
1757 opt(Stable, Flag, "h", "help", "Display this message", ""),
1758 opt(
1759 Stable,
1760 Multi,
1761 "",
1762 "cfg",
1763 "Configure the compilation environment.\n\
1764 SPEC supports the syntax `<NAME>[=\"<VALUE>\"]`.",
1765 "<SPEC>",
1766 ),
1767 opt(Stable, Multi, "", "check-cfg", "Provide list of expected cfgs for checking", "<SPEC>"),
1768 opt(
1769 Stable,
1770 Multi,
1771 "L",
1772 "",
1773 "Add a directory to the library search path. \
1774 The optional KIND can be one of <dependency|crate|native|framework|all> (default: all).",
1775 "[<KIND>=]<PATH>",
1776 ),
1777 opt(
1778 Stable,
1779 Multi,
1780 "l",
1781 "",
1782 "Link the generated crate(s) to the specified native\n\
1783 library NAME. The optional KIND can be one of\n\
1784 <static|framework|dylib> (default: dylib).\n\
1785 Optional comma separated MODIFIERS\n\
1786 <bundle|verbatim|whole-archive|as-needed>\n\
1787 may be specified each with a prefix of either '+' to\n\
1788 enable or '-' to disable.",
1789 "[<KIND>[:<MODIFIERS>]=]<NAME>[:<RENAME>]",
1790 ),
1791 make_crate_type_option(),
1792 opt(Stable, Opt, "", "crate-name", "Specify the name of the crate being built", "<NAME>"),
1793 opt(Stable, Opt, "", "edition", &EDITION_STRING, EDITION_NAME_LIST),
1794 opt(Stable, Multi, "", "emit", &EMIT_HELP, "<TYPE>[=<FILE>]"),
1795 opt(Stable, Multi, "", "print", &print_request::PRINT_HELP, "<INFO>[=<FILE>]"),
1796 opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
1797 opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=3", ""),
1798 opt(Stable, Opt, "o", "", "Write output to FILENAME", "<FILENAME>"),
1799 opt(Stable, Opt, "", "out-dir", "Write output to compiler-chosen filename in DIR", "<DIR>"),
1800 opt(
1801 Stable,
1802 Opt,
1803 "",
1804 "explain",
1805 "Provide a detailed explanation of an error message",
1806 "<OPT>",
1807 ),
1808 opt(Stable, Flag, "", "test", "Build a test harness", ""),
1809 opt(Stable, Opt, "", "target", "Target tuple for which the code is compiled", "<TARGET>"),
1810 opt(Stable, Multi, "A", "allow", "Set lint allowed", "<LINT>"),
1811 opt(Stable, Multi, "W", "warn", "Set lint warnings", "<LINT>"),
1812 opt(Stable, Multi, "", "force-warn", "Set lint force-warn", "<LINT>"),
1813 opt(Stable, Multi, "D", "deny", "Set lint denied", "<LINT>"),
1814 opt(Stable, Multi, "F", "forbid", "Set lint forbidden", "<LINT>"),
1815 opt(
1816 Stable,
1817 Multi,
1818 "",
1819 "cap-lints",
1820 "Set the most restrictive lint level. More restrictive lints are capped at this level",
1821 "<LEVEL>",
1822 ),
1823 opt(Stable, Multi, "C", "codegen", "Set a codegen option", "<OPT>[=<VALUE>]"),
1824 opt(Stable, Flag, "V", "version", "Print version info and exit", ""),
1825 opt(Stable, Flag, "v", "verbose", "Use verbose output", ""),
1826 ];
1827
1828 let verbose_only = [
1831 opt(
1832 Stable,
1833 Multi,
1834 "",
1835 "extern",
1836 "Specify where an external rust library is located",
1837 "<NAME>[=<PATH>]",
1838 ),
1839 opt(Stable, Opt, "", "sysroot", "Override the system root", "<PATH>"),
1840 opt(Unstable, Multi, "Z", "", "Set unstable / perma-unstable options", "<FLAG>"),
1841 opt(
1842 Stable,
1843 Opt,
1844 "",
1845 "error-format",
1846 "How errors and other messages are produced",
1847 "<human|json|short>",
1848 ),
1849 opt(Stable, Multi, "", "json", "Configure the JSON output of the compiler", "<CONFIG>"),
1850 opt(
1851 Stable,
1852 Opt,
1853 "",
1854 "color",
1855 "Configure coloring of output:
1856 * auto = colorize, if output goes to a tty (default);
1857 * always = always colorize output;
1858 * never = never colorize output",
1859 "<auto|always|never>",
1860 ),
1861 opt(
1862 Stable,
1863 Opt,
1864 "",
1865 "diagnostic-width",
1866 "Inform rustc of the width of the output so that diagnostics can be truncated to fit",
1867 "<WIDTH>",
1868 ),
1869 opt(
1870 Stable,
1871 Multi,
1872 "",
1873 "remap-path-prefix",
1874 "Remap source names in all output (compiler messages and output files)",
1875 "<FROM>=<TO>",
1876 ),
1877 opt(
1878 Stable,
1879 Opt,
1880 "",
1881 "remap-path-scope",
1882 "Defines which scopes of paths should be remapped by `--remap-path-prefix`",
1883 "<macro,diagnostics,debuginfo,coverage,object,all>",
1884 ),
1885 opt(Unstable, Multi, "", "env-set", "Inject an environment variable", "<VAR>=<VALUE>"),
1886 ];
1887 options.extend(verbose_only.into_iter().map(|mut opt| {
1888 opt.is_verbose_help_only = true;
1889 opt
1890 }));
1891
1892 options
1893}
1894
1895pub fn get_cmd_lint_options(
1896 early_dcx: &EarlyDiagCtxt,
1897 matches: &getopts::Matches,
1898) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
1899 let mut lint_opts_with_position = ::alloc::vec::Vec::new()vec![];
1900 let mut describe_lints = false;
1901
1902 for level in [lint::Allow, lint::Warn, lint::ForceWarn, lint::Deny, lint::Forbid] {
1903 for (arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
1904 if lint_name == "help" {
1905 describe_lints = true;
1906 } else {
1907 lint_opts_with_position.push((arg_pos, lint_name.replace('-', "_"), level));
1908 }
1909 }
1910 }
1911
1912 lint_opts_with_position.sort_by_key(|x| x.0);
1913 let lint_opts = lint_opts_with_position
1914 .iter()
1915 .cloned()
1916 .map(|(_, lint_name, level)| (lint_name, level))
1917 .collect();
1918
1919 let lint_cap = matches.opt_str("cap-lints").map(|cap| {
1920 lint::Level::from_str(&cap)
1921 .unwrap_or_else(|| early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("unknown lint level: `{0}`", cap))
})format!("unknown lint level: `{cap}`")))
1922 });
1923
1924 (lint_opts, describe_lints, lint_cap)
1925}
1926
1927pub fn parse_color(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> ColorConfig {
1929 match matches.opt_str("color").as_deref() {
1930 Some("auto") => ColorConfig::Auto,
1931 Some("always") => ColorConfig::Always,
1932 Some("never") => ColorConfig::Never,
1933
1934 None => ColorConfig::Auto,
1935
1936 Some(arg) => early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("argument for `--color` must be auto, always or never (instead was `{0}`)",
arg))
})format!(
1937 "argument for `--color` must be auto, \
1938 always or never (instead was `{arg}`)"
1939 )),
1940 }
1941}
1942
1943pub struct JsonConfig {
1945 pub json_rendered: HumanReadableErrorType,
1946 pub json_color: ColorConfig,
1947 json_artifact_notifications: bool,
1948 json_timings: bool,
1951 pub json_unused_externs: JsonUnusedExterns,
1952 json_future_incompat: bool,
1953}
1954
1955#[derive(#[automatically_derived]
impl ::core::marker::Copy for JsonUnusedExterns { }Copy, #[automatically_derived]
impl ::core::clone::Clone for JsonUnusedExterns {
#[inline]
fn clone(&self) -> JsonUnusedExterns { *self }
}Clone)]
1957pub enum JsonUnusedExterns {
1958 No,
1960 Silent,
1962 Loud,
1964}
1965
1966impl JsonUnusedExterns {
1967 pub fn is_enabled(&self) -> bool {
1968 match self {
1969 JsonUnusedExterns::No => false,
1970 JsonUnusedExterns::Loud | JsonUnusedExterns::Silent => true,
1971 }
1972 }
1973
1974 pub fn is_loud(&self) -> bool {
1975 match self {
1976 JsonUnusedExterns::No | JsonUnusedExterns::Silent => false,
1977 JsonUnusedExterns::Loud => true,
1978 }
1979 }
1980}
1981
1982pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> JsonConfig {
1987 let mut json_rendered = HumanReadableErrorType { short: false, unicode: false };
1988 let mut json_color = ColorConfig::Never;
1989 let mut json_artifact_notifications = false;
1990 let mut json_unused_externs = JsonUnusedExterns::No;
1991 let mut json_future_incompat = false;
1992 let mut json_timings = false;
1993 for option in matches.opt_strs("json") {
1994 if matches.opt_str("color").is_some() {
1998 early_dcx.early_fatal("cannot specify the `--color` option with `--json`");
1999 }
2000
2001 for sub_option in option.split(',') {
2002 match sub_option {
2003 "diagnostic-short" => {
2004 json_rendered = HumanReadableErrorType { short: true, unicode: false };
2005 }
2006 "diagnostic-unicode" => {
2007 json_rendered = HumanReadableErrorType { short: false, unicode: true };
2008 }
2009 "diagnostic-rendered-ansi" => json_color = ColorConfig::Always,
2010 "artifacts" => json_artifact_notifications = true,
2011 "timings" => json_timings = true,
2012 "unused-externs" => json_unused_externs = JsonUnusedExterns::Loud,
2013 "unused-externs-silent" => json_unused_externs = JsonUnusedExterns::Silent,
2014 "future-incompat" => json_future_incompat = true,
2015 s => early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("unknown `--json` option `{0}`", s))
})format!("unknown `--json` option `{s}`")),
2016 }
2017 }
2018 }
2019
2020 JsonConfig {
2021 json_rendered,
2022 json_color,
2023 json_artifact_notifications,
2024 json_timings,
2025 json_unused_externs,
2026 json_future_incompat,
2027 }
2028}
2029
2030pub fn parse_error_format(
2032 early_dcx: &mut EarlyDiagCtxt,
2033 matches: &getopts::Matches,
2034 color_config: ColorConfig,
2035 json_color: ColorConfig,
2036 json_rendered: HumanReadableErrorType,
2037) -> ErrorOutputType {
2038 let default_kind = HumanReadableErrorType { short: false, unicode: false };
2039 let error_format = if matches.opts_present(&["error-format".to_owned()]) {
2044 match matches.opt_str("error-format").as_deref() {
2045 None | Some("human") => {
2046 ErrorOutputType::HumanReadable { color_config, kind: default_kind }
2047 }
2048 Some("json") => {
2049 ErrorOutputType::Json { pretty: false, json_rendered, color_config: json_color }
2050 }
2051 Some("pretty-json") => {
2052 ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color }
2053 }
2054 Some("short") => ErrorOutputType::HumanReadable {
2055 kind: HumanReadableErrorType { short: true, unicode: false },
2056 color_config,
2057 },
2058 Some("human-unicode") => ErrorOutputType::HumanReadable {
2059 kind: HumanReadableErrorType { short: false, unicode: true },
2060 color_config,
2061 },
2062 Some(arg) => {
2063 early_dcx.set_error_format(ErrorOutputType::HumanReadable {
2064 color_config,
2065 kind: default_kind,
2066 });
2067 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("argument for `--error-format` must be `human`, `human-unicode`, `json`, `pretty-json` or `short` (instead was `{0}`)",
arg))
})format!(
2068 "argument for `--error-format` must be `human`, `human-unicode`, \
2069 `json`, `pretty-json` or `short` (instead was `{arg}`)"
2070 ))
2071 }
2072 }
2073 } else {
2074 ErrorOutputType::HumanReadable { color_config, kind: default_kind }
2075 };
2076
2077 match error_format {
2078 ErrorOutputType::Json { .. } => {}
2079
2080 _ if !matches.opt_strs("json").is_empty() => {
2084 early_dcx.early_fatal("using `--json` requires also using `--error-format=json`");
2085 }
2086
2087 _ => {}
2088 }
2089
2090 error_format
2091}
2092
2093pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Edition {
2094 let edition = match matches.opt_str("edition") {
2095 Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| {
2096 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("argument for `--edition` must be one of: {0}. (instead was `{1}`)",
EDITION_NAME_LIST, arg))
})format!(
2097 "argument for `--edition` must be one of: \
2098 {EDITION_NAME_LIST}. (instead was `{arg}`)"
2099 ))
2100 }),
2101 None => DEFAULT_EDITION,
2102 };
2103
2104 if !edition.is_stable() && !nightly_options::is_unstable_enabled(matches) {
2105 let is_nightly = nightly_options::match_is_nightly_build(matches);
2106 let msg = if !is_nightly {
2107 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the crate requires edition {0}, but the latest edition supported by this Rust version is {1}",
edition, LATEST_STABLE_EDITION))
})format!(
2108 "the crate requires edition {edition}, but the latest edition supported by this Rust version is {LATEST_STABLE_EDITION}"
2109 )
2110 } else {
2111 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("edition {0} is unstable and only available with -Z unstable-options",
edition))
})format!("edition {edition} is unstable and only available with -Z unstable-options")
2112 };
2113 early_dcx.early_fatal(msg)
2114 }
2115
2116 edition
2117}
2118
2119fn check_error_format_stability(
2120 early_dcx: &EarlyDiagCtxt,
2121 unstable_opts: &UnstableOptions,
2122 is_nightly_build: bool,
2123 format: ErrorOutputType,
2124) {
2125 if unstable_opts.unstable_options || is_nightly_build {
2126 return;
2127 }
2128 let format = match format {
2129 ErrorOutputType::Json { pretty: true, .. } => "pretty-json",
2130 ErrorOutputType::HumanReadable { kind, .. } => match kind {
2131 HumanReadableErrorType { unicode: true, .. } => "human-unicode",
2132 _ => return,
2133 },
2134 _ => return,
2135 };
2136 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`--error-format={0}` is unstable",
format))
})format!("`--error-format={format}` is unstable"))
2137}
2138
2139fn parse_output_types(
2140 early_dcx: &EarlyDiagCtxt,
2141 unstable_opts: &UnstableOptions,
2142 matches: &getopts::Matches,
2143) -> OutputTypes {
2144 let mut output_types = BTreeMap::new();
2145 if !unstable_opts.parse_crate_root_only {
2146 for list in matches.opt_strs("emit") {
2147 for output_type in list.split(',') {
2148 let (shorthand, path) = split_out_file_name(output_type);
2149 let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
2150 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("unknown emission type: `{1}` - expected one of: {0}",
OutputType::shorthands_display(), shorthand))
})format!(
2151 "unknown emission type: `{shorthand}` - expected one of: {display}",
2152 display = OutputType::shorthands_display(),
2153 ))
2154 });
2155 if output_type == OutputType::ThinLinkBitcode && !unstable_opts.unstable_options {
2156 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} requested but -Zunstable-options not specified",
OutputType::ThinLinkBitcode.shorthand()))
})format!(
2157 "{} requested but -Zunstable-options not specified",
2158 OutputType::ThinLinkBitcode.shorthand()
2159 ));
2160 }
2161 output_types.insert(output_type, path);
2162 }
2163 }
2164 };
2165 if output_types.is_empty() {
2166 output_types.insert(OutputType::Exe, None);
2167 }
2168 OutputTypes(output_types)
2169}
2170
2171fn split_out_file_name(arg: &str) -> (&str, Option<OutFileName>) {
2172 match arg.split_once('=') {
2173 None => (arg, None),
2174 Some((kind, "-")) => (kind, Some(OutFileName::Stdout)),
2175 Some((kind, path)) => (kind, Some(OutFileName::Real(PathBuf::from(path)))),
2176 }
2177}
2178
2179fn should_override_cgus_and_disable_thinlto(
2180 early_dcx: &EarlyDiagCtxt,
2181 output_types: &OutputTypes,
2182 matches: &getopts::Matches,
2183 mut codegen_units: Option<usize>,
2184) -> (bool, Option<usize>) {
2185 let mut disable_local_thinlto = false;
2186 let incompatible: Vec<_> = output_types
2189 .0
2190 .iter()
2191 .map(|ot_path| ot_path.0)
2192 .filter(|ot| !ot.is_compatible_with_codegen_units_and_single_output_file())
2193 .map(|ot| ot.shorthand())
2194 .collect();
2195 if !incompatible.is_empty() {
2196 match codegen_units {
2197 Some(n) if n > 1 => {
2198 if matches.opt_present("o") {
2199 for ot in &incompatible {
2200 early_dcx.early_warn(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`--emit={0}` with `-o` incompatible with `-C codegen-units=N` for N > 1",
ot))
})format!(
2201 "`--emit={ot}` with `-o` incompatible with \
2202 `-C codegen-units=N` for N > 1",
2203 ));
2204 }
2205 early_dcx.early_warn("resetting to default -C codegen-units=1");
2206 codegen_units = Some(1);
2207 disable_local_thinlto = true;
2208 }
2209 }
2210 _ => {
2211 codegen_units = Some(1);
2212 disable_local_thinlto = true;
2213 }
2214 }
2215 }
2216
2217 if codegen_units == Some(0) {
2218 early_dcx.early_fatal("value for codegen units must be a positive non-zero integer");
2219 }
2220
2221 (disable_local_thinlto, codegen_units)
2222}
2223
2224pub fn parse_target_triple(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> TargetTuple {
2225 match matches.opt_str("target") {
2226 Some(target) if target.ends_with(".json") => {
2227 let path = Path::new(&target);
2228 TargetTuple::from_path(path).unwrap_or_else(|_| {
2229 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("target file {0:?} does not exist",
path))
})format!("target file {path:?} does not exist"))
2230 })
2231 }
2232 Some(target) => TargetTuple::TargetTuple(target),
2233 _ => TargetTuple::from_tuple(host_tuple()),
2234 }
2235}
2236
2237fn parse_opt_level(
2238 early_dcx: &EarlyDiagCtxt,
2239 matches: &getopts::Matches,
2240 cg: &CodegenOptions,
2241) -> OptLevel {
2242 let max_o = matches.opt_positions("O").into_iter().max();
2249 let max_c = matches
2250 .opt_strs_pos("C")
2251 .into_iter()
2252 .flat_map(|(i, s)| {
2253 if let Some("opt-level") = s.split('=').next() { Some(i) } else { None }
2255 })
2256 .max();
2257 if max_o > max_c {
2258 OptLevel::Aggressive
2259 } else {
2260 match cg.opt_level.as_ref() {
2261 "0" => OptLevel::No,
2262 "1" => OptLevel::Less,
2263 "2" => OptLevel::More,
2264 "3" => OptLevel::Aggressive,
2265 "s" => OptLevel::Size,
2266 "z" => OptLevel::SizeMin,
2267 arg => {
2268 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("optimization level needs to be between 0-3, s or z (instead was `{0}`)",
arg))
})format!(
2269 "optimization level needs to be \
2270 between 0-3, s or z (instead was `{arg}`)"
2271 ));
2272 }
2273 }
2274 }
2275}
2276
2277fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInfo {
2278 let max_g = matches.opt_positions("g").into_iter().max();
2279 let max_c = matches
2280 .opt_strs_pos("C")
2281 .into_iter()
2282 .flat_map(|(i, s)| {
2283 if let Some("debuginfo") = s.split('=').next() { Some(i) } else { None }
2285 })
2286 .max();
2287 if max_g > max_c { DebugInfo::Full } else { cg.debuginfo }
2288}
2289
2290pub fn parse_externs(
2291 early_dcx: &EarlyDiagCtxt,
2292 matches: &getopts::Matches,
2293 unstable_opts: &UnstableOptions,
2294) -> Externs {
2295 let is_unstable_enabled = unstable_opts.unstable_options;
2296 let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
2297 for arg in matches.opt_strs("extern") {
2298 let ExternOpt { crate_name: name, path, options } =
2299 split_extern_opt(early_dcx, unstable_opts, &arg).unwrap_or_else(|e| e.emit());
2300
2301 let entry = externs.entry(name.to_owned());
2302
2303 use std::collections::btree_map::Entry;
2304
2305 let entry = if let Some(path) = path {
2306 let path = CanonicalizedPath::new(path);
2308 match entry {
2309 Entry::Vacant(vacant) => {
2310 let files = BTreeSet::from_iter(iter::once(path));
2311 vacant.insert(ExternEntry::new(ExternLocation::ExactPaths(files)))
2312 }
2313 Entry::Occupied(occupied) => {
2314 let ext_ent = occupied.into_mut();
2315 match ext_ent {
2316 ExternEntry { location: ExternLocation::ExactPaths(files), .. } => {
2317 files.insert(path);
2318 }
2319 ExternEntry {
2320 location: location @ ExternLocation::FoundInLibrarySearchDirectories,
2321 ..
2322 } => {
2323 let files = BTreeSet::from_iter(iter::once(path));
2325 *location = ExternLocation::ExactPaths(files);
2326 }
2327 }
2328 ext_ent
2329 }
2330 }
2331 } else {
2332 match entry {
2334 Entry::Vacant(vacant) => {
2335 vacant.insert(ExternEntry::new(ExternLocation::FoundInLibrarySearchDirectories))
2336 }
2337 Entry::Occupied(occupied) => {
2338 occupied.into_mut()
2340 }
2341 }
2342 };
2343
2344 let mut is_private_dep = false;
2345 let mut add_prelude = true;
2346 let mut nounused_dep = false;
2347 let mut force = false;
2348 if let Some(opts) = options {
2349 if !is_unstable_enabled {
2350 early_dcx.early_fatal(
2351 "the `-Z unstable-options` flag must also be passed to \
2352 enable `--extern` options",
2353 );
2354 }
2355 for opt in opts.split(',') {
2356 match opt {
2357 "priv" => is_private_dep = true,
2358 "noprelude" => {
2359 if let ExternLocation::ExactPaths(_) = &entry.location {
2360 add_prelude = false;
2361 } else {
2362 early_dcx.early_fatal(
2363 "the `noprelude` --extern option requires a file path",
2364 );
2365 }
2366 }
2367 "nounused" => nounused_dep = true,
2368 "force" => force = true,
2369 _ => early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("unknown --extern option `{0}`",
opt))
})format!("unknown --extern option `{opt}`")),
2370 }
2371 }
2372 }
2373
2374 entry.is_private_dep |= is_private_dep;
2377 entry.nounused_dep |= nounused_dep;
2379 entry.force |= force;
2381 entry.add_prelude |= add_prelude;
2383 }
2384 Externs(externs)
2385}
2386
2387fn parse_remap_path_prefix(
2388 early_dcx: &EarlyDiagCtxt,
2389 matches: &getopts::Matches,
2390 unstable_opts: &UnstableOptions,
2391) -> Vec<(PathBuf, PathBuf)> {
2392 let mut mapping: Vec<(PathBuf, PathBuf)> = matches
2393 .opt_strs("remap-path-prefix")
2394 .into_iter()
2395 .map(|remap| match remap.rsplit_once('=') {
2396 None => {
2397 early_dcx.early_fatal("--remap-path-prefix must contain '=' between FROM and TO")
2398 }
2399 Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)),
2400 })
2401 .collect();
2402 match &unstable_opts.remap_cwd_prefix {
2403 Some(to) => match std::env::current_dir() {
2404 Ok(cwd) => mapping.push((cwd, to.clone())),
2405 Err(_) => (),
2406 },
2407 None => (),
2408 };
2409 mapping
2410}
2411
2412fn parse_logical_env(
2413 early_dcx: &EarlyDiagCtxt,
2414 matches: &getopts::Matches,
2415) -> FxIndexMap<String, String> {
2416 let mut vars = FxIndexMap::default();
2417
2418 for arg in matches.opt_strs("env-set") {
2419 if let Some((name, val)) = arg.split_once('=') {
2420 vars.insert(name.to_string(), val.to_string());
2421 } else {
2422 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`--env-set`: specify value for variable `{0}`",
arg))
})format!("`--env-set`: specify value for variable `{arg}`"));
2423 }
2424 }
2425
2426 vars
2427}
2428
2429#[allow(rustc::bad_opt_access)]
2431pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::Matches) -> Options {
2432 let color = parse_color(early_dcx, matches);
2433
2434 let edition = parse_crate_edition(early_dcx, matches);
2435
2436 let crate_name = matches.opt_str("crate-name");
2437 let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
2438 let JsonConfig {
2439 json_rendered,
2440 json_color,
2441 json_artifact_notifications,
2442 json_timings,
2443 json_unused_externs,
2444 json_future_incompat,
2445 } = parse_json(early_dcx, matches);
2446
2447 let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered);
2448
2449 early_dcx.set_error_format(error_format);
2450
2451 let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
2452 early_dcx.early_fatal("`--diagnostic-width` must be an positive integer");
2453 });
2454
2455 let unparsed_crate_types = matches.opt_strs("crate-type");
2456 let crate_types = parse_crate_types_from_list(unparsed_crate_types)
2457 .unwrap_or_else(|e| early_dcx.early_fatal(e));
2458
2459 let mut target_modifiers = BTreeMap::<OptionsTargetModifiers, String>::new();
2460
2461 let mut unstable_opts = UnstableOptions::build(early_dcx, matches, &mut target_modifiers);
2462 let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches);
2463
2464 if !unstable_opts.unstable_options && json_timings {
2465 early_dcx.early_fatal("--json=timings is unstable and requires using `-Zunstable-options`");
2466 }
2467
2468 check_error_format_stability(
2469 early_dcx,
2470 &unstable_opts,
2471 unstable_features.is_nightly_build(),
2472 error_format,
2473 );
2474
2475 let output_types = parse_output_types(early_dcx, &unstable_opts, matches);
2476
2477 let mut cg = CodegenOptions::build(early_dcx, matches, &mut target_modifiers);
2478 let (disable_local_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto(
2479 early_dcx,
2480 &output_types,
2481 matches,
2482 cg.codegen_units,
2483 );
2484
2485 if unstable_opts.threads == 0 {
2486 early_dcx.early_fatal("value for threads must be a positive non-zero integer");
2487 }
2488
2489 if unstable_opts.threads == parse::MAX_THREADS_CAP {
2490 early_dcx.early_warn(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("number of threads was capped at {0}",
parse::MAX_THREADS_CAP))
})format!("number of threads was capped at {}", parse::MAX_THREADS_CAP));
2491 }
2492
2493 let incremental = cg.incremental.as_ref().map(PathBuf::from);
2494
2495 if cg.profile_generate.enabled() && cg.profile_use.is_some() {
2496 early_dcx.early_fatal("options `-C profile-generate` and `-C profile-use` are exclusive");
2497 }
2498
2499 if unstable_opts.profile_sample_use.is_some()
2500 && (cg.profile_generate.enabled() || cg.profile_use.is_some())
2501 {
2502 early_dcx.early_fatal(
2503 "option `-Z profile-sample-use` cannot be used with `-C profile-generate` or `-C profile-use`",
2504 );
2505 }
2506
2507 match cg.symbol_mangling_version {
2510 None | Some(SymbolManglingVersion::V0) => {}
2512
2513 Some(SymbolManglingVersion::Legacy) => {
2515 if !unstable_opts.unstable_options {
2516 early_dcx.early_fatal(
2517 "`-C symbol-mangling-version=legacy` requires `-Z unstable-options`",
2518 );
2519 }
2520 }
2521 Some(SymbolManglingVersion::Hashed) => {
2522 if !unstable_opts.unstable_options {
2523 early_dcx.early_fatal(
2524 "`-C symbol-mangling-version=hashed` requires `-Z unstable-options`",
2525 );
2526 }
2527 }
2528 }
2529
2530 if cg.instrument_coverage != InstrumentCoverage::No {
2531 if cg.profile_generate.enabled() || cg.profile_use.is_some() {
2532 early_dcx.early_fatal(
2533 "option `-C instrument-coverage` is not compatible with either `-C profile-use` \
2534 or `-C profile-generate`",
2535 );
2536 }
2537
2538 match cg.symbol_mangling_version {
2543 None => cg.symbol_mangling_version = Some(SymbolManglingVersion::V0),
2544 Some(SymbolManglingVersion::Legacy) => {
2545 early_dcx.early_warn(
2546 "-C instrument-coverage requires symbol mangling version `v0`, \
2547 but `-C symbol-mangling-version=legacy` was specified",
2548 );
2549 }
2550 Some(SymbolManglingVersion::V0) => {}
2551 Some(SymbolManglingVersion::Hashed) => {
2552 early_dcx.early_warn(
2553 "-C instrument-coverage requires symbol mangling version `v0`, \
2554 but `-C symbol-mangling-version=hashed` was specified",
2555 );
2556 }
2557 }
2558 }
2559
2560 if let Ok(graphviz_font) = std::env::var("RUSTC_GRAPHVIZ_FONT") {
2561 unstable_opts.graphviz_font = graphviz_font;
2564 }
2565
2566 if !cg.embed_bitcode {
2567 match cg.lto {
2568 LtoCli::No | LtoCli::Unspecified => {}
2569 LtoCli::Yes | LtoCli::NoParam | LtoCli::Thin | LtoCli::Fat => {
2570 early_dcx.early_fatal("options `-C embed-bitcode=no` and `-C lto` are incompatible")
2571 }
2572 }
2573 }
2574
2575 let unstable_options_enabled = nightly_options::is_unstable_enabled(matches);
2576 if !unstable_options_enabled && cg.force_frame_pointers == FramePointer::NonLeaf {
2577 early_dcx.early_fatal(
2578 "`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \
2579 and a nightly compiler",
2580 )
2581 }
2582
2583 if !nightly_options::is_unstable_enabled(matches) && !unstable_opts.offload.is_empty() {
2584 early_dcx.early_fatal(
2585 "`-Zoffload=Enable` also requires `-Zunstable-options` \
2586 and a nightly compiler",
2587 )
2588 }
2589
2590 let target_triple = parse_target_triple(early_dcx, matches);
2591
2592 if !unstable_options_enabled {
2595 if let Err(error) = cg.link_self_contained.check_unstable_variants(&target_triple) {
2596 early_dcx.early_fatal(error);
2597 }
2598
2599 if let Some(flavor) = cg.linker_flavor {
2600 if flavor.is_unstable() {
2601 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the linker flavor `{0}` is unstable, the `-Z unstable-options` flag must also be passed to use the unstable values",
flavor.desc()))
})format!(
2602 "the linker flavor `{}` is unstable, the `-Z unstable-options` \
2603 flag must also be passed to use the unstable values",
2604 flavor.desc()
2605 ));
2606 }
2607 }
2608 }
2609
2610 if let Some(erroneous_components) = cg.link_self_contained.check_consistency() {
2613 let names: String = erroneous_components
2614 .into_iter()
2615 .map(|c| c.as_str().unwrap())
2616 .intersperse(", ")
2617 .collect();
2618 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("some `-C link-self-contained` components were both enabled and disabled: {0}",
names))
})format!(
2619 "some `-C link-self-contained` components were both enabled and disabled: {names}"
2620 ));
2621 }
2622
2623 let prints = print_request::collect_print_requests(early_dcx, &mut cg, &unstable_opts, matches);
2624
2625 if unstable_opts.retpoline_external_thunk {
2627 unstable_opts.retpoline = true;
2628 target_modifiers.insert(
2629 OptionsTargetModifiers::UnstableOptions(UnstableOptionsTargetModifiers::retpoline),
2630 "true".to_string(),
2631 );
2632 }
2633
2634 let cg = cg;
2635
2636 let opt_level = parse_opt_level(early_dcx, matches, &cg);
2637 let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
2641 let debuginfo = select_debuginfo(matches, &cg);
2642
2643 if !unstable_options_enabled {
2644 if let Err(error) = cg.linker_features.check_unstable_variants(&target_triple) {
2645 early_dcx.early_fatal(error);
2646 }
2647 }
2648
2649 if !unstable_options_enabled && cg.panic == Some(PanicStrategy::ImmediateAbort) {
2650 early_dcx.early_fatal(
2651 "`-Cpanic=immediate-abort` requires `-Zunstable-options` and a nightly compiler",
2652 )
2653 }
2654
2655 let libs = parse_native_libs(early_dcx, &unstable_opts, unstable_features, matches);
2657
2658 let test = matches.opt_present("test");
2659
2660 if !cg.remark.is_empty() && debuginfo == DebugInfo::None {
2661 early_dcx.early_warn("-C remark requires \"-C debuginfo=n\" to show source locations");
2662 }
2663
2664 if cg.remark.is_empty() && unstable_opts.remark_dir.is_some() {
2665 early_dcx
2666 .early_warn("using -Z remark-dir without enabling remarks using e.g. -C remark=all");
2667 }
2668
2669 let externs = parse_externs(early_dcx, matches, &unstable_opts);
2670
2671 let remap_path_prefix = parse_remap_path_prefix(early_dcx, matches, &unstable_opts);
2672 let remap_path_scope = parse_remap_path_scope(early_dcx, matches, &unstable_opts);
2673
2674 let pretty = parse_pretty(early_dcx, &unstable_opts);
2675
2676 if unstable_opts.dump_dep_graph && !unstable_opts.query_dep_graph {
2678 early_dcx.early_fatal("can't dump dependency graph without `-Z query-dep-graph`");
2679 }
2680
2681 let logical_env = parse_logical_env(early_dcx, matches);
2682
2683 let sysroot = Sysroot::new(matches.opt_str("sysroot").map(PathBuf::from));
2684
2685 let real_source_base_dir = |suffix: &str, confirm: &str| {
2686 let mut candidate = sysroot.path().join(suffix);
2687 if let Ok(metadata) = candidate.symlink_metadata() {
2688 if metadata.file_type().is_symlink() {
2692 if let Ok(symlink_dest) = std::fs::read_link(&candidate) {
2693 candidate = symlink_dest;
2694 }
2695 }
2696 }
2697
2698 candidate.join(confirm).is_file().then_some(candidate)
2700 };
2701
2702 let real_rust_source_base_dir =
2703 real_source_base_dir("lib/rustlib/src/rust", "library/std/src/lib.rs");
2705
2706 let real_rustc_dev_source_base_dir =
2707 real_source_base_dir("lib/rustlib/rustc-src/rust", "compiler/rustc/src/main.rs");
2709
2710 let search_paths: Vec<SearchPath> = {
2715 let mut seen_search_paths = FxHashSet::default();
2716 let search_path_matches: Vec<String> = matches.opt_strs("L");
2717 search_path_matches
2718 .iter()
2719 .filter(|p| seen_search_paths.insert(*p))
2720 .map(|path| {
2721 SearchPath::from_cli_opt(
2722 sysroot.path(),
2723 &target_triple,
2724 early_dcx,
2725 &path,
2726 unstable_opts.unstable_options,
2727 )
2728 })
2729 .collect()
2730 };
2731
2732 let working_dir = {
2735 let working_dir = std::env::current_dir().unwrap_or_else(|e| {
2736 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("Current directory is invalid: {0}",
e))
})format!("Current directory is invalid: {e}"));
2737 });
2738
2739 let file_mapping = file_path_mapping(remap_path_prefix.clone(), remap_path_scope);
2740 file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
2741 };
2742
2743 let verbose = matches.opt_present("verbose") || unstable_opts.verbose_internals;
2744
2745 Options {
2746 crate_types,
2747 optimize: opt_level,
2748 debuginfo,
2749 lint_opts,
2750 lint_cap,
2751 describe_lints,
2752 output_types,
2753 search_paths,
2754 sysroot,
2755 target_triple,
2756 test,
2757 incremental,
2758 untracked_state_hash: Default::default(),
2759 unstable_opts,
2760 prints,
2761 cg,
2762 error_format,
2763 diagnostic_width,
2764 externs,
2765 unstable_features,
2766 crate_name,
2767 libs,
2768 debug_assertions,
2769 actually_rustdoc: false,
2770 resolve_doc_links: ResolveDocLinks::ExportedMetadata,
2771 trimmed_def_paths: false,
2772 cli_forced_codegen_units: codegen_units,
2773 cli_forced_local_thinlto_off: disable_local_thinlto,
2774 remap_path_prefix,
2775 remap_path_scope,
2776 real_rust_source_base_dir,
2777 real_rustc_dev_source_base_dir,
2778 edition,
2779 json_artifact_notifications,
2780 json_timings,
2781 json_unused_externs,
2782 json_future_incompat,
2783 pretty,
2784 working_dir,
2785 color,
2786 logical_env,
2787 verbose,
2788 target_modifiers,
2789 }
2790}
2791
2792fn parse_pretty(early_dcx: &EarlyDiagCtxt, unstable_opts: &UnstableOptions) -> Option<PpMode> {
2793 use PpMode::*;
2794
2795 let first = match unstable_opts.unpretty.as_deref()? {
2796 "normal" => Source(PpSourceMode::Normal),
2797 "identified" => Source(PpSourceMode::Identified),
2798 "expanded" => Source(PpSourceMode::Expanded),
2799 "expanded,identified" => Source(PpSourceMode::ExpandedIdentified),
2800 "expanded,hygiene" => Source(PpSourceMode::ExpandedHygiene),
2801 "ast-tree" => AstTree,
2802 "ast-tree,expanded" => AstTreeExpanded,
2803 "hir" => Hir(PpHirMode::Normal),
2804 "hir,identified" => Hir(PpHirMode::Identified),
2805 "hir,typed" => Hir(PpHirMode::Typed),
2806 "hir-tree" => HirTree,
2807 "thir-tree" => ThirTree,
2808 "thir-flat" => ThirFlat,
2809 "mir" => Mir,
2810 "stable-mir" => StableMir,
2811 "mir-cfg" => MirCFG,
2812 name => early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("argument to `unpretty` must be one of `normal`, `identified`, `expanded`, `expanded,identified`, `expanded,hygiene`, `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, `hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir`, `stable-mir`, or `mir-cfg`; got {0}",
name))
})format!(
2813 "argument to `unpretty` must be one of `normal`, `identified`, \
2814 `expanded`, `expanded,identified`, `expanded,hygiene`, \
2815 `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
2816 `hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir`, `stable-mir`, or \
2817 `mir-cfg`; got {name}"
2818 )),
2819 };
2820 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_session/src/config.rs:2820",
"rustc_session::config", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_session/src/config.rs"),
::tracing_core::__macro_support::Option::Some(2820u32),
::tracing_core::__macro_support::Option::Some("rustc_session::config"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("got unpretty option: {0:?}",
first) as &dyn Value))])
});
} else { ; }
};debug!("got unpretty option: {first:?}");
2821 Some(first)
2822}
2823
2824pub fn make_crate_type_option() -> RustcOptGroup {
2825 make_opt(
2826 OptionStability::Stable,
2827 OptionKind::Multi,
2828 "",
2829 "crate-type",
2830 "Comma separated list of types of crates
2831 for the compiler to emit",
2832 "<bin|lib|rlib|dylib|cdylib|staticlib|proc-macro>",
2833 )
2834}
2835
2836pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> {
2837 let mut crate_types: Vec<CrateType> = Vec::new();
2838 for unparsed_crate_type in &list_list {
2839 for part in unparsed_crate_type.split(',') {
2840 let new_part = match part {
2841 "lib" => CrateType::default(),
2842 "rlib" => CrateType::Rlib,
2843 "staticlib" => CrateType::StaticLib,
2844 "dylib" => CrateType::Dylib,
2845 "cdylib" => CrateType::Cdylib,
2846 "bin" => CrateType::Executable,
2847 "proc-macro" => CrateType::ProcMacro,
2848 "sdylib" => CrateType::Sdylib,
2849 _ => {
2850 return Err(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("unknown crate type: `{0}`, expected one of: `lib`, `rlib`, `staticlib`, `dylib`, `cdylib`, `bin`, `proc-macro`",
part))
})format!(
2851 "unknown crate type: `{part}`, expected one of: \
2852 `lib`, `rlib`, `staticlib`, `dylib`, `cdylib`, `bin`, `proc-macro`",
2853 ));
2854 }
2855 };
2856 if !crate_types.contains(&new_part) {
2857 crate_types.push(new_part)
2858 }
2859 }
2860 }
2861
2862 Ok(crate_types)
2863}
2864
2865pub mod nightly_options {
2866 use rustc_feature::UnstableFeatures;
2867
2868 use super::{OptionStability, RustcOptGroup};
2869 use crate::EarlyDiagCtxt;
2870
2871 pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
2872 match_is_nightly_build(matches)
2873 && matches.opt_strs("Z").iter().any(|x| *x == "unstable-options")
2874 }
2875
2876 pub fn match_is_nightly_build(matches: &getopts::Matches) -> bool {
2877 is_nightly_build(matches.opt_str("crate-name").as_deref())
2878 }
2879
2880 fn is_nightly_build(krate: Option<&str>) -> bool {
2881 UnstableFeatures::from_environment(krate).is_nightly_build()
2882 }
2883
2884 pub fn check_nightly_options(
2885 early_dcx: &EarlyDiagCtxt,
2886 matches: &getopts::Matches,
2887 flags: &[RustcOptGroup],
2888 ) {
2889 let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options");
2890 let really_allows_unstable_options = match_is_nightly_build(matches);
2891 let mut nightly_options_on_stable = 0;
2892
2893 for opt in flags.iter() {
2894 if opt.stability == OptionStability::Stable {
2895 continue;
2896 }
2897 if !matches.opt_present(opt.name) {
2898 continue;
2899 }
2900 if opt.name != "Z" && !has_z_unstable_option {
2901 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the `-Z unstable-options` flag must also be passed to enable the flag `{0}`",
opt.name))
})format!(
2902 "the `-Z unstable-options` flag must also be passed to enable \
2903 the flag `{}`",
2904 opt.name
2905 ));
2906 }
2907 if really_allows_unstable_options {
2908 continue;
2909 }
2910 match opt.stability {
2911 OptionStability::Unstable => {
2912 nightly_options_on_stable += 1;
2913 let msg = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the option `{0}` is only accepted on the nightly compiler",
opt.name))
})format!(
2914 "the option `{}` is only accepted on the nightly compiler",
2915 opt.name
2916 );
2917 let _ = early_dcx.early_err(msg);
2919 }
2920 OptionStability::Stable => {}
2921 }
2922 }
2923 if nightly_options_on_stable > 0 {
2924 early_dcx
2925 .early_help("consider switching to a nightly toolchain: `rustup default nightly`");
2926 early_dcx.early_note("selecting a toolchain with `+toolchain` arguments require a rustup proxy; see <https://rust-lang.github.io/rustup/concepts/index.html>");
2927 early_dcx.early_note("for more information about Rust's stability policy, see <https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#unstable-features>");
2928 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} nightly option{1} were parsed",
nightly_options_on_stable,
if nightly_options_on_stable > 1 { "s" } else { "" }))
})format!(
2929 "{} nightly option{} were parsed",
2930 nightly_options_on_stable,
2931 if nightly_options_on_stable > 1 { "s" } else { "" }
2932 ));
2933 }
2934 }
2935}
2936
2937#[derive(#[automatically_derived]
impl ::core::marker::Copy for PpSourceMode { }Copy, #[automatically_derived]
impl ::core::clone::Clone for PpSourceMode {
#[inline]
fn clone(&self) -> PpSourceMode { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for PpSourceMode {
#[inline]
fn eq(&self, other: &PpSourceMode) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for PpSourceMode {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
PpSourceMode::Normal => "Normal",
PpSourceMode::Expanded => "Expanded",
PpSourceMode::Identified => "Identified",
PpSourceMode::ExpandedIdentified => "ExpandedIdentified",
PpSourceMode::ExpandedHygiene => "ExpandedHygiene",
})
}
}Debug)]
2938pub enum PpSourceMode {
2939 Normal,
2941 Expanded,
2943 Identified,
2945 ExpandedIdentified,
2947 ExpandedHygiene,
2949}
2950
2951#[derive(#[automatically_derived]
impl ::core::marker::Copy for PpHirMode { }Copy, #[automatically_derived]
impl ::core::clone::Clone for PpHirMode {
#[inline]
fn clone(&self) -> PpHirMode { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for PpHirMode {
#[inline]
fn eq(&self, other: &PpHirMode) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for PpHirMode {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
PpHirMode::Normal => "Normal",
PpHirMode::Identified => "Identified",
PpHirMode::Typed => "Typed",
})
}
}Debug)]
2952pub enum PpHirMode {
2953 Normal,
2955 Identified,
2957 Typed,
2959}
2960
2961#[derive(#[automatically_derived]
impl ::core::marker::Copy for PpMode { }Copy, #[automatically_derived]
impl ::core::clone::Clone for PpMode {
#[inline]
fn clone(&self) -> PpMode {
let _: ::core::clone::AssertParamIsClone<PpSourceMode>;
let _: ::core::clone::AssertParamIsClone<PpHirMode>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for PpMode {
#[inline]
fn eq(&self, other: &PpMode) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(PpMode::Source(__self_0), PpMode::Source(__arg1_0)) =>
__self_0 == __arg1_0,
(PpMode::Hir(__self_0), PpMode::Hir(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for PpMode {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
PpMode::Source(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Source",
&__self_0),
PpMode::AstTree =>
::core::fmt::Formatter::write_str(f, "AstTree"),
PpMode::AstTreeExpanded =>
::core::fmt::Formatter::write_str(f, "AstTreeExpanded"),
PpMode::Hir(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Hir",
&__self_0),
PpMode::HirTree =>
::core::fmt::Formatter::write_str(f, "HirTree"),
PpMode::ThirTree =>
::core::fmt::Formatter::write_str(f, "ThirTree"),
PpMode::ThirFlat =>
::core::fmt::Formatter::write_str(f, "ThirFlat"),
PpMode::Mir => ::core::fmt::Formatter::write_str(f, "Mir"),
PpMode::MirCFG => ::core::fmt::Formatter::write_str(f, "MirCFG"),
PpMode::StableMir =>
::core::fmt::Formatter::write_str(f, "StableMir"),
}
}
}Debug)]
2962pub enum PpMode {
2964 Source(PpSourceMode),
2967 AstTree,
2969 AstTreeExpanded,
2971 Hir(PpHirMode),
2973 HirTree,
2975 ThirTree,
2977 ThirFlat,
2979 Mir,
2981 MirCFG,
2983 StableMir,
2985}
2986
2987impl PpMode {
2988 pub fn needs_ast_map(&self) -> bool {
2989 use PpMode::*;
2990 use PpSourceMode::*;
2991 match *self {
2992 Source(Normal | Identified) | AstTree => false,
2993
2994 Source(Expanded | ExpandedIdentified | ExpandedHygiene)
2995 | AstTreeExpanded
2996 | Hir(_)
2997 | HirTree
2998 | ThirTree
2999 | ThirFlat
3000 | Mir
3001 | MirCFG
3002 | StableMir => true,
3003 }
3004 }
3005
3006 pub fn needs_analysis(&self) -> bool {
3007 use PpMode::*;
3008 #[allow(non_exhaustive_omitted_patterns)] match *self {
Hir(PpHirMode::Typed) | Mir | StableMir | MirCFG | ThirTree | ThirFlat =>
true,
_ => false,
}matches!(*self, Hir(PpHirMode::Typed) | Mir | StableMir | MirCFG | ThirTree | ThirFlat)
3009 }
3010}
3011
3012#[derive(#[automatically_derived]
impl ::core::clone::Clone for WasiExecModel {
#[inline]
fn clone(&self) -> WasiExecModel {
match self {
WasiExecModel::Command => WasiExecModel::Command,
WasiExecModel::Reactor => WasiExecModel::Reactor,
}
}
}Clone, #[automatically_derived]
impl ::core::hash::Hash for WasiExecModel {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::cmp::PartialEq for WasiExecModel {
#[inline]
fn eq(&self, other: &WasiExecModel) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for WasiExecModel {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for WasiExecModel {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
WasiExecModel::Command => "Command",
WasiExecModel::Reactor => "Reactor",
})
}
}Debug)]
3013pub enum WasiExecModel {
3014 Command,
3015 Reactor,
3016}
3017
3018pub(crate) mod dep_tracking {
3037 use std::collections::BTreeMap;
3038 use std::hash::Hash;
3039 use std::num::NonZero;
3040 use std::path::PathBuf;
3041
3042 use rustc_abi::Align;
3043 use rustc_data_structures::fx::FxIndexMap;
3044 use rustc_data_structures::stable_hasher::StableHasher;
3045 use rustc_errors::LanguageIdentifier;
3046 use rustc_feature::UnstableFeatures;
3047 use rustc_hashes::Hash64;
3048 use rustc_hir::attrs::CollapseMacroDebuginfo;
3049 use rustc_span::edition::Edition;
3050 use rustc_span::{RealFileName, RemapPathScopeComponents};
3051 use rustc_target::spec::{
3052 CodeModel, FramePointer, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel,
3053 RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility, TargetTuple,
3054 TlsModel,
3055 };
3056
3057 use super::{
3058 AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CoverageOptions,
3059 CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn,
3060 InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
3061 LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, OutFileName, OutputType,
3062 OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks, SourceFileHashAlgorithm,
3063 SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
3064 };
3065 use crate::lint;
3066 use crate::utils::NativeLib;
3067
3068 pub(crate) trait DepTrackingHash {
3069 fn hash(
3070 &self,
3071 hasher: &mut StableHasher,
3072 error_format: ErrorOutputType,
3073 for_crate_hash: bool,
3074 );
3075 }
3076
3077 macro_rules! impl_dep_tracking_hash_via_hash {
3078 ($($t:ty),+ $(,)?) => {$(
3079 impl DepTrackingHash for $t {
3080 fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType, _for_crate_hash: bool) {
3081 Hash::hash(self, hasher);
3082 }
3083 }
3084 )+};
3085 }
3086
3087 impl<T: DepTrackingHash> DepTrackingHash for Option<T> {
3088 fn hash(
3089 &self,
3090 hasher: &mut StableHasher,
3091 error_format: ErrorOutputType,
3092 for_crate_hash: bool,
3093 ) {
3094 match self {
3095 Some(x) => {
3096 Hash::hash(&1, hasher);
3097 DepTrackingHash::hash(x, hasher, error_format, for_crate_hash);
3098 }
3099 None => Hash::hash(&0, hasher),
3100 }
3101 }
3102 }
3103
3104 impl DepTrackingHash for Align {
fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
_for_crate_hash: bool) {
Hash::hash(self, hasher);
}
}impl_dep_tracking_hash_via_hash!(
3105 (),
3106 AnnotateMoves,
3107 AutoDiff,
3108 Offload,
3109 bool,
3110 usize,
3111 NonZero<usize>,
3112 u64,
3113 Hash64,
3114 String,
3115 PathBuf,
3116 lint::Level,
3117 WasiExecModel,
3118 u32,
3119 FramePointer,
3120 RelocModel,
3121 CodeModel,
3122 TlsModel,
3123 InstrumentCoverage,
3124 CoverageOptions,
3125 InstrumentXRay,
3126 CrateType,
3127 MergeFunctions,
3128 OnBrokenPipe,
3129 PanicStrategy,
3130 RelroLevel,
3131 OptLevel,
3132 LtoCli,
3133 DebugInfo,
3134 DebugInfoCompression,
3135 MirStripDebugInfo,
3136 CollapseMacroDebuginfo,
3137 UnstableFeatures,
3138 NativeLib,
3139 SanitizerSet,
3140 CFGuard,
3141 CFProtection,
3142 TargetTuple,
3143 Edition,
3144 LinkerPluginLto,
3145 ResolveDocLinks,
3146 SplitDebuginfo,
3147 SplitDwarfKind,
3148 StackProtector,
3149 SwitchWithOptPath,
3150 SymbolManglingVersion,
3151 SymbolVisibility,
3152 RemapPathScopeComponents,
3153 SourceFileHashAlgorithm,
3154 OutFileName,
3155 OutputType,
3156 RealFileName,
3157 LocationDetail,
3158 FmtDebug,
3159 BranchProtection,
3160 LanguageIdentifier,
3161 NextSolverConfig,
3162 PatchableFunctionEntry,
3163 Polonius,
3164 InliningThreshold,
3165 FunctionReturn,
3166 Align,
3167 );
3168
3169 impl<T1, T2> DepTrackingHash for (T1, T2)
3170 where
3171 T1: DepTrackingHash,
3172 T2: DepTrackingHash,
3173 {
3174 fn hash(
3175 &self,
3176 hasher: &mut StableHasher,
3177 error_format: ErrorOutputType,
3178 for_crate_hash: bool,
3179 ) {
3180 Hash::hash(&0, hasher);
3181 DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash);
3182 Hash::hash(&1, hasher);
3183 DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash);
3184 }
3185 }
3186
3187 impl<T1, T2, T3> DepTrackingHash for (T1, T2, T3)
3188 where
3189 T1: DepTrackingHash,
3190 T2: DepTrackingHash,
3191 T3: DepTrackingHash,
3192 {
3193 fn hash(
3194 &self,
3195 hasher: &mut StableHasher,
3196 error_format: ErrorOutputType,
3197 for_crate_hash: bool,
3198 ) {
3199 Hash::hash(&0, hasher);
3200 DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash);
3201 Hash::hash(&1, hasher);
3202 DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash);
3203 Hash::hash(&2, hasher);
3204 DepTrackingHash::hash(&self.2, hasher, error_format, for_crate_hash);
3205 }
3206 }
3207
3208 impl<T: DepTrackingHash> DepTrackingHash for Vec<T> {
3209 fn hash(
3210 &self,
3211 hasher: &mut StableHasher,
3212 error_format: ErrorOutputType,
3213 for_crate_hash: bool,
3214 ) {
3215 Hash::hash(&self.len(), hasher);
3216 for (index, elem) in self.iter().enumerate() {
3217 Hash::hash(&index, hasher);
3218 DepTrackingHash::hash(elem, hasher, error_format, for_crate_hash);
3219 }
3220 }
3221 }
3222
3223 impl<T: DepTrackingHash, V: DepTrackingHash> DepTrackingHash for FxIndexMap<T, V> {
3224 fn hash(
3225 &self,
3226 hasher: &mut StableHasher,
3227 error_format: ErrorOutputType,
3228 for_crate_hash: bool,
3229 ) {
3230 Hash::hash(&self.len(), hasher);
3231 for (key, value) in self.iter() {
3232 DepTrackingHash::hash(key, hasher, error_format, for_crate_hash);
3233 DepTrackingHash::hash(value, hasher, error_format, for_crate_hash);
3234 }
3235 }
3236 }
3237
3238 impl DepTrackingHash for OutputTypes {
3239 fn hash(
3240 &self,
3241 hasher: &mut StableHasher,
3242 error_format: ErrorOutputType,
3243 for_crate_hash: bool,
3244 ) {
3245 Hash::hash(&self.0.len(), hasher);
3246 for (key, val) in &self.0 {
3247 DepTrackingHash::hash(key, hasher, error_format, for_crate_hash);
3248 if !for_crate_hash {
3249 DepTrackingHash::hash(val, hasher, error_format, for_crate_hash);
3250 }
3251 }
3252 }
3253 }
3254
3255 pub(crate) fn stable_hash(
3257 sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>,
3258 hasher: &mut StableHasher,
3259 error_format: ErrorOutputType,
3260 for_crate_hash: bool,
3261 ) {
3262 for (key, sub_hash) in sub_hashes {
3263 Hash::hash(&key.len(), hasher);
3266 Hash::hash(key, hasher);
3267 sub_hash.hash(hasher, error_format, for_crate_hash);
3268 }
3269 }
3270}
3271
3272#[derive(#[automatically_derived]
impl ::core::clone::Clone for ProcMacroExecutionStrategy {
#[inline]
fn clone(&self) -> ProcMacroExecutionStrategy { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for ProcMacroExecutionStrategy { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for ProcMacroExecutionStrategy {
#[inline]
fn eq(&self, other: &ProcMacroExecutionStrategy) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for ProcMacroExecutionStrategy {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for ProcMacroExecutionStrategy {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
ProcMacroExecutionStrategy::SameThread => "SameThread",
ProcMacroExecutionStrategy::CrossThread => "CrossThread",
})
}
}Debug)]
3274pub enum ProcMacroExecutionStrategy {
3275 SameThread,
3277
3278 CrossThread,
3280}
3281
3282#[derive(#[automatically_derived]
impl ::core::clone::Clone for DumpMonoStatsFormat {
#[inline]
fn clone(&self) -> DumpMonoStatsFormat { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for DumpMonoStatsFormat { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for DumpMonoStatsFormat {
#[inline]
fn eq(&self, other: &DumpMonoStatsFormat) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for DumpMonoStatsFormat {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for DumpMonoStatsFormat {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
DumpMonoStatsFormat::Markdown => "Markdown",
DumpMonoStatsFormat::Json => "Json",
})
}
}Debug)]
3284pub enum DumpMonoStatsFormat {
3285 Markdown,
3287 Json,
3289}
3290
3291impl DumpMonoStatsFormat {
3292 pub fn extension(self) -> &'static str {
3293 match self {
3294 Self::Markdown => "md",
3295 Self::Json => "json",
3296 }
3297 }
3298}
3299
3300#[derive(#[automatically_derived]
impl ::core::clone::Clone for PatchableFunctionEntry {
#[inline]
fn clone(&self) -> PatchableFunctionEntry {
let _: ::core::clone::AssertParamIsClone<u8>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for PatchableFunctionEntry { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for PatchableFunctionEntry {
#[inline]
fn eq(&self, other: &PatchableFunctionEntry) -> bool {
self.prefix == other.prefix && self.entry == other.entry
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for PatchableFunctionEntry {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.prefix, state);
::core::hash::Hash::hash(&self.entry, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for PatchableFunctionEntry {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"PatchableFunctionEntry", "prefix", &self.prefix, "entry",
&&self.entry)
}
}Debug, #[automatically_derived]
impl ::core::default::Default for PatchableFunctionEntry {
#[inline]
fn default() -> PatchableFunctionEntry {
PatchableFunctionEntry {
prefix: ::core::default::Default::default(),
entry: ::core::default::Default::default(),
}
}
}Default)]
3303pub struct PatchableFunctionEntry {
3304 prefix: u8,
3306 entry: u8,
3308}
3309
3310impl PatchableFunctionEntry {
3311 pub fn from_total_and_prefix_nops(
3312 total_nops: u8,
3313 prefix_nops: u8,
3314 ) -> Option<PatchableFunctionEntry> {
3315 if total_nops < prefix_nops {
3316 None
3317 } else {
3318 Some(Self { prefix: prefix_nops, entry: total_nops - prefix_nops })
3319 }
3320 }
3321 pub fn prefix(&self) -> u8 {
3322 self.prefix
3323 }
3324 pub fn entry(&self) -> u8 {
3325 self.entry
3326 }
3327}
3328
3329#[derive(#[automatically_derived]
impl ::core::clone::Clone for Polonius {
#[inline]
fn clone(&self) -> Polonius { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Polonius { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for Polonius {
#[inline]
fn eq(&self, other: &Polonius) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for Polonius {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Polonius {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
Polonius::Off => "Off",
Polonius::Legacy => "Legacy",
Polonius::Next => "Next",
})
}
}Debug, #[automatically_derived]
impl ::core::default::Default for Polonius {
#[inline]
fn default() -> Polonius { Self::Off }
}Default)]
3332pub enum Polonius {
3333 #[default]
3335 Off,
3336
3337 Legacy,
3339
3340 Next,
3342}
3343
3344impl Polonius {
3345 pub fn is_legacy_enabled(&self) -> bool {
3347 #[allow(non_exhaustive_omitted_patterns)] match self {
Polonius::Legacy => true,
_ => false,
}matches!(self, Polonius::Legacy)
3348 }
3349
3350 pub fn is_next_enabled(&self) -> bool {
3352 #[allow(non_exhaustive_omitted_patterns)] match self {
Polonius::Next => true,
_ => false,
}matches!(self, Polonius::Next)
3353 }
3354}
3355
3356#[derive(#[automatically_derived]
impl ::core::clone::Clone for InliningThreshold {
#[inline]
fn clone(&self) -> InliningThreshold {
let _: ::core::clone::AssertParamIsClone<usize>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for InliningThreshold { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for InliningThreshold {
#[inline]
fn eq(&self, other: &InliningThreshold) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(InliningThreshold::Sometimes(__self_0),
InliningThreshold::Sometimes(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for InliningThreshold {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
InliningThreshold::Sometimes(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
_ => {}
}
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for InliningThreshold {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
InliningThreshold::Always =>
::core::fmt::Formatter::write_str(f, "Always"),
InliningThreshold::Sometimes(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f,
"Sometimes", &__self_0),
InliningThreshold::Never =>
::core::fmt::Formatter::write_str(f, "Never"),
}
}
}Debug)]
3357pub enum InliningThreshold {
3358 Always,
3359 Sometimes(usize),
3360 Never,
3361}
3362
3363impl Default for InliningThreshold {
3364 fn default() -> Self {
3365 Self::Sometimes(100)
3366 }
3367}
3368
3369#[derive(#[automatically_derived]
impl ::core::clone::Clone for FunctionReturn {
#[inline]
fn clone(&self) -> FunctionReturn { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for FunctionReturn { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for FunctionReturn {
#[inline]
fn eq(&self, other: &FunctionReturn) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for FunctionReturn {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for FunctionReturn {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
FunctionReturn::Keep => "Keep",
FunctionReturn::ThunkExtern => "ThunkExtern",
})
}
}Debug, #[automatically_derived]
impl ::core::default::Default for FunctionReturn {
#[inline]
fn default() -> FunctionReturn { Self::Keep }
}Default)]
3371pub enum FunctionReturn {
3372 #[default]
3374 Keep,
3375
3376 ThunkExtern,
3378}
3379
3380#[derive(#[automatically_derived]
impl ::core::clone::Clone for MirIncludeSpans {
#[inline]
fn clone(&self) -> MirIncludeSpans { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for MirIncludeSpans { }Copy, #[automatically_derived]
impl ::core::default::Default for MirIncludeSpans {
#[inline]
fn default() -> MirIncludeSpans { Self::Nll }
}Default, #[automatically_derived]
impl ::core::cmp::PartialEq for MirIncludeSpans {
#[inline]
fn eq(&self, other: &MirIncludeSpans) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for MirIncludeSpans {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
MirIncludeSpans::Off => "Off",
MirIncludeSpans::On => "On",
MirIncludeSpans::Nll => "Nll",
})
}
}Debug)]
3383pub enum MirIncludeSpans {
3384 Off,
3385 On,
3386 #[default]
3389 Nll,
3390}
3391
3392impl MirIncludeSpans {
3393 pub fn is_enabled(self) -> bool {
3398 self == MirIncludeSpans::On
3399 }
3400}