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::num::NonZero;
11use std::path::{Path, PathBuf};
12use std::str::{self, FromStr};
13use std::sync::LazyLock;
14use std::{cmp, fs, iter, thread};
15
16use externs::{ExternOpt, split_extern_opt};
17use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
18use rustc_data_structures::stable_hash::{StableHasher, StableOrd};
19use rustc_errors::emitter::HumanReadableErrorType;
20use rustc_errors::{ColorConfig, DiagCtxtFlags};
21use rustc_feature::UnstableFeatures;
22use rustc_hashes::Hash64;
23use rustc_macros::{BlobDecodable, Decodable, Encodable, StableHash};
24use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION};
25use rustc_span::source_map::FilePathMapping;
26use rustc_span::{
27 FileName, RealFileName, RemapPathScopeComponents, SourceFileHashAlgorithm, Symbol, sym,
28};
29use rustc_target::spec::{
30 FramePointer, LinkSelfContainedComponents, LinkerFeatures, PanicStrategy, SplitDebuginfo,
31 Target, TargetTuple,
32};
33use tracing::debug;
34
35pub use crate::config::cfg::{Cfg, CheckCfg, ExpectedValues};
36use crate::config::native_libs::parse_native_libs;
37pub use crate::config::print_request::{PrintKind, PrintRequest};
38use crate::diagnostics::FileWriteFail;
39pub use crate::options::*;
40use crate::search_paths::SearchPath;
41use crate::utils::CanonicalizedPath;
42use crate::{EarlyDiagCtxt, Session, filesearch, lint};
43
44mod cfg;
45mod externs;
46mod native_libs;
47mod print_request;
48pub mod sigpipe;
49
50pub const NATIVE_CPU: &str = "native";
52
53#[derive(#[automatically_derived]
impl ::core::clone::Clone for Strip {
#[inline]
fn clone(&self) -> Strip { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Strip { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for Strip {
#[inline]
fn eq(&self, other: &Strip) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for Strip {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for Strip {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
Strip::None => "None",
Strip::Debuginfo => "Debuginfo",
Strip::Symbols => "Symbols",
})
}
}Debug)]
55pub enum Strip {
56 None,
58
59 Debuginfo,
61
62 Symbols,
64}
65
66#[derive(#[automatically_derived]
impl ::core::clone::Clone for CFGuard {
#[inline]
fn clone(&self) -> CFGuard { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CFGuard { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for CFGuard {
#[inline]
fn eq(&self, other: &CFGuard) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for CFGuard {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for CFGuard {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
CFGuard::Disabled => "Disabled",
CFGuard::NoChecks => "NoChecks",
CFGuard::Checks => "Checks",
})
}
}Debug)]
68pub enum CFGuard {
69 Disabled,
71
72 NoChecks,
74
75 Checks,
77}
78
79#[derive(#[automatically_derived]
impl ::core::clone::Clone for CFProtection {
#[inline]
fn clone(&self) -> CFProtection { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CFProtection { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for CFProtection {
#[inline]
fn eq(&self, other: &CFProtection) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for CFProtection {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for CFProtection {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
CFProtection::None => "None",
CFProtection::Branch => "Branch",
CFProtection::Return => "Return",
CFProtection::Full => "Full",
})
}
}Debug)]
81pub enum CFProtection {
82 None,
84
85 Branch,
87
88 Return,
90
91 Full,
93}
94
95#[derive(#[automatically_derived]
impl ::core::clone::Clone for OptLevel {
#[inline]
fn clone(&self) -> OptLevel { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for OptLevel { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for OptLevel {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
OptLevel::No => "No",
OptLevel::Less => "Less",
OptLevel::More => "More",
OptLevel::Aggressive => "Aggressive",
OptLevel::Size => "Size",
OptLevel::SizeMin => "SizeMin",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for OptLevel {
#[inline]
fn eq(&self, other: &OptLevel) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for OptLevel {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for OptLevel {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
OptLevel::No => {}
OptLevel::Less => {}
OptLevel::More => {}
OptLevel::Aggressive => {}
OptLevel::Size => {}
OptLevel::SizeMin => {}
}
}
}
};StableHash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for OptLevel {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
OptLevel::No => { 0usize }
OptLevel::Less => { 1usize }
OptLevel::More => { 2usize }
OptLevel::Aggressive => { 3usize }
OptLevel::Size => { 4usize }
OptLevel::SizeMin => { 5usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
OptLevel::No => {}
OptLevel::Less => {}
OptLevel::More => {}
OptLevel::Aggressive => {}
OptLevel::Size => {}
OptLevel::SizeMin => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for OptLevel {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { OptLevel::No }
1usize => { OptLevel::Less }
2usize => { OptLevel::More }
3usize => { OptLevel::Aggressive }
4usize => { OptLevel::Size }
5usize => { OptLevel::SizeMin }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `OptLevel`, expected 0..6, actual {0}",
n));
}
}
}
}
};Decodable)]
96pub enum OptLevel {
97 No,
99 Less,
101 More,
103 Aggressive,
105 Size,
107 SizeMin,
109}
110
111#[derive(#[automatically_derived]
impl ::core::clone::Clone for Lto {
#[inline]
fn clone(&self) -> Lto {
match self {
Lto::No => Lto::No,
Lto::Thin => Lto::Thin,
Lto::ThinLocal => Lto::ThinLocal,
Lto::Fat => Lto::Fat,
}
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for Lto {
#[inline]
fn eq(&self, other: &Lto) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for Lto {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
Lto::No => { 0usize }
Lto::Thin => { 1usize }
Lto::ThinLocal => { 2usize }
Lto::Fat => { 3usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
Lto::No => {}
Lto::Thin => {}
Lto::ThinLocal => {}
Lto::Fat => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for Lto {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => { Lto::No }
1usize => { Lto::Thin }
2usize => { Lto::ThinLocal }
3usize => { Lto::Fat }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `Lto`, expected 0..4, actual {0}",
n));
}
}
}
}
};Decodable)]
116pub enum Lto {
117 No,
119
120 Thin,
122
123 ThinLocal,
126
127 Fat,
129}
130
131#[derive(#[automatically_derived]
impl ::core::clone::Clone for LtoCli {
#[inline]
fn clone(&self) -> LtoCli { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for LtoCli { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for LtoCli {
#[inline]
fn eq(&self, other: &LtoCli) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for LtoCli {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for LtoCli {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
LtoCli::No => "No",
LtoCli::Yes => "Yes",
LtoCli::NoParam => "NoParam",
LtoCli::Thin => "Thin",
LtoCli::Fat => "Fat",
LtoCli::Unspecified => "Unspecified",
})
}
}Debug)]
133pub enum LtoCli {
134 No,
136 Yes,
138 NoParam,
140 Thin,
142 Fat,
144 Unspecified,
146}
147
148#[derive(#[automatically_derived]
impl ::core::clone::Clone for InstrumentCoverage {
#[inline]
fn clone(&self) -> InstrumentCoverage { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for InstrumentCoverage { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for InstrumentCoverage {
#[inline]
fn eq(&self, other: &InstrumentCoverage) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for InstrumentCoverage {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for InstrumentCoverage {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
InstrumentCoverage::No => "No",
InstrumentCoverage::Yes => "Yes",
})
}
}Debug)]
150pub enum InstrumentCoverage {
151 No,
153 Yes,
155}
156
157#[derive(#[automatically_derived]
impl ::core::clone::Clone for CoverageOptions {
#[inline]
fn clone(&self) -> CoverageOptions {
let _: ::core::clone::AssertParamIsClone<CoverageLevel>;
let _: ::core::clone::AssertParamIsClone<bool>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CoverageOptions { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for CoverageOptions {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"CoverageOptions", "level", &self.level,
"discard_all_spans_in_codegen",
&&self.discard_all_spans_in_codegen)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for CoverageOptions {
#[inline]
fn eq(&self, other: &CoverageOptions) -> bool {
self.discard_all_spans_in_codegen ==
other.discard_all_spans_in_codegen &&
self.level == other.level
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for CoverageOptions {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<CoverageLevel>;
let _: ::core::cmp::AssertParamIsEq<bool>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for CoverageOptions {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.level, state);
::core::hash::Hash::hash(&self.discard_all_spans_in_codegen, state)
}
}Hash, #[automatically_derived]
impl ::core::default::Default for CoverageOptions {
#[inline]
fn default() -> CoverageOptions {
CoverageOptions {
level: ::core::default::Default::default(),
discard_all_spans_in_codegen: ::core::default::Default::default(),
}
}
}Default)]
159pub struct CoverageOptions {
160 pub level: CoverageLevel,
161
162 pub discard_all_spans_in_codegen: bool,
168}
169
170#[derive(#[automatically_derived]
impl ::core::clone::Clone for CoverageLevel {
#[inline]
fn clone(&self) -> CoverageLevel { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for CoverageLevel { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for CoverageLevel {
#[inline]
fn eq(&self, other: &CoverageLevel) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for CoverageLevel {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for CoverageLevel {
#[inline]
fn partial_cmp(&self, other: &CoverageLevel)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for CoverageLevel {
#[inline]
fn cmp(&self, other: &CoverageLevel) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
}
}Ord, #[automatically_derived]
impl ::core::hash::Hash for CoverageLevel {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for CoverageLevel {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
CoverageLevel::Block => "Block",
CoverageLevel::Branch => "Branch",
CoverageLevel::Condition => "Condition",
})
}
}Debug, #[automatically_derived]
impl ::core::default::Default for CoverageLevel {
#[inline]
fn default() -> CoverageLevel { Self::Block }
}Default)]
172pub enum CoverageLevel {
173 #[default]
175 Block,
176 Branch,
178 Condition,
194}
195
196#[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)]
198pub enum Offload {
199 Device,
201 Host(String),
203 Test,
205}
206
207#[derive(#[automatically_derived]
impl ::core::marker::Copy for CodegenRetagOptions { }Copy, #[automatically_derived]
impl ::core::clone::Clone for CodegenRetagOptions {
#[inline]
fn clone(&self) -> CodegenRetagOptions {
let _: ::core::clone::AssertParamIsClone<bool>;
*self
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for CodegenRetagOptions {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"CodegenRetagOptions", "no_precise_im", &self.no_precise_im,
"no_precise_pin", &&self.no_precise_pin)
}
}Debug, #[automatically_derived]
impl ::core::default::Default for CodegenRetagOptions {
#[inline]
fn default() -> CodegenRetagOptions {
CodegenRetagOptions {
no_precise_im: ::core::default::Default::default(),
no_precise_pin: ::core::default::Default::default(),
}
}
}Default, #[automatically_derived]
impl ::core::cmp::PartialEq for CodegenRetagOptions {
#[inline]
fn eq(&self, other: &CodegenRetagOptions) -> bool {
self.no_precise_im == other.no_precise_im &&
self.no_precise_pin == other.no_precise_pin
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for CodegenRetagOptions {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.no_precise_im, state);
::core::hash::Hash::hash(&self.no_precise_pin, state)
}
}Hash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for CodegenRetagOptions {
fn encode(&self, __encoder: &mut __E) {
match *self {
CodegenRetagOptions {
no_precise_im: ref __binding_0,
no_precise_pin: ref __binding_1 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for CodegenRetagOptions {
fn decode(__decoder: &mut __D) -> Self {
CodegenRetagOptions {
no_precise_im: ::rustc_serialize::Decodable::decode(__decoder),
no_precise_pin: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable)]
209pub struct CodegenRetagOptions {
210 pub no_precise_im: bool,
212 pub no_precise_pin: bool,
214}
215
216#[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)]
218pub enum AutoDiff {
219 Enable,
221
222 PrintTA,
224 PrintTAFn(String),
226 PrintAA,
228 PrintPerf,
230 PrintSteps,
232 PrintModBefore,
234 PrintModAfter,
236 PrintModFinal,
238
239 PrintPasses,
241 NoPostopt,
243 LooseTypes,
246 Inline,
248 NoTT,
250}
251
252#[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)]
254pub enum AnnotateMoves {
255 Disabled,
257 Enabled(Option<u64>),
260}
261
262#[derive(#[automatically_derived]
impl ::core::clone::Clone for InstrumentMcount {
#[inline]
fn clone(&self) -> InstrumentMcount { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for InstrumentMcount { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for InstrumentMcount {
#[inline]
fn eq(&self, other: &InstrumentMcount) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for InstrumentMcount {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::fmt::Debug for InstrumentMcount {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
InstrumentMcount::Disabled => "Disabled",
InstrumentMcount::Mcount => "Mcount",
InstrumentMcount::Fentry => "Fentry",
})
}
}Debug, #[automatically_derived]
impl ::core::hash::Hash for InstrumentMcount {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash)]
264pub enum InstrumentMcount {
265 Disabled,
267 Mcount,
269 Fentry,
271}
272
273#[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)]
275pub struct InstrumentXRay {
276 pub always: bool,
278 pub never: bool,
280 pub ignore_loops: bool,
283 pub instruction_threshold: Option<usize>,
286 pub skip_entry: bool,
288 pub skip_exit: bool,
290}
291
292#[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)]
293pub enum LinkerPluginLto {
294 LinkerPlugin(PathBuf),
295 LinkerPluginAuto,
296 Disabled,
297}
298
299impl LinkerPluginLto {
300 pub fn enabled(&self) -> bool {
301 match *self {
302 LinkerPluginLto::LinkerPlugin(_) | LinkerPluginLto::LinkerPluginAuto => true,
303 LinkerPluginLto::Disabled => false,
304 }
305 }
306}
307
308#[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)]
324pub struct LinkSelfContained {
325 pub explicitly_set: Option<bool>,
328
329 enabled_components: LinkSelfContainedComponents,
332
333 disabled_components: LinkSelfContainedComponents,
336}
337
338impl LinkSelfContained {
339 pub(crate) fn handle_cli_component(&mut self, component: &str) -> Option<()> {
342 if let Some(component_to_enable) = component.strip_prefix('+') {
347 self.explicitly_set = None;
348 self.enabled_components
349 .insert(LinkSelfContainedComponents::from_str(component_to_enable).ok()?);
350 Some(())
351 } else if let Some(component_to_disable) = component.strip_prefix('-') {
352 self.explicitly_set = None;
353 self.disabled_components
354 .insert(LinkSelfContainedComponents::from_str(component_to_disable).ok()?);
355 Some(())
356 } else {
357 None
358 }
359 }
360
361 pub(crate) fn set_all_explicitly(&mut self, enabled: bool) {
364 self.explicitly_set = Some(enabled);
365
366 if enabled {
367 self.enabled_components = LinkSelfContainedComponents::all();
368 self.disabled_components = LinkSelfContainedComponents::empty();
369 } else {
370 self.enabled_components = LinkSelfContainedComponents::empty();
371 self.disabled_components = LinkSelfContainedComponents::all();
372 }
373 }
374
375 pub fn on() -> Self {
377 let mut on = LinkSelfContained::default();
378 on.set_all_explicitly(true);
379 on
380 }
381
382 fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
386 if self.explicitly_set.is_some() {
387 return Ok(());
388 }
389
390 let has_minus_linker = self.disabled_components.is_linker_enabled();
392 if has_minus_linker && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
393 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!(
394 "`-C link-self-contained=-linker` is unstable on the `{target_tuple}` \
395 target. The `-Z unstable-options` flag must also be passed to use it on this target",
396 ));
397 }
398
399 let unstable_enabled = self.enabled_components;
401 let unstable_disabled = self.disabled_components - LinkSelfContainedComponents::LINKER;
402 if !unstable_enabled.union(unstable_disabled).is_empty() {
403 return Err(String::from(
404 "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off`/`-linker` \
405 are stable, the `-Z unstable-options` flag must also be passed to use \
406 the unstable values",
407 ));
408 }
409
410 Ok(())
411 }
412
413 pub fn is_linker_enabled(&self) -> bool {
416 self.enabled_components.contains(LinkSelfContainedComponents::LINKER)
417 }
418
419 pub fn is_linker_disabled(&self) -> bool {
422 self.disabled_components.contains(LinkSelfContainedComponents::LINKER)
423 }
424
425 fn check_consistency(&self) -> Option<LinkSelfContainedComponents> {
428 if self.explicitly_set.is_some() {
429 None
430 } else {
431 let common = self.enabled_components.intersection(self.disabled_components);
432 if common.is_empty() { None } else { Some(common) }
433 }
434 }
435}
436
437#[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)]
446pub struct LinkerFeaturesCli {
447 pub enabled: LinkerFeatures,
449
450 pub disabled: LinkerFeatures,
452}
453
454impl LinkerFeaturesCli {
455 pub(crate) fn handle_cli_feature(&mut self, feature: &str) -> Option<()> {
458 match feature {
464 "+lld" => {
465 self.enabled.insert(LinkerFeatures::LLD);
466 self.disabled.remove(LinkerFeatures::LLD);
467 Some(())
468 }
469 "-lld" => {
470 self.disabled.insert(LinkerFeatures::LLD);
471 self.enabled.remove(LinkerFeatures::LLD);
472 Some(())
473 }
474 _ => None,
475 }
476 }
477
478 pub(crate) fn check_unstable_variants(&self, target_tuple: &TargetTuple) -> Result<(), String> {
483 let has_minus_lld = self.disabled.is_lld_enabled();
485 if has_minus_lld && target_tuple.tuple() != "x86_64-unknown-linux-gnu" {
486 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!(
487 "`-C linker-features=-lld` is unstable on the `{target_tuple}` \
488 target. The `-Z unstable-options` flag must also be passed to use it on this target",
489 ));
490 }
491
492 let unstable_enabled = self.enabled;
494 let unstable_disabled = self.disabled - LinkerFeatures::LLD;
495 if !unstable_enabled.union(unstable_disabled).is_empty() {
496 let unstable_features: Vec<_> = unstable_enabled
497 .iter()
498 .map(|f| ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("+{0}", f.as_str().unwrap()))
})format!("+{}", f.as_str().unwrap()))
499 .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())))
500 .collect();
501 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!(
502 "`-C linker-features={}` is unstable, and also requires the \
503 `-Z unstable-options` flag to be used",
504 unstable_features.join(","),
505 ));
506 }
507
508 Ok(())
509 }
510}
511
512#[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)]
514pub enum IncrementalStateAssertion {
515 Loaded,
520 NotLoaded,
522}
523
524#[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)]
526pub struct LocationDetail {
527 pub file: bool,
528 pub line: bool,
529 pub column: bool,
530}
531
532impl LocationDetail {
533 pub(crate) fn all() -> Self {
534 Self { file: true, line: true, column: true }
535 }
536}
537
538#[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)]
540pub enum FmtDebug {
541 Full,
543 Shallow,
545 None,
547}
548
549impl FmtDebug {
550 pub(crate) fn all() -> [Symbol; 3] {
551 [sym::full, sym::none, sym::shallow]
552 }
553}
554
555#[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)]
556pub enum SwitchWithOptPath {
557 Enabled(Option<PathBuf>),
558 Disabled,
559}
560
561impl SwitchWithOptPath {
562 pub fn enabled(&self) -> bool {
563 match *self {
564 SwitchWithOptPath::Enabled(_) => true,
565 SwitchWithOptPath::Disabled => false,
566 }
567 }
568}
569
570#[derive(#[automatically_derived]
impl ::core::marker::Copy for SymbolManglingVersion { }Copy, #[automatically_derived]
impl ::core::clone::Clone for SymbolManglingVersion {
#[inline]
fn clone(&self) -> SymbolManglingVersion { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for SymbolManglingVersion {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
SymbolManglingVersion::Legacy => "Legacy",
SymbolManglingVersion::V0 => "V0",
SymbolManglingVersion::Hashed => "Hashed",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for SymbolManglingVersion {
#[inline]
fn eq(&self, other: &SymbolManglingVersion) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for SymbolManglingVersion {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for SymbolManglingVersion {
#[inline]
fn partial_cmp(&self, other: &SymbolManglingVersion)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for SymbolManglingVersion {
#[inline]
fn cmp(&self, other: &SymbolManglingVersion) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
}
}Ord, #[automatically_derived]
impl ::core::hash::Hash for SymbolManglingVersion {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for
SymbolManglingVersion {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
SymbolManglingVersion::Legacy => {}
SymbolManglingVersion::V0 => {}
SymbolManglingVersion::Hashed => {}
}
}
}
};StableHash)]
571#[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)]
572pub enum SymbolManglingVersion {
573 Legacy,
574 V0,
575 Hashed,
576}
577
578#[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)]
579pub enum DebugInfo {
580 None,
581 LineDirectivesOnly,
582 LineTablesOnly,
583 Limited,
584 Full,
585}
586
587#[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)]
588pub enum DebugInfoCompression {
589 None,
590 Zlib,
591 Zstd,
592}
593
594#[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)]
595pub enum MirStripDebugInfo {
596 None,
597 LocalsInTinyFunctions,
598 AllLocals,
599}
600
601#[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)]
611pub enum SplitDwarfKind {
612 Single,
615 Split,
618}
619
620impl FromStr for SplitDwarfKind {
621 type Err = ();
622
623 fn from_str(s: &str) -> Result<Self, ()> {
624 Ok(match s {
625 "single" => SplitDwarfKind::Single,
626 "split" => SplitDwarfKind::Split,
627 _ => return Err(()),
628 })
629 }
630}
631
632macro_rules! define_output_types {
633 (
634 $(
635 $(#[doc = $doc:expr])*
636 $Variant:ident => {
637 shorthand: $shorthand:expr,
638 extension: $extension:expr,
639 description: $description:expr,
640 default_filename: $default_filename:expr,
641 is_text: $is_text:expr,
642 compatible_with_cgus_and_single_output: $compatible:expr
643 }
644 ),* $(,)?
645 ) => {
646 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, StableHash)]
647 #[derive(Encodable, Decodable)]
648 pub enum OutputType {
649 $(
650 $(#[doc = $doc])*
651 $Variant,
652 )*
653 }
654
655 impl StableOrd for OutputType {
656 const CAN_USE_UNSTABLE_SORT: bool = true;
657
658 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
660 }
661
662 impl OutputType {
663 pub fn iter_all() -> impl Iterator<Item = OutputType> {
664 static ALL_VARIANTS: &[OutputType] = &[
665 $(
666 OutputType::$Variant,
667 )*
668 ];
669 ALL_VARIANTS.iter().copied()
670 }
671
672 fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool {
673 match *self {
674 $(
675 OutputType::$Variant => $compatible,
676 )*
677 }
678 }
679
680 pub fn shorthand(&self) -> &'static str {
681 match *self {
682 $(
683 OutputType::$Variant => $shorthand,
684 )*
685 }
686 }
687
688 fn from_shorthand(shorthand: &str) -> Option<Self> {
689 match shorthand {
690 $(
691 s if s == $shorthand => Some(OutputType::$Variant),
692 )*
693 _ => None,
694 }
695 }
696
697 fn shorthands_display() -> String {
698 let shorthands = vec![
699 $(
700 format!("`{}`", $shorthand),
701 )*
702 ];
703 shorthands.join(", ")
704 }
705
706 pub fn extension(&self) -> &'static str {
707 match *self {
708 $(
709 OutputType::$Variant => $extension,
710 )*
711 }
712 }
713
714 pub fn is_text_output(&self) -> bool {
715 match *self {
716 $(
717 OutputType::$Variant => $is_text,
718 )*
719 }
720 }
721
722 pub fn description(&self) -> &'static str {
723 match *self {
724 $(
725 OutputType::$Variant => $description,
726 )*
727 }
728 }
729
730 pub fn default_filename(&self) -> &'static str {
731 match *self {
732 $(
733 OutputType::$Variant => $default_filename,
734 )*
735 }
736 }
737
738
739 }
740 }
741}
742
743#[automatically_derived]
impl ::core::clone::Clone for OutputType {
#[inline]
fn clone(&self) -> OutputType { *self }
}
#[automatically_derived]
impl ::core::marker::Copy for OutputType { }
#[automatically_derived]
impl ::core::marker::StructuralPartialEq for OutputType { }
#[automatically_derived]
impl ::core::cmp::PartialEq for OutputType {
#[inline]
fn eq(&self, other: &OutputType) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}
#[automatically_derived]
impl ::core::cmp::Eq for OutputType {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}
#[automatically_derived]
impl ::core::hash::Hash for OutputType {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}
#[automatically_derived]
impl ::core::fmt::Debug for OutputType {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
OutputType::Assembly => "Assembly",
OutputType::Bitcode => "Bitcode",
OutputType::DepInfo => "DepInfo",
OutputType::Exe => "Exe",
OutputType::LlvmAssembly => "LlvmAssembly",
OutputType::Metadata => "Metadata",
OutputType::Mir => "Mir",
OutputType::Object => "Object",
OutputType::ThinLinkBitcode => "ThinLinkBitcode",
})
}
}
#[automatically_derived]
impl ::core::cmp::PartialOrd for OutputType {
#[inline]
fn partial_cmp(&self, other: &OutputType)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}
#[automatically_derived]
impl ::core::cmp::Ord for OutputType {
#[inline]
fn cmp(&self, other: &OutputType) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
}
}
const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for OutputType {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
OutputType::Assembly => {}
OutputType::Bitcode => {}
OutputType::DepInfo => {}
OutputType::Exe => {}
OutputType::LlvmAssembly => {}
OutputType::Metadata => {}
OutputType::Mir => {}
OutputType::Object => {}
OutputType::ThinLinkBitcode => {}
}
}
}
};
impl StableOrd for OutputType {
const CAN_USE_UNSTABLE_SORT: bool = true;
const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
}
impl OutputType {
pub fn iter_all() -> impl Iterator<Item = OutputType> {
static ALL_VARIANTS: &[OutputType] =
&[OutputType::Assembly, OutputType::Bitcode, OutputType::DepInfo,
OutputType::Exe, OutputType::LlvmAssembly,
OutputType::Metadata, OutputType::Mir, OutputType::Object,
OutputType::ThinLinkBitcode];
ALL_VARIANTS.iter().copied()
}
fn is_compatible_with_codegen_units_and_single_output_file(&self)
-> bool {
match *self {
OutputType::Assembly => false,
OutputType::Bitcode => false,
OutputType::DepInfo => true,
OutputType::Exe => true,
OutputType::LlvmAssembly => false,
OutputType::Metadata => true,
OutputType::Mir => false,
OutputType::Object => false,
OutputType::ThinLinkBitcode => false,
}
}
pub fn shorthand(&self) -> &'static str {
match *self {
OutputType::Assembly => "asm",
OutputType::Bitcode => "llvm-bc",
OutputType::DepInfo => "dep-info",
OutputType::Exe => "link",
OutputType::LlvmAssembly => "llvm-ir",
OutputType::Metadata => "metadata",
OutputType::Mir => "mir",
OutputType::Object => "obj",
OutputType::ThinLinkBitcode => "thin-link-bitcode",
}
}
fn from_shorthand(shorthand: &str) -> Option<Self> {
match shorthand {
s if s == "asm" => Some(OutputType::Assembly),
s if s == "llvm-bc" => Some(OutputType::Bitcode),
s if s == "dep-info" => Some(OutputType::DepInfo),
s if s == "link" => Some(OutputType::Exe),
s if s == "llvm-ir" => Some(OutputType::LlvmAssembly),
s if s == "metadata" => Some(OutputType::Metadata),
s if s == "mir" => Some(OutputType::Mir),
s if s == "obj" => Some(OutputType::Object),
s if s == "thin-link-bitcode" =>
Some(OutputType::ThinLinkBitcode),
_ => None,
}
}
fn shorthands_display() -> String {
let shorthands =
::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "asm"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "llvm-bc"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "dep-info"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "link"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "llvm-ir"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "metadata"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "mir"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`", "obj"))
}),
::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`",
"thin-link-bitcode"))
})]));
shorthands.join(", ")
}
pub fn extension(&self) -> &'static str {
match *self {
OutputType::Assembly => "s",
OutputType::Bitcode => "bc",
OutputType::DepInfo => "d",
OutputType::Exe => "",
OutputType::LlvmAssembly => "ll",
OutputType::Metadata => "rmeta",
OutputType::Mir => "mir",
OutputType::Object => "o",
OutputType::ThinLinkBitcode => "indexing.o",
}
}
pub fn is_text_output(&self) -> bool {
match *self {
OutputType::Assembly => true,
OutputType::Bitcode => false,
OutputType::DepInfo => true,
OutputType::Exe => false,
OutputType::LlvmAssembly => true,
OutputType::Metadata => false,
OutputType::Mir => true,
OutputType::Object => false,
OutputType::ThinLinkBitcode => false,
}
}
pub fn description(&self) -> &'static str {
match *self {
OutputType::Assembly =>
"Generates a file with the crate's assembly code",
OutputType::Bitcode =>
"Generates a binary file containing the LLVM bitcode",
OutputType::DepInfo =>
"Generates a file with Makefile syntax that indicates all the source files that were loaded to generate the crate",
OutputType::Exe =>
"Generates the crates specified by --crate-type. This is the default if --emit is not specified",
OutputType::LlvmAssembly => "Generates a file containing LLVM IR",
OutputType::Metadata =>
"Generates a file containing metadata about the crate",
OutputType::Mir =>
"Generates a file containing rustc's mid-level intermediate representation",
OutputType::Object => "Generates a native object file",
OutputType::ThinLinkBitcode =>
"Generates the ThinLTO summary as bitcode",
}
}
pub fn default_filename(&self) -> &'static str {
match *self {
OutputType::Assembly => "CRATE_NAME.s",
OutputType::Bitcode => "CRATE_NAME.bc",
OutputType::DepInfo => "CRATE_NAME.d",
OutputType::Exe => "(platform and crate-type dependent)",
OutputType::LlvmAssembly => "CRATE_NAME.ll",
OutputType::Metadata => "libCRATE_NAME.rmeta",
OutputType::Mir => "CRATE_NAME.mir",
OutputType::Object => "CRATE_NAME.o",
OutputType::ThinLinkBitcode => "CRATE_NAME.indexing.o",
}
}
}define_output_types! {
744 Assembly => {
745 shorthand: "asm",
746 extension: "s",
747 description: "Generates a file with the crate's assembly code",
748 default_filename: "CRATE_NAME.s",
749 is_text: true,
750 compatible_with_cgus_and_single_output: false
751 },
752 #[doc = "This is the optimized bitcode, which could be either pre-LTO or non-LTO bitcode,"]
753 #[doc = "depending on the specific request type."]
754 Bitcode => {
755 shorthand: "llvm-bc",
756 extension: "bc",
757 description: "Generates a binary file containing the LLVM bitcode",
758 default_filename: "CRATE_NAME.bc",
759 is_text: false,
760 compatible_with_cgus_and_single_output: false
761 },
762 DepInfo => {
763 shorthand: "dep-info",
764 extension: "d",
765 description: "Generates a file with Makefile syntax that indicates all the source files that were loaded to generate the crate",
766 default_filename: "CRATE_NAME.d",
767 is_text: true,
768 compatible_with_cgus_and_single_output: true
769 },
770 Exe => {
771 shorthand: "link",
772 extension: "",
773 description: "Generates the crates specified by --crate-type. This is the default if --emit is not specified",
774 default_filename: "(platform and crate-type dependent)",
775 is_text: false,
776 compatible_with_cgus_and_single_output: true
777 },
778 LlvmAssembly => {
779 shorthand: "llvm-ir",
780 extension: "ll",
781 description: "Generates a file containing LLVM IR",
782 default_filename: "CRATE_NAME.ll",
783 is_text: true,
784 compatible_with_cgus_and_single_output: false
785 },
786 Metadata => {
787 shorthand: "metadata",
788 extension: "rmeta",
789 description: "Generates a file containing metadata about the crate",
790 default_filename: "libCRATE_NAME.rmeta",
791 is_text: false,
792 compatible_with_cgus_and_single_output: true
793 },
794 Mir => {
795 shorthand: "mir",
796 extension: "mir",
797 description: "Generates a file containing rustc's mid-level intermediate representation",
798 default_filename: "CRATE_NAME.mir",
799 is_text: true,
800 compatible_with_cgus_and_single_output: false
801 },
802 Object => {
803 shorthand: "obj",
804 extension: "o",
805 description: "Generates a native object file",
806 default_filename: "CRATE_NAME.o",
807 is_text: false,
808 compatible_with_cgus_and_single_output: false
809 },
810 #[doc = "This is the summary or index data part of the ThinLTO bitcode."]
811 ThinLinkBitcode => {
812 shorthand: "thin-link-bitcode",
813 extension: "indexing.o",
814 description: "Generates the ThinLTO summary as bitcode",
815 default_filename: "CRATE_NAME.indexing.o",
816 is_text: false,
817 compatible_with_cgus_and_single_output: false
818 },
819}
820
821#[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)]
823pub enum ErrorOutputType {
824 #[default]
826 HumanReadable {
827 kind: HumanReadableErrorType = HumanReadableErrorType { short: false, unicode: false },
828 color_config: ColorConfig = ColorConfig::Auto,
829 },
830 Json {
832 pretty: bool,
834 json_rendered: HumanReadableErrorType,
837 color_config: ColorConfig,
838 },
839}
840
841#[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)]
842pub enum ResolveDocLinks {
843 None,
845 ExportedMetadata,
847 Exported,
849 All,
851}
852
853#[derive(#[automatically_derived]
impl ::core::clone::Clone for OutputTypes {
#[inline]
fn clone(&self) -> OutputTypes {
OutputTypes(::core::clone::Clone::clone(&self.0))
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for OutputTypes {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "OutputTypes",
&&self.0)
}
}Debug, #[automatically_derived]
impl ::core::hash::Hash for OutputTypes {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for OutputTypes
{
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
OutputTypes(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for OutputTypes {
fn encode(&self, __encoder: &mut __E) {
match *self {
OutputTypes(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for OutputTypes {
fn decode(__decoder: &mut __D) -> Self {
OutputTypes(::rustc_serialize::Decodable::decode(__decoder))
}
}
};Decodable)]
858pub struct OutputTypes(BTreeMap<OutputType, Option<OutFileName>>);
859
860impl OutputTypes {
861 pub fn new(entries: &[(OutputType, Option<OutFileName>)]) -> OutputTypes {
862 OutputTypes(BTreeMap::from_iter(entries.iter().map(|&(k, ref v)| (k, v.clone()))))
863 }
864
865 pub(crate) fn get(&self, key: &OutputType) -> Option<&Option<OutFileName>> {
866 self.0.get(key)
867 }
868
869 pub fn contains_key(&self, key: &OutputType) -> bool {
870 self.0.contains_key(key)
871 }
872
873 pub fn contains_explicit_name(&self, key: &OutputType) -> bool {
875 #[allow(non_exhaustive_omitted_patterns)] match self.0.get(key) {
Some(Some(..)) => true,
_ => false,
}matches!(self.0.get(key), Some(Some(..)))
876 }
877
878 pub fn iter(&self) -> BTreeMapIter<'_, OutputType, Option<OutFileName>> {
879 self.0.iter()
880 }
881
882 pub fn keys(&self) -> BTreeMapKeysIter<'_, OutputType, Option<OutFileName>> {
883 self.0.keys()
884 }
885
886 pub fn values(&self) -> BTreeMapValuesIter<'_, OutputType, Option<OutFileName>> {
887 self.0.values()
888 }
889
890 pub fn len(&self) -> usize {
891 self.0.len()
892 }
893
894 pub fn should_codegen(&self) -> bool {
896 self.0.keys().any(|k| match *k {
897 OutputType::Bitcode
898 | OutputType::ThinLinkBitcode
899 | OutputType::Assembly
900 | OutputType::LlvmAssembly
901 | OutputType::Mir
902 | OutputType::Object
903 | OutputType::Exe => true,
904 OutputType::Metadata | OutputType::DepInfo => false,
905 })
906 }
907
908 pub fn should_link(&self) -> bool {
910 self.0.keys().any(|k| match *k {
911 OutputType::Bitcode
912 | OutputType::ThinLinkBitcode
913 | OutputType::Assembly
914 | OutputType::LlvmAssembly
915 | OutputType::Mir
916 | OutputType::Metadata
917 | OutputType::Object
918 | OutputType::DepInfo => false,
919 OutputType::Exe => true,
920 })
921 }
922}
923
924#[derive(#[automatically_derived]
impl ::core::clone::Clone for Externs {
#[inline]
fn clone(&self) -> Externs {
Externs(::core::clone::Clone::clone(&self.0))
}
}Clone)]
928pub struct Externs(BTreeMap<String, ExternEntry>);
929
930#[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)]
931pub struct ExternEntry {
932 pub location: ExternLocation,
933 pub is_private_dep: bool,
939 pub add_prelude: bool,
944 pub nounused_dep: bool,
949 pub force: bool,
955}
956
957#[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)]
958pub enum ExternLocation {
959 FoundInLibrarySearchDirectories,
963 ExactPaths(BTreeSet<CanonicalizedPath>),
970}
971
972impl Externs {
973 pub fn new(data: BTreeMap<String, ExternEntry>) -> Externs {
975 Externs(data)
976 }
977
978 pub fn get(&self, key: &str) -> Option<&ExternEntry> {
979 self.0.get(key)
980 }
981
982 pub fn iter(&self) -> BTreeMapIter<'_, String, ExternEntry> {
983 self.0.iter()
984 }
985}
986
987impl ExternEntry {
988 fn new(location: ExternLocation) -> ExternEntry {
989 ExternEntry {
990 location,
991 is_private_dep: false,
992 add_prelude: false,
993 nounused_dep: false,
994 force: false,
995 }
996 }
997
998 pub fn files(&self) -> Option<impl Iterator<Item = &CanonicalizedPath>> {
999 match &self.location {
1000 ExternLocation::ExactPaths(set) => Some(set.iter()),
1001 _ => None,
1002 }
1003 }
1004}
1005
1006#[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)]
1007pub struct NextSolverConfig {
1008 pub coherence: bool = true,
1010 pub globally: bool = false,
1013}
1014
1015#[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)]
1016pub enum Input {
1017 File(PathBuf),
1019 Str {
1021 name: FileName,
1023 input: String,
1025 },
1026}
1027
1028impl Input {
1029 pub fn filestem(&self) -> &str {
1030 if let Input::File(ifile) = self {
1031 if let Some(name) = ifile.file_stem().and_then(OsStr::to_str) {
1034 return name;
1035 }
1036 }
1037 "rust_out"
1038 }
1039
1040 pub fn file_name(&self, session: &Session) -> FileName {
1041 match *self {
1042 Input::File(ref ifile) => FileName::Real(
1043 session
1044 .psess
1045 .source_map()
1046 .path_mapping()
1047 .to_real_filename(session.psess.source_map().working_dir(), ifile.as_path()),
1048 ),
1049 Input::Str { ref name, .. } => name.clone(),
1050 }
1051 }
1052
1053 pub fn opt_path(&self) -> Option<&Path> {
1054 match self {
1055 Input::File(file) => Some(file),
1056 Input::Str { name, .. } => match name {
1057 FileName::Real(real) => real.local_path(),
1058 FileName::CfgSpec(_) => None,
1059 FileName::Anon(_) => None,
1060 FileName::MacroExpansion(_) => None,
1061 FileName::ProcMacroSourceCode(_) => None,
1062 FileName::CliCrateAttr(_) => None,
1063 FileName::Custom(_) => None,
1064 FileName::DocTest(path, _) => Some(path),
1065 FileName::InlineAsm(_) => None,
1066 },
1067 }
1068 }
1069}
1070
1071#[derive(#[automatically_derived]
impl ::core::clone::Clone for OutFileName {
#[inline]
fn clone(&self) -> OutFileName {
match self {
OutFileName::Real(__self_0) =>
OutFileName::Real(::core::clone::Clone::clone(__self_0)),
OutFileName::Stdout => OutFileName::Stdout,
}
}
}Clone, #[automatically_derived]
impl ::core::hash::Hash for OutFileName {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state);
match self {
OutFileName::Real(__self_0) =>
::core::hash::Hash::hash(__self_0, state),
_ => {}
}
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for OutFileName {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
OutFileName::Real(__self_0) =>
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Real",
&__self_0),
OutFileName::Stdout =>
::core::fmt::Formatter::write_str(f, "Stdout"),
}
}
}Debug, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for OutFileName
{
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
OutFileName::Real(ref __binding_0) => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
OutFileName::Stdout => {}
}
}
}
};StableHash, #[automatically_derived]
impl ::core::cmp::PartialEq for OutFileName {
#[inline]
fn eq(&self, other: &OutFileName) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr &&
match (self, other) {
(OutFileName::Real(__self_0), OutFileName::Real(__arg1_0)) =>
__self_0 == __arg1_0,
_ => true,
}
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for OutFileName {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<PathBuf>;
}
}Eq, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for OutFileName {
fn encode(&self, __encoder: &mut __E) {
let disc =
match *self {
OutFileName::Real(ref __binding_0) => { 0usize }
OutFileName::Stdout => { 1usize }
};
::rustc_serialize::Encoder::emit_u8(__encoder, disc as u8);
match *self {
OutFileName::Real(ref __binding_0) => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
}
OutFileName::Stdout => {}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for OutFileName {
fn decode(__decoder: &mut __D) -> Self {
match ::rustc_serialize::Decoder::read_u8(__decoder) as usize
{
0usize => {
OutFileName::Real(::rustc_serialize::Decodable::decode(__decoder))
}
1usize => { OutFileName::Stdout }
n => {
::core::panicking::panic_fmt(format_args!("invalid enum variant tag while decoding `OutFileName`, expected 0..2, actual {0}",
n));
}
}
}
}
};Decodable)]
1072pub enum OutFileName {
1073 Real(PathBuf),
1074 Stdout,
1075}
1076
1077impl OutFileName {
1078 pub fn parent(&self) -> Option<&Path> {
1079 match *self {
1080 OutFileName::Real(ref path) => path.parent(),
1081 OutFileName::Stdout => None,
1082 }
1083 }
1084
1085 pub fn filestem(&self) -> Option<&OsStr> {
1086 match *self {
1087 OutFileName::Real(ref path) => path.file_stem(),
1088 OutFileName::Stdout => Some(OsStr::new("stdout")),
1089 }
1090 }
1091
1092 pub fn is_stdout(&self) -> bool {
1093 match *self {
1094 OutFileName::Real(_) => false,
1095 OutFileName::Stdout => true,
1096 }
1097 }
1098
1099 pub fn is_tty(&self) -> bool {
1100 use std::io::IsTerminal;
1101 match *self {
1102 OutFileName::Real(_) => false,
1103 OutFileName::Stdout => std::io::stdout().is_terminal(),
1104 }
1105 }
1106
1107 pub fn as_path(&self) -> &Path {
1108 match *self {
1109 OutFileName::Real(ref path) => path.as_ref(),
1110 OutFileName::Stdout => Path::new("stdout"),
1111 }
1112 }
1113
1114 pub fn file_for_writing(
1120 &self,
1121 outputs: &OutputFilenames,
1122 flavor: OutputType,
1123 codegen_unit_name: &str,
1124 ) -> PathBuf {
1125 match *self {
1126 OutFileName::Real(ref path) => path.clone(),
1127 OutFileName::Stdout => outputs.temp_path_for_cgu(flavor, codegen_unit_name),
1128 }
1129 }
1130
1131 pub fn overwrite(&self, content: &str, sess: &Session) {
1132 match self {
1133 OutFileName::Stdout => { ::std::io::_print(format_args!("{0}", content)); }print!("{content}"),
1134 OutFileName::Real(path) => {
1135 if let Err(e) = fs::write(path, content) {
1136 sess.dcx().emit_fatal(FileWriteFail { path, err: e.to_string() });
1137 }
1138 }
1139 }
1140 }
1141}
1142
1143#[derive(#[automatically_derived]
impl ::core::clone::Clone for OutputFilenames {
#[inline]
fn clone(&self) -> OutputFilenames {
OutputFilenames {
out_directory: ::core::clone::Clone::clone(&self.out_directory),
crate_stem: ::core::clone::Clone::clone(&self.crate_stem),
filestem: ::core::clone::Clone::clone(&self.filestem),
single_output_file: ::core::clone::Clone::clone(&self.single_output_file),
temps_directory: ::core::clone::Clone::clone(&self.temps_directory),
invocation_temp: ::core::clone::Clone::clone(&self.invocation_temp),
explicit_dwo_out_directory: ::core::clone::Clone::clone(&self.explicit_dwo_out_directory),
outputs: ::core::clone::Clone::clone(&self.outputs),
}
}
}Clone, #[automatically_derived]
impl ::core::hash::Hash for OutputFilenames {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.out_directory, state);
::core::hash::Hash::hash(&self.crate_stem, state);
::core::hash::Hash::hash(&self.filestem, state);
::core::hash::Hash::hash(&self.single_output_file, state);
::core::hash::Hash::hash(&self.temps_directory, state);
::core::hash::Hash::hash(&self.invocation_temp, state);
::core::hash::Hash::hash(&self.explicit_dwo_out_directory, state);
::core::hash::Hash::hash(&self.outputs, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for OutputFilenames {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
let names: &'static _ =
&["out_directory", "crate_stem", "filestem", "single_output_file",
"temps_directory", "invocation_temp",
"explicit_dwo_out_directory", "outputs"];
let values: &[&dyn ::core::fmt::Debug] =
&[&self.out_directory, &self.crate_stem, &self.filestem,
&self.single_output_file, &self.temps_directory,
&self.invocation_temp, &self.explicit_dwo_out_directory,
&&self.outputs];
::core::fmt::Formatter::debug_struct_fields_finish(f,
"OutputFilenames", names, values)
}
}Debug, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for
OutputFilenames {
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
match *self {
OutputFilenames {
out_directory: ref __binding_0,
crate_stem: ref __binding_1,
filestem: ref __binding_2,
single_output_file: ref __binding_3,
temps_directory: ref __binding_4,
invocation_temp: ref __binding_5,
explicit_dwo_out_directory: ref __binding_6,
outputs: ref __binding_7 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
{ __binding_1.stable_hash(__hcx, __hasher); }
{ __binding_2.stable_hash(__hcx, __hasher); }
{ __binding_3.stable_hash(__hcx, __hasher); }
{ __binding_4.stable_hash(__hcx, __hasher); }
{}
{ __binding_6.stable_hash(__hcx, __hasher); }
{ __binding_7.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for OutputFilenames {
fn encode(&self, __encoder: &mut __E) {
match *self {
OutputFilenames {
out_directory: ref __binding_0,
crate_stem: ref __binding_1,
filestem: ref __binding_2,
single_output_file: ref __binding_3,
temps_directory: ref __binding_4,
invocation_temp: ref __binding_5,
explicit_dwo_out_directory: ref __binding_6,
outputs: ref __binding_7 } => {
::rustc_serialize::Encodable::<__E>::encode(__binding_0,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_1,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_2,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_3,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_4,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_5,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_6,
__encoder);
::rustc_serialize::Encodable::<__E>::encode(__binding_7,
__encoder);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for OutputFilenames {
fn decode(__decoder: &mut __D) -> Self {
OutputFilenames {
out_directory: ::rustc_serialize::Decodable::decode(__decoder),
crate_stem: ::rustc_serialize::Decodable::decode(__decoder),
filestem: ::rustc_serialize::Decodable::decode(__decoder),
single_output_file: ::rustc_serialize::Decodable::decode(__decoder),
temps_directory: ::rustc_serialize::Decodable::decode(__decoder),
invocation_temp: ::rustc_serialize::Decodable::decode(__decoder),
explicit_dwo_out_directory: ::rustc_serialize::Decodable::decode(__decoder),
outputs: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable)]
1144pub struct OutputFilenames {
1145 pub(crate) out_directory: PathBuf,
1146 crate_stem: String,
1148 filestem: String,
1150 pub single_output_file: Option<OutFileName>,
1151 temps_directory: Option<PathBuf>,
1152
1153 #[stable_hash(ignore)]
1161 invocation_temp: Option<String>,
1162
1163 explicit_dwo_out_directory: Option<PathBuf>,
1164 pub outputs: OutputTypes,
1165}
1166
1167pub const RLINK_EXT: &str = "rlink";
1168pub const RUST_CGU_EXT: &str = "rcgu";
1169pub const DWARF_OBJECT_EXT: &str = "dwo";
1170pub const MAX_FILENAME_LENGTH: usize = 143; fn maybe_strip_file_name(mut path: PathBuf) -> PathBuf {
1176 if path.file_name().map_or(0, |name| name.len()) > MAX_FILENAME_LENGTH {
1177 let filename = path.file_name().unwrap().to_string_lossy();
1178 let hash_len = 64 / 4; let hyphen_len = 1; let allowed_suffix = MAX_FILENAME_LENGTH.saturating_sub(hash_len + hyphen_len);
1183
1184 let stripped_bytes = filename.len().saturating_sub(allowed_suffix);
1186
1187 let split_at = filename.ceil_char_boundary(stripped_bytes);
1189
1190 let mut hasher = StableHasher::new();
1191 filename[..split_at].hash(&mut hasher);
1192 let hash = hasher.finish::<Hash64>();
1193
1194 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..]));
1195 }
1196 path
1197}
1198impl OutputFilenames {
1199 pub fn new(
1200 out_directory: PathBuf,
1201 out_crate_name: String,
1202 out_filestem: String,
1203 single_output_file: Option<OutFileName>,
1204 temps_directory: Option<PathBuf>,
1205 invocation_temp: Option<String>,
1206 explicit_dwo_out_directory: Option<PathBuf>,
1207 extra: String,
1208 outputs: OutputTypes,
1209 ) -> Self {
1210 OutputFilenames {
1211 out_directory,
1212 single_output_file,
1213 temps_directory,
1214 invocation_temp,
1215 explicit_dwo_out_directory,
1216 outputs,
1217 crate_stem: ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}{1}", out_crate_name, extra))
})format!("{out_crate_name}{extra}"),
1218 filestem: ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}{1}", out_filestem, extra))
})format!("{out_filestem}{extra}"),
1219 }
1220 }
1221
1222 pub fn path(&self, flavor: OutputType) -> OutFileName {
1223 self.outputs
1224 .get(&flavor)
1225 .and_then(|p| p.to_owned())
1226 .or_else(|| self.single_output_file.clone())
1227 .unwrap_or_else(|| OutFileName::Real(self.output_path(flavor)))
1228 }
1229
1230 pub fn interface_path(&self) -> PathBuf {
1231 {
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:1231",
"rustc_session::config", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_session/src/config.rs"),
::tracing_core::__macro_support::Option::Some(1231u32),
::tracing_core::__macro_support::Option::Some("rustc_session::config"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("using crate_name={0} for interface_path",
self.crate_stem) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("using crate_name={} for interface_path", self.crate_stem);
1232 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))
1233 }
1234
1235 fn output_path(&self, flavor: OutputType) -> PathBuf {
1238 let extension = flavor.extension();
1239 match flavor {
1240 OutputType::Metadata => {
1241 {
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:1241",
"rustc_session::config", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_session/src/config.rs"),
::tracing_core::__macro_support::Option::Some(1241u32),
::tracing_core::__macro_support::Option::Some("rustc_session::config"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("using crate_name={0} for {1}",
self.crate_stem, extension) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("using crate_name={} for {extension}", self.crate_stem);
1242 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))
1243 }
1244 _ => self.with_directory_and_extension(&self.out_directory, extension),
1245 }
1246 }
1247
1248 pub fn temp_path_for_cgu(&self, flavor: OutputType, codegen_unit_name: &str) -> PathBuf {
1252 let extension = flavor.extension();
1253 self.temp_path_ext_for_cgu(extension, codegen_unit_name)
1254 }
1255
1256 pub fn temp_path_dwo_for_cgu(&self, codegen_unit_name: &str) -> PathBuf {
1258 let p = self.temp_path_ext_for_cgu(DWARF_OBJECT_EXT, codegen_unit_name);
1259 if let Some(dwo_out) = &self.explicit_dwo_out_directory {
1260 let mut o = dwo_out.clone();
1261 o.push(p.file_name().unwrap());
1262 o
1263 } else {
1264 p
1265 }
1266 }
1267
1268 pub fn temp_path_ext_for_cgu(&self, ext: &str, codegen_unit_name: &str) -> PathBuf {
1271 let mut extension = codegen_unit_name.to_string();
1272
1273 if let Some(rng) = &self.invocation_temp {
1275 extension.push('.');
1276 extension.push_str(rng);
1277 }
1278
1279 if !ext.is_empty() {
1282 extension.push('.');
1283 extension.push_str(RUST_CGU_EXT);
1284 extension.push('.');
1285 extension.push_str(ext);
1286 }
1287
1288 let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
1289 maybe_strip_file_name(self.with_directory_and_extension(temps_directory, &extension))
1290 }
1291
1292 pub fn temp_path_for_diagnostic(&self, ext: &str) -> PathBuf {
1293 let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
1294 self.with_directory_and_extension(temps_directory, &ext)
1295 }
1296
1297 pub fn with_extension(&self, extension: &str) -> PathBuf {
1298 self.with_directory_and_extension(&self.out_directory, extension)
1299 }
1300
1301 pub fn with_directory_and_extension(&self, directory: &Path, extension: &str) -> PathBuf {
1302 {
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:1302",
"rustc_session::config", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_session/src/config.rs"),
::tracing_core::__macro_support::Option::Some(1302u32),
::tracing_core::__macro_support::Option::Some("rustc_session::config"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("using filestem={0} for {1}",
self.filestem, extension) as
&dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("using filestem={} for {extension}", self.filestem);
1303 let mut path = directory.join(&self.filestem);
1304 path.set_extension(extension);
1305 path
1306 }
1307
1308 pub fn split_dwarf_path(
1311 &self,
1312 split_debuginfo_kind: SplitDebuginfo,
1313 split_dwarf_kind: SplitDwarfKind,
1314 cgu_name: &str,
1315 ) -> Option<PathBuf> {
1316 let obj_out = self.temp_path_for_cgu(OutputType::Object, cgu_name);
1317 let dwo_out = self.temp_path_dwo_for_cgu(cgu_name);
1318 match (split_debuginfo_kind, split_dwarf_kind) {
1319 (SplitDebuginfo::Off, SplitDwarfKind::Single | SplitDwarfKind::Split) => None,
1320 (SplitDebuginfo::Packed | SplitDebuginfo::Unpacked, SplitDwarfKind::Single) => {
1324 Some(obj_out)
1325 }
1326 (SplitDebuginfo::Packed | SplitDebuginfo::Unpacked, SplitDwarfKind::Split) => {
1328 Some(dwo_out)
1329 }
1330 }
1331 }
1332}
1333
1334pub fn parse_remap_path_scope(
1336 early_dcx: &EarlyDiagCtxt,
1337 matches: &getopts::Matches,
1338 unstable_opts: &UnstableOptions,
1339) -> RemapPathScopeComponents {
1340 if let Some(v) = matches.opt_str("remap-path-scope") {
1341 let mut slot = RemapPathScopeComponents::empty();
1342 for s in v.split(',') {
1343 slot |= match s {
1344 "macro" => RemapPathScopeComponents::MACRO,
1345 "diagnostics" => RemapPathScopeComponents::DIAGNOSTICS,
1346 "documentation" => {
1347 if !unstable_opts.unstable_options {
1348 early_dcx.early_fatal("remapping `documentation` path scope requested but `-Zunstable-options` not specified");
1349 }
1350
1351 RemapPathScopeComponents::DOCUMENTATION
1352 },
1353 "debuginfo" => RemapPathScopeComponents::DEBUGINFO,
1354 "coverage" => RemapPathScopeComponents::COVERAGE,
1355 "object" => RemapPathScopeComponents::OBJECT,
1356 "all" => RemapPathScopeComponents::all(),
1357 _ => early_dcx.early_fatal("argument for `--remap-path-scope` must be a comma separated list of scopes: `macro`, `diagnostics`, `documentation`, `debuginfo`, `coverage`, `object`, `all`"),
1358 }
1359 }
1360 slot
1361 } else {
1362 RemapPathScopeComponents::all()
1363 }
1364}
1365
1366#[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)]
1367pub struct Sysroot {
1368 pub explicit: Option<PathBuf>,
1369 pub default: PathBuf,
1370}
1371
1372impl Sysroot {
1373 pub fn new(explicit: Option<PathBuf>) -> Sysroot {
1374 Sysroot { explicit, default: filesearch::default_sysroot() }
1375 }
1376
1377 pub fn path(&self) -> &Path {
1379 self.explicit.as_deref().unwrap_or(&self.default)
1380 }
1381
1382 pub fn all_paths(&self) -> impl Iterator<Item = &Path> {
1384 self.explicit.as_deref().into_iter().chain(iter::once(&*self.default))
1385 }
1386}
1387
1388pub fn host_tuple() -> &'static str {
1389 (::core::option::Option::Some("x86_64-unknown-linux-gnu")option_env!("CFG_COMPILER_HOST_TRIPLE")).expect("CFG_COMPILER_HOST_TRIPLE")
1398}
1399
1400fn file_path_mapping(
1401 remap_path_prefix: Vec<(PathBuf, PathBuf)>,
1402 remap_cwd_prefix: Option<&Path>,
1403 remap_path_scope: RemapPathScopeComponents,
1404) -> FilePathMapping {
1405 let cwd_remap = if let Some(to) = remap_cwd_prefix
1408 && let Ok(cwd) = std::env::current_dir()
1409 {
1410 Some((cwd, to.to_path_buf()))
1411 } else {
1412 None
1413 };
1414 FilePathMapping::new(remap_path_prefix.into_iter().chain(cwd_remap).collect(), remap_path_scope)
1417}
1418
1419impl Default for Options {
1420 fn default() -> Options {
1421 let unstable_opts = UnstableOptions::default();
1422
1423 let working_dir = {
1427 let working_dir = std::env::current_dir().unwrap();
1428 let file_mapping =
1429 file_path_mapping(Vec::new(), None, RemapPathScopeComponents::empty());
1430 file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
1431 };
1432
1433 Options {
1434 crate_types: Vec::new(),
1435 optimize: OptLevel::No,
1436 debuginfo: DebugInfo::None,
1437 lint_opts: Vec::new(),
1438 lint_cap: None,
1439 describe_lints: false,
1440 output_types: OutputTypes(BTreeMap::new()),
1441 search_paths: ::alloc::vec::Vec::new()vec![],
1442 sysroot: Sysroot::new(None),
1443 target_triple: TargetTuple::from_tuple(host_tuple()),
1444 test: false,
1445 incremental: None,
1446 unstable_opts,
1447 prints: Vec::new(),
1448 cg: Default::default(),
1449 error_format: ErrorOutputType::default(),
1450 diagnostic_width: None,
1451 externs: Externs(BTreeMap::new()),
1452 crate_name: None,
1453 libs: Vec::new(),
1454 unstable_features: UnstableFeatures::Disallow,
1455 debug_assertions: true,
1456 actually_rustdoc: false,
1457 resolve_doc_links: ResolveDocLinks::None,
1458 trimmed_def_paths: false,
1459 cli_forced_codegen_units: None,
1460 cli_forced_local_thinlto_off: false,
1461 remap_path_prefix: Vec::new(),
1462 remap_path_scope: RemapPathScopeComponents::all(),
1463 real_rust_source_base_dir: None,
1464 real_rustc_dev_source_base_dir: None,
1465 edition: DEFAULT_EDITION,
1466 json_artifact_notifications: false,
1467 json_timings: false,
1468 json_unused_externs: JsonUnusedExterns::No,
1469 json_future_incompat: false,
1470 pretty: None,
1471 working_dir,
1472 color: ColorConfig::Auto,
1473 logical_env: FxIndexMap::default(),
1474 verbose: false,
1475 target_modifiers: BTreeMap::default(),
1476 mitigation_coverage_map: Default::default(),
1477 jobs: Jobs { frontend: None, backend: None, linker: LinkerJobs::Default },
1478 }
1479 }
1480}
1481
1482impl Options {
1483 pub fn build_dep_graph(&self) -> bool {
1485 self.incremental.is_some()
1486 || self.unstable_opts.dump_dep_graph
1487 || self.unstable_opts.query_dep_graph
1488 }
1489
1490 pub fn file_path_mapping(&self) -> FilePathMapping {
1491 file_path_mapping(
1492 self.remap_path_prefix.clone(),
1493 self.unstable_opts.remap_cwd_prefix.as_deref(),
1494 self.remap_path_scope,
1495 )
1496 }
1497
1498 pub fn will_create_output_file(&self) -> bool {
1500 !self.unstable_opts.parse_crate_root_only && self.unstable_opts.ls.is_empty() }
1503
1504 #[inline]
1505 pub fn share_generics(&self) -> bool {
1506 match self.unstable_opts.share_generics {
1507 Some(setting) => setting,
1508 None => match self.optimize {
1509 OptLevel::No | OptLevel::Less | OptLevel::Size | OptLevel::SizeMin => true,
1510 OptLevel::More | OptLevel::Aggressive => false,
1511 },
1512 }
1513 }
1514
1515 pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
1516 self.cg.symbol_mangling_version.unwrap_or(SymbolManglingVersion::V0)
1517 }
1518
1519 #[inline]
1520 pub fn autodiff_enabled(&self) -> bool {
1521 self.unstable_opts.autodiff.contains(&AutoDiff::Enable)
1522 }
1523}
1524
1525impl UnstableOptions {
1526 pub fn dcx_flags(&self, can_emit_warnings: bool) -> DiagCtxtFlags {
1527 DiagCtxtFlags {
1528 can_emit_warnings,
1529 treat_err_as_bug: self.treat_err_as_bug,
1530 eagerly_emit_delayed_bugs: self.eagerly_emit_delayed_bugs,
1531 macro_backtrace: self.macro_backtrace,
1532 deduplicate_diagnostics: self.deduplicate_diagnostics,
1533 track_diagnostics: self.track_diagnostics,
1534 }
1535 }
1536
1537 pub fn src_hash_algorithm(&self, target: &Target) -> SourceFileHashAlgorithm {
1538 self.src_hash_algorithm.unwrap_or_else(|| {
1539 if target.is_like_msvc {
1540 SourceFileHashAlgorithm::Sha256
1541 } else {
1542 SourceFileHashAlgorithm::Md5
1543 }
1544 })
1545 }
1546
1547 pub fn checksum_hash_algorithm(&self) -> Option<SourceFileHashAlgorithm> {
1548 self.checksum_hash_algorithm
1549 }
1550}
1551
1552#[derive(#[automatically_derived]
impl ::core::marker::Copy for EntryFnType { }Copy, #[automatically_derived]
impl ::core::clone::Clone for EntryFnType {
#[inline]
fn clone(&self) -> EntryFnType {
let _: ::core::clone::AssertParamIsClone<u8>;
*self
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for EntryFnType {
#[inline]
fn eq(&self, other: &EntryFnType) -> bool {
match (self, other) {
(EntryFnType::Main { sigpipe: __self_0 }, EntryFnType::Main {
sigpipe: __arg1_0 }) => __self_0 == __arg1_0,
}
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for EntryFnType {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
match self {
EntryFnType::Main { sigpipe: __self_0 } =>
::core::hash::Hash::hash(__self_0, state),
}
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for EntryFnType {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
match self {
EntryFnType::Main { sigpipe: __self_0 } =>
::core::fmt::Formatter::debug_struct_field1_finish(f, "Main",
"sigpipe", &__self_0),
}
}
}Debug, const _: () =
{
impl ::rustc_data_structures::stable_hash::StableHash for EntryFnType
{
#[inline]
fn stable_hash<__Hcx: ::rustc_data_structures::stable_hash::StableHashCtxt>(&self,
__hcx: &mut __Hcx,
__hasher:
&mut ::rustc_data_structures::stable_hash::StableHasher) {
::std::mem::discriminant(self).stable_hash(__hcx, __hasher);
match *self {
EntryFnType::Main { sigpipe: ref __binding_0 } => {
{ __binding_0.stable_hash(__hcx, __hasher); }
}
}
}
}
};StableHash)]
1554pub enum EntryFnType {
1555 Main {
1556 sigpipe: u8,
1563 },
1564}
1565
1566pub use rustc_hir::attrs::CrateType;
1567
1568#[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)]
1569pub enum Passes {
1570 Some(Vec<String>),
1571 All,
1572}
1573
1574impl Passes {
1575 fn is_empty(&self) -> bool {
1576 match *self {
1577 Passes::Some(ref v) => v.is_empty(),
1578 Passes::All => false,
1579 }
1580 }
1581
1582 pub(crate) fn extend(&mut self, passes: impl IntoIterator<Item = String>) {
1583 match *self {
1584 Passes::Some(ref mut v) => v.extend(passes),
1585 Passes::All => {}
1586 }
1587 }
1588}
1589
1590#[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)]
1591pub enum PAuthKey {
1592 A,
1593 B,
1594}
1595
1596#[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)]
1597pub struct PacRet {
1598 pub leaf: bool,
1599 pub pc: bool,
1600 pub key: PAuthKey,
1601}
1602
1603#[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)]
1604pub struct BranchProtection {
1605 pub bti: bool,
1606 pub pac_ret: Option<PacRet>,
1607 pub gcs: bool,
1608}
1609
1610#[derive(#[automatically_derived]
impl ::core::clone::Clone for PointerAuthOption {
#[inline]
fn clone(&self) -> PointerAuthOption { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for PointerAuthOption { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for PointerAuthOption {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
const __NAMES: &str =
"Aarch64JumpTableHardeningAuthTrapsCallsElfGotFunctionPointerTypeDiscriminationIndirectGotosInitFiniInitFiniAddressDiscriminationIntrinsicsReturnAddressesTypeInfoVTPtrDiscVTPtrAddrDiscVTPtrTypeDisc";
const __OFFSET: [usize; 14] =
[0usize, 25usize, 34usize, 39usize, 45usize, 78usize, 91usize,
99usize, 128usize, 138usize, 153usize, 170usize, 183usize,
196usize];
let __d = ::core::intrinsics::discriminant_value(self) as usize;
::core::fmt::Formatter::debug_c_like_enum_write_str(f, __NAMES,
&__OFFSET, __d)
}
}Debug, #[automatically_derived]
impl ::core::cmp::Eq for PointerAuthOption {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for PointerAuthOption {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
let __self_discr = ::core::intrinsics::discriminant_value(self);
::core::hash::Hash::hash(&__self_discr, state)
}
}Hash, #[automatically_derived]
impl ::core::cmp::Ord for PointerAuthOption {
#[inline]
fn cmp(&self, other: &PointerAuthOption) -> ::core::cmp::Ordering {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
::core::cmp::Ord::cmp(&__self_discr, &__arg1_discr)
}
}Ord, #[automatically_derived]
impl ::core::cmp::PartialOrd for PointerAuthOption {
#[inline]
fn partial_cmp(&self, other: &PointerAuthOption)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::PartialEq for PointerAuthOption {
#[inline]
fn eq(&self, other: &PointerAuthOption) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq)]
1611pub enum PointerAuthOption {
1612 Aarch64JumpTableHardening,
1617 AuthTraps,
1618 Calls,
1619 ElfGot,
1620 FunctionPointerTypeDiscrimination,
1621 IndirectGotos,
1622 InitFini,
1623 InitFiniAddressDiscrimination,
1624 Intrinsics,
1625 ReturnAddresses,
1626 TypeInfoVTPtrDisc,
1627 VTPtrAddrDisc,
1628 VTPtrTypeDisc,
1629 }
1631impl PointerAuthOption {
1632 pub fn parse(s: &str) -> Option<Self> {
1633 match s {
1634 "aarch64-jump-table-hardening" => Some(Self::Aarch64JumpTableHardening),
1635 "auth-traps" => Some(Self::AuthTraps),
1636 "calls" => Some(Self::Calls),
1637 "elf-got" => Some(Self::ElfGot),
1638 "function-pointer-type-discrimination" => Some(Self::FunctionPointerTypeDiscrimination),
1639 "indirect-gotos" => Some(Self::IndirectGotos),
1640 "init-fini" => Some(Self::InitFini),
1641 "init-fini-address-discrimination" => Some(Self::InitFiniAddressDiscrimination),
1642 "intrinsics" => Some(Self::Intrinsics),
1643 "return-addresses" => Some(Self::ReturnAddresses),
1644 "typeinfo-vt-ptr-discrimination" => Some(Self::TypeInfoVTPtrDisc),
1645 "vt-ptr-addr-discrimination" => Some(Self::VTPtrAddrDisc),
1646 "vt-ptr-type-discrimination" => Some(Self::VTPtrTypeDisc),
1647 _ => None,
1648 }
1649 }
1650}
1651
1652#[derive(#[automatically_derived]
impl ::core::clone::Clone for BackendJobs {
#[inline]
fn clone(&self) -> BackendJobs {
let _: ::core::clone::AssertParamIsClone<NonZero<usize>>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for BackendJobs { }Copy)]
1653pub enum BackendJobs {
1654 Limited(NonZero<usize>),
1656 UnlimitedOr32,
1661}
1662
1663impl BackendJobs {
1664 pub fn value(self) -> NonZero<usize> {
1665 match self {
1666 BackendJobs::Limited(n) => n,
1667 BackendJobs::UnlimitedOr32 => NonZero::new(32).unwrap(),
1668 }
1669 }
1670}
1671
1672#[derive(#[automatically_derived]
impl ::core::clone::Clone for LinkerJobs {
#[inline]
fn clone(&self) -> LinkerJobs {
let _: ::core::clone::AssertParamIsClone<NonZero<usize>>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for LinkerJobs { }Copy)]
1673pub enum LinkerJobs {
1674 Default,
1676 Explicit(NonZero<usize>),
1678}
1679
1680#[derive(#[automatically_derived]
impl ::core::clone::Clone for Jobs {
#[inline]
fn clone(&self) -> Jobs {
let _: ::core::clone::AssertParamIsClone<Option<NonZero<usize>>>;
let _: ::core::clone::AssertParamIsClone<Option<BackendJobs>>;
let _: ::core::clone::AssertParamIsClone<LinkerJobs>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Jobs { }Copy)]
1683pub struct Jobs {
1684 pub frontend: Option<NonZero<usize>>,
1685 pub backend: Option<BackendJobs>,
1686 pub linker: LinkerJobs,
1687}
1688
1689fn parse_jobs_all(
1690 early_dcx: &EarlyDiagCtxt,
1691 matches: &getopts::Matches,
1692 zthreads: Option<&str>,
1693 zno_parallel_backend: bool,
1694 unstable: bool,
1695) -> Jobs {
1696 if zno_parallel_backend {
1697 early_dcx.early_fatal("`-Zno-parallel-backend` is removed, use `--jobs-backend=1` instead");
1698 }
1699 let mut available = None;
1700 let jobs = matches
1701 .opt_str("jobs")
1702 .map(|s| parse_jobs_one(early_dcx, "--jobs", &s, unstable, &mut available));
1703 let check_upper_limit = |value: Option<_>, opt_name| {
1704 if let Some(jobs) = jobs
1705 && value.or(NonZero::new(1)) > jobs.or(NonZero::new(1))
1706 {
1707 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}` cannot be larger than `--jobs`",
opt_name))
})format!("`{opt_name}` cannot be larger than `--jobs`"));
1708 }
1709 };
1710 let frontend = match matches.opt_str("jobs-frontend") {
1711 Some(jobs_frontend) => {
1712 let opt_name = "--jobs-frontend";
1713 let frontend =
1714 parse_jobs_one(early_dcx, opt_name, &jobs_frontend, unstable, &mut available);
1715 check_upper_limit(frontend, opt_name);
1716 if zthreads.is_some() {
1717 early_dcx.early_fatal("cannot use both `--jobs-frontend` and `-Zthreads`");
1718 }
1719 frontend
1720 }
1721 None => match zthreads {
1722 Some(zthreads) => {
1723 let opt_name = "-Zthreads";
1724 let frontend =
1725 parse_jobs_one(early_dcx, opt_name, zthreads, unstable, &mut available);
1726 check_upper_limit(frontend, opt_name);
1727 frontend
1728 }
1729 None => jobs.flatten(),
1730 },
1731 };
1732 let backend = match matches.opt_str("jobs-backend") {
1733 Some(jobs_backend) => {
1734 let opt_name = "--jobs-backend";
1735 let backend =
1736 parse_jobs_one(early_dcx, opt_name, &jobs_backend, unstable, &mut available);
1737 check_upper_limit(backend, opt_name);
1738 backend.map(BackendJobs::Limited)
1739 }
1740 None => match jobs {
1741 Some(n) => n.map(BackendJobs::Limited),
1742 None => Some(BackendJobs::UnlimitedOr32),
1743 },
1744 };
1745 let linker = match matches.opt_str("jobs-linker") {
1746 Some(jobs_linker) => {
1747 let opt_name = "--jobs-linker";
1748 let linker =
1749 parse_jobs_one(early_dcx, opt_name, &jobs_linker, unstable, &mut available);
1750 check_upper_limit(linker, opt_name);
1751 LinkerJobs::Explicit(linker.or(NonZero::new(1)).unwrap())
1752 }
1753 None => match jobs {
1754 Some(n) => LinkerJobs::Explicit(n.or(NonZero::new(1)).unwrap()),
1755 None => LinkerJobs::Default, },
1757 };
1758
1759 Jobs { frontend, backend, linker }
1760}
1761
1762fn parse_jobs_one(
1764 early_dcx: &EarlyDiagCtxt,
1765 opt_name: &str,
1766 s: &str,
1767 unstable: bool,
1768 available: &mut Option<u8>,
1769) -> Option<NonZero<usize>> {
1770 if s == "sync" {
1771 if !unstable {
1773 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}=sync` requires `-Z unstable-options`",
opt_name))
})format!("`{opt_name}=sync` requires `-Z unstable-options`"));
1774 }
1775 return NonZero::new(1);
1776 }
1777 let n = match u8::from_str(s) {
1781 Ok(0) => *available.get_or_insert_with(|| match thread::available_parallelism() {
1782 Ok(n) => u8::try_from(n.get()).unwrap_or(u8::MAX),
1783 Err(_) => 1,
1784 }),
1785 Ok(n) => n,
1786 Err(_) => early_dcx
1787 .early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("`{0}`: expected a number from 0 to 255 or `sync`",
opt_name))
})format!("`{opt_name}`: expected a number from 0 to 255 or `sync`")),
1788 };
1789 (n > 1).then_some(NonZero::new(usize::from(n)).unwrap())
1791}
1792
1793pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
1794 cfg::disallow_cfgs(sess, &user_cfg);
1796
1797 user_cfg.extend(cfg::default_configuration(sess));
1800 user_cfg
1801}
1802
1803pub fn build_target_config(
1804 early_dcx: &EarlyDiagCtxt,
1805 target: &TargetTuple,
1806 sysroot: &Path,
1807 unstable_options: bool,
1808) -> Target {
1809 match Target::search(target, sysroot, unstable_options) {
1810 Ok((target, warnings)) => {
1811 for warning in warnings.warning_messages() {
1812 early_dcx.early_warn(warning)
1813 }
1814
1815 if !#[allow(non_exhaustive_omitted_patterns)] match target.pointer_width {
16 | 32 | 64 => true,
_ => false,
}matches!(target.pointer_width, 16 | 32 | 64) {
1816 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!(
1817 "target specification was invalid: unrecognized target-pointer-width {}",
1818 target.pointer_width
1819 ))
1820 }
1821 target
1822 }
1823 Err(e) => {
1824 let mut err =
1825 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}"));
1826 err.help("run `rustc --print target-list` for a list of built-in targets");
1827 let typed = target.tuple();
1828 let limit = typed.len() / 3 + 1;
1829 if let Some(suggestion) = rustc_target::spec::TARGETS
1830 .iter()
1831 .filter_map(|&t| {
1832 rustc_span::edit_distance::edit_distance_with_substrings(typed, t, limit)
1833 .map(|d| (d, t))
1834 })
1835 .min_by_key(|(d, _)| *d)
1836 .map(|(_, t)| t)
1837 {
1838 err.help(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("did you mean `{0}`?", suggestion))
})format!("did you mean `{suggestion}`?"));
1839 }
1840 err.emit()
1841 }
1842 }
1843}
1844
1845#[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)]
1846pub enum OptionStability {
1847 Stable,
1848 Unstable,
1849}
1850
1851#[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)]
1852pub enum OptionKind {
1853 Opt,
1857
1858 Multi,
1862
1863 Flag,
1868
1869 FlagMulti,
1874}
1875
1876pub struct RustcOptGroup {
1877 pub name: &'static str,
1885 stability: OptionStability,
1886 kind: OptionKind,
1887
1888 short_name: &'static str,
1889 long_name: &'static str,
1890 desc: &'static str,
1891 value_hint: &'static str,
1892
1893 pub is_verbose_help_only: bool,
1896}
1897
1898impl RustcOptGroup {
1899 pub fn is_stable(&self) -> bool {
1900 self.stability == OptionStability::Stable
1901 }
1902
1903 pub fn apply(&self, options: &mut getopts::Options) {
1904 let &Self { short_name, long_name, desc, value_hint, .. } = self;
1905 match self.kind {
1906 OptionKind::Opt => options.optopt(short_name, long_name, desc, value_hint),
1907 OptionKind::Multi => options.optmulti(short_name, long_name, desc, value_hint),
1908 OptionKind::Flag => options.optflag(short_name, long_name, desc),
1909 OptionKind::FlagMulti => options.optflagmulti(short_name, long_name, desc),
1910 };
1911 }
1912
1913 pub fn long_name(&self) -> &str {
1915 self.long_name
1916 }
1917}
1918
1919pub fn make_opt(
1920 stability: OptionStability,
1921 kind: OptionKind,
1922 short_name: &'static str,
1923 long_name: &'static str,
1924 desc: &'static str,
1925 value_hint: &'static str,
1926) -> RustcOptGroup {
1927 match kind {
1929 OptionKind::Opt | OptionKind::Multi => {}
1930 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, ""),
1931 }
1932 RustcOptGroup {
1933 name: cmp::max_by_key(short_name, long_name, |s| s.len()),
1934 stability,
1935 kind,
1936 short_name,
1937 long_name,
1938 desc,
1939 value_hint,
1940 is_verbose_help_only: false,
1941 }
1942}
1943
1944static EDITION_STRING: LazyLock<String> = LazyLock::new(|| {
1945 ::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!(
1946 "Specify which edition of the compiler to use when compiling code. \
1947The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE_EDITION}."
1948 )
1949});
1950
1951static EMIT_HELP: LazyLock<String> = LazyLock::new(|| {
1952 let mut result =
1953 String::from("Comma separated list of types of output for the compiler to emit.\n");
1954 result.push_str("Each TYPE has the default FILE name:\n");
1955
1956 for output in OutputType::iter_all() {
1957 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()));
1958 }
1959
1960 result
1961});
1962
1963pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
1973 use OptionKind::{Flag, FlagMulti, Multi, Opt};
1974 use OptionStability::{Stable, Unstable};
1975
1976 use self::make_opt as opt;
1977
1978 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![
1979 opt(Stable, Flag, "h", "help", "Display this message", ""),
1980 opt(
1981 Stable,
1982 Multi,
1983 "",
1984 "cfg",
1985 "Configure the compilation environment.\n\
1986 SPEC supports the syntax `<NAME>[=\"<VALUE>\"]`.",
1987 "<SPEC>",
1988 ),
1989 opt(Stable, Multi, "", "check-cfg", "Provide list of expected cfgs for checking", "<SPEC>"),
1990 opt(
1991 Stable,
1992 Multi,
1993 "L",
1994 "",
1995 "Add a directory to the library search path. \
1996 The optional KIND can be one of <dependency|crate|native|framework|all> (default: all).",
1997 "[<KIND>=]<PATH>",
1998 ),
1999 opt(
2000 Stable,
2001 Multi,
2002 "l",
2003 "",
2004 "Link the generated crate(s) to the specified native\n\
2005 library NAME. The optional KIND can be one of\n\
2006 <static|framework|dylib> (default: dylib).\n\
2007 Optional comma separated MODIFIERS\n\
2008 <bundle|verbatim|whole-archive|as-needed>\n\
2009 may be specified each with a prefix of either '+' to\n\
2010 enable or '-' to disable.",
2011 "[<KIND>[:<MODIFIERS>]=]<NAME>[:<RENAME>]",
2012 ),
2013 make_crate_type_option(),
2014 opt(Stable, Opt, "", "crate-name", "Specify the name of the crate being built", "<NAME>"),
2015 opt(Stable, Opt, "", "edition", &EDITION_STRING, EDITION_NAME_LIST),
2016 opt(Stable, Multi, "", "emit", &EMIT_HELP, "<TYPE>[=<FILE>]"),
2017 opt(Stable, Multi, "", "print", &print_request::PRINT_HELP, "<INFO>[=<FILE>]"),
2018 opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
2019 opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=3", ""),
2020 opt(Stable, Opt, "o", "", "Write output to FILENAME", "<FILENAME>"),
2021 opt(Stable, Opt, "", "out-dir", "Write output to compiler-chosen filename in DIR", "<DIR>"),
2022 opt(
2023 Stable,
2024 Opt,
2025 "",
2026 "explain",
2027 "Provide a detailed explanation of an error message",
2028 "<OPT>",
2029 ),
2030 opt(Stable, Flag, "", "test", "Build a test harness", ""),
2031 opt(Stable, Opt, "", "target", "Target tuple for which the code is compiled", "<TARGET>"),
2032 opt(Stable, Multi, "A", "allow", "Set lint allowed", "<LINT>"),
2033 opt(Stable, Multi, "W", "warn", "Set lint warnings", "<LINT>"),
2034 opt(Stable, Multi, "", "force-warn", "Set lint force-warn", "<LINT>"),
2035 opt(Stable, Multi, "D", "deny", "Set lint denied", "<LINT>"),
2036 opt(Stable, Multi, "F", "forbid", "Set lint forbidden", "<LINT>"),
2037 opt(
2038 Stable,
2039 Multi,
2040 "",
2041 "cap-lints",
2042 "Set the most restrictive lint level. More restrictive lints are capped at this level",
2043 "<LEVEL>",
2044 ),
2045 opt(Stable, Multi, "C", "codegen", "Set a codegen option", "<OPT>[=<VALUE>]"),
2046 opt(Stable, Flag, "V", "version", "Print version info and exit", ""),
2047 opt(Stable, Flag, "v", "verbose", "Use verbose output", ""),
2048 ];
2049
2050 let verbose_only = [
2053 opt(
2054 Stable,
2055 Multi,
2056 "",
2057 "extern",
2058 "Specify where an external rust library is located",
2059 "<NAME>[=<PATH>]",
2060 ),
2061 opt(Stable, Opt, "", "sysroot", "Override the system root", "<PATH>"),
2062 opt(Unstable, Multi, "Z", "", "Set unstable / perma-unstable options", "<FLAG>"),
2063 opt(
2064 Stable,
2065 Opt,
2066 "",
2067 "error-format",
2068 "How errors and other messages are produced",
2069 "<human|json|short>",
2070 ),
2071 opt(Stable, Multi, "", "json", "Configure the JSON output of the compiler", "<CONFIG>"),
2072 opt(
2073 Stable,
2074 Opt,
2075 "",
2076 "color",
2077 "Configure coloring of output:
2078 * auto = colorize, if output goes to a tty (default);
2079 * always = always colorize output;
2080 * never = never colorize output",
2081 "<auto|always|never>",
2082 ),
2083 opt(
2084 Stable,
2085 Opt,
2086 "",
2087 "diagnostic-width",
2088 "Inform rustc of the width of the output so that diagnostics can be truncated to fit",
2089 "<WIDTH>",
2090 ),
2091 opt(
2092 Stable,
2093 Multi,
2094 "",
2095 "remap-path-prefix",
2096 "Remap source names in all output (compiler messages and output files)",
2097 "<FROM>=<TO>",
2098 ),
2099 opt(
2100 Stable,
2101 Opt,
2102 "",
2103 "remap-path-scope",
2104 "Defines which scopes of paths should be remapped by `--remap-path-prefix`",
2105 "<macro,diagnostics,debuginfo,coverage,object,all>",
2106 ),
2107 opt(Unstable, Multi, "", "env-set", "Inject an environment variable", "<VAR>=<VALUE>"),
2108 opt(Unstable, Opt, "j", "jobs", "Limit on the number of used parallel jobs", "<N>"),
2109 opt(
2110 Unstable,
2111 Opt,
2112 "",
2113 "jobs-frontend",
2114 "Limit on the number of parallel jobs used by frontend",
2115 "<N>",
2116 ),
2117 opt(
2118 Unstable,
2119 Opt,
2120 "",
2121 "jobs-backend",
2122 "Limit on the number of parallel jobs used by backend",
2123 "<N>",
2124 ),
2125 opt(
2126 Unstable,
2127 Opt,
2128 "",
2129 "jobs-linker",
2130 "Limit on the number of parallel jobs used by linker",
2131 "<N>",
2132 ),
2133 ];
2134 options.extend(verbose_only.into_iter().map(|mut opt| {
2135 opt.is_verbose_help_only = true;
2136 opt
2137 }));
2138
2139 options
2140}
2141
2142pub fn get_cmd_lint_options(
2143 early_dcx: &EarlyDiagCtxt,
2144 matches: &getopts::Matches,
2145) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
2146 let mut lint_opts_with_position = ::alloc::vec::Vec::new()vec![];
2147 let mut describe_lints = false;
2148
2149 for level in [lint::Allow, lint::Warn, lint::ForceWarn, lint::Deny, lint::Forbid] {
2150 for (arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
2151 if lint_name == "help" {
2152 describe_lints = true;
2153 } else {
2154 lint_opts_with_position.push((arg_pos, lint_name.replace('-', "_"), level));
2155 }
2156 }
2157 }
2158
2159 lint_opts_with_position.sort_by_key(|x| x.0);
2160 let lint_opts = lint_opts_with_position
2161 .iter()
2162 .cloned()
2163 .map(|(_, lint_name, level)| (lint_name, level))
2164 .collect();
2165
2166 let lint_cap = matches.opt_str("cap-lints").map(|cap| {
2167 lint::Level::from_str(&cap)
2168 .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}`")))
2169 });
2170
2171 (lint_opts, describe_lints, lint_cap)
2172}
2173
2174pub fn parse_color(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> ColorConfig {
2176 match matches.opt_str("color").as_deref() {
2177 Some("auto") => ColorConfig::Auto,
2178 Some("always") => ColorConfig::Always,
2179 Some("never") => ColorConfig::Never,
2180
2181 None => ColorConfig::Auto,
2182
2183 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!(
2184 "argument for `--color` must be auto, \
2185 always or never (instead was `{arg}`)"
2186 )),
2187 }
2188}
2189
2190pub struct JsonConfig {
2192 pub json_rendered: HumanReadableErrorType,
2193 pub json_color: ColorConfig,
2194 json_artifact_notifications: bool,
2195 json_timings: bool,
2198 pub json_unused_externs: JsonUnusedExterns,
2199 json_future_incompat: bool,
2200}
2201
2202#[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)]
2204pub enum JsonUnusedExterns {
2205 No,
2207 Silent,
2209 Loud,
2211}
2212
2213impl JsonUnusedExterns {
2214 pub fn is_enabled(&self) -> bool {
2215 match self {
2216 JsonUnusedExterns::No => false,
2217 JsonUnusedExterns::Loud | JsonUnusedExterns::Silent => true,
2218 }
2219 }
2220
2221 pub fn is_loud(&self) -> bool {
2222 match self {
2223 JsonUnusedExterns::No | JsonUnusedExterns::Silent => false,
2224 JsonUnusedExterns::Loud => true,
2225 }
2226 }
2227}
2228
2229pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> JsonConfig {
2234 let mut json_rendered = HumanReadableErrorType { short: false, unicode: false };
2235 let mut json_color = ColorConfig::Never;
2236 let mut json_artifact_notifications = false;
2237 let mut json_unused_externs = JsonUnusedExterns::No;
2238 let mut json_future_incompat = false;
2239 let mut json_timings = false;
2240 for option in matches.opt_strs("json") {
2241 if matches.opt_str("color").is_some() {
2245 early_dcx.early_fatal("cannot specify the `--color` option with `--json`");
2246 }
2247
2248 for sub_option in option.split(',') {
2249 match sub_option {
2250 "diagnostic-short" => {
2251 json_rendered = HumanReadableErrorType { short: true, unicode: false };
2252 }
2253 "diagnostic-unicode" => {
2254 json_rendered = HumanReadableErrorType { short: false, unicode: true };
2255 }
2256 "diagnostic-rendered-ansi" => json_color = ColorConfig::Always,
2257 "artifacts" => json_artifact_notifications = true,
2258 "timings" => json_timings = true,
2259 "unused-externs" => json_unused_externs = JsonUnusedExterns::Loud,
2260 "unused-externs-silent" => json_unused_externs = JsonUnusedExterns::Silent,
2261 "future-incompat" => json_future_incompat = true,
2262 s => early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("unknown `--json` option `{0}`", s))
})format!("unknown `--json` option `{s}`")),
2263 }
2264 }
2265 }
2266
2267 JsonConfig {
2268 json_rendered,
2269 json_color,
2270 json_artifact_notifications,
2271 json_timings,
2272 json_unused_externs,
2273 json_future_incompat,
2274 }
2275}
2276
2277pub fn parse_error_format(
2279 early_dcx: &mut EarlyDiagCtxt,
2280 matches: &getopts::Matches,
2281 color_config: ColorConfig,
2282 json_color: ColorConfig,
2283 json_rendered: HumanReadableErrorType,
2284) -> ErrorOutputType {
2285 let default_kind = HumanReadableErrorType { short: false, unicode: false };
2286 let error_format = if matches.opts_present(&["error-format".to_owned()]) {
2291 match matches.opt_str("error-format").as_deref() {
2292 None | Some("human") => {
2293 ErrorOutputType::HumanReadable { color_config, kind: default_kind }
2294 }
2295 Some("json") => {
2296 ErrorOutputType::Json { pretty: false, json_rendered, color_config: json_color }
2297 }
2298 Some("pretty-json") => {
2299 ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color }
2300 }
2301 Some("short") => ErrorOutputType::HumanReadable {
2302 kind: HumanReadableErrorType { short: true, unicode: false },
2303 color_config,
2304 },
2305 Some("human-unicode") => ErrorOutputType::HumanReadable {
2306 kind: HumanReadableErrorType { short: false, unicode: true },
2307 color_config,
2308 },
2309 Some(arg) => {
2310 early_dcx.set_error_format(ErrorOutputType::HumanReadable {
2311 color_config,
2312 kind: default_kind,
2313 });
2314 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!(
2315 "argument for `--error-format` must be `human`, `human-unicode`, \
2316 `json`, `pretty-json` or `short` (instead was `{arg}`)"
2317 ))
2318 }
2319 }
2320 } else {
2321 ErrorOutputType::HumanReadable { color_config, kind: default_kind }
2322 };
2323
2324 match error_format {
2325 ErrorOutputType::Json { .. } => {}
2326
2327 _ if !matches.opt_strs("json").is_empty() => {
2331 early_dcx.early_fatal("using `--json` requires also using `--error-format=json`");
2332 }
2333
2334 _ => {}
2335 }
2336
2337 error_format
2338}
2339
2340pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Edition {
2341 let edition = match matches.opt_str("edition") {
2342 Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| {
2343 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!(
2344 "argument for `--edition` must be one of: \
2345 {EDITION_NAME_LIST}. (instead was `{arg}`)"
2346 ))
2347 }),
2348 None => DEFAULT_EDITION,
2349 };
2350
2351 if !edition.is_stable() && !nightly_options::is_unstable_enabled(matches) {
2352 let is_nightly = nightly_options::match_is_nightly_build(matches);
2353 let msg = if !is_nightly {
2354 ::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!(
2355 "the crate requires edition {edition}, but the latest edition supported by this Rust version is {LATEST_STABLE_EDITION}"
2356 )
2357 } else {
2358 ::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")
2359 };
2360 early_dcx.early_fatal(msg)
2361 }
2362
2363 edition
2364}
2365
2366fn check_error_format_stability(
2367 early_dcx: &EarlyDiagCtxt,
2368 unstable_opts: &UnstableOptions,
2369 is_nightly_build: bool,
2370 format: ErrorOutputType,
2371) {
2372 if unstable_opts.unstable_options || is_nightly_build {
2373 return;
2374 }
2375 let format = match format {
2376 ErrorOutputType::Json { pretty: true, .. } => "pretty-json",
2377 ErrorOutputType::HumanReadable { kind, .. } => match kind {
2378 HumanReadableErrorType { unicode: true, .. } => "human-unicode",
2379 _ => return,
2380 },
2381 _ => return,
2382 };
2383 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"))
2384}
2385
2386fn parse_output_types(
2387 early_dcx: &EarlyDiagCtxt,
2388 unstable_opts: &UnstableOptions,
2389 matches: &getopts::Matches,
2390) -> OutputTypes {
2391 let mut output_types = BTreeMap::new();
2392 if !unstable_opts.parse_crate_root_only {
2393 for list in matches.opt_strs("emit") {
2394 for output_type in list.split(',') {
2395 let (shorthand, path) = split_out_file_name(output_type);
2396 let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
2397 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!(
2398 "unknown emission type: `{shorthand}` - expected one of: {display}",
2399 display = OutputType::shorthands_display(),
2400 ))
2401 });
2402 if output_type == OutputType::ThinLinkBitcode && !unstable_opts.unstable_options {
2403 early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0} requested but -Zunstable-options not specified",
OutputType::ThinLinkBitcode.shorthand()))
})format!(
2404 "{} requested but -Zunstable-options not specified",
2405 OutputType::ThinLinkBitcode.shorthand()
2406 ));
2407 }
2408 output_types.insert(output_type, path);
2409 }
2410 }
2411 };
2412 if output_types.is_empty() {
2413 output_types.insert(OutputType::Exe, None);
2414 }
2415 OutputTypes(output_types)
2416}
2417
2418fn split_out_file_name(arg: &str) -> (&str, Option<OutFileName>) {
2419 match arg.split_once('=') {
2420 None => (arg, None),
2421 Some((kind, "-")) => (kind, Some(OutFileName::Stdout)),
2422 Some((kind, path)) => (kind, Some(OutFileName::Real(PathBuf::from(path)))),
2423 }
2424}
2425
2426fn should_override_cgus_and_disable_thinlto(
2427 early_dcx: &EarlyDiagCtxt,
2428 output_types: &OutputTypes,
2429 matches: &getopts::Matches,
2430 mut codegen_units: Option<usize>,
2431) -> (bool, Option<usize>) {
2432 let mut disable_local_thinlto = false;
2433 let incompatible: Vec<_> = output_types
2436 .0
2437 .iter()
2438 .map(|ot_path| ot_path.0)
2439 .filter(|ot| !ot.is_compatible_with_codegen_units_and_single_output_file())
2440 .map(|ot| ot.shorthand())
2441 .collect();
2442 if !incompatible.is_empty() {
2443 match codegen_units {
2444 Some(n) if n > 1 => {
2445 if matches.opt_present("o") {
2446 for ot in &incompatible {
2447 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!(
2448 "`--emit={ot}` with `-o` incompatible with \
2449 `-C codegen-units=N` for N > 1",
2450 ));
2451 }
2452 early_dcx.early_warn("resetting to default -C codegen-units=1");
2453 codegen_units = Some(1);
2454 disable_local_thinlto = true;
2455 }
2456 }
2457 _ => {
2458 codegen_units = Some(1);
2459 disable_local_thinlto = true;
2460 }
2461 }
2462 }
2463
2464 if codegen_units == Some(0) {
2465 early_dcx.early_fatal("value for codegen units must be a positive non-zero integer");
2466 }
2467
2468 (disable_local_thinlto, codegen_units)
2469}
2470
2471pub fn parse_target_triple(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> TargetTuple {
2472 match matches.opt_str("target") {
2473 Some(target) if target.ends_with(".json") => {
2474 let path = Path::new(&target);
2475 TargetTuple::from_path(path).unwrap_or_else(|_| {
2476 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"))
2477 })
2478 }
2479 Some(target) => TargetTuple::TargetTuple(target),
2480 _ => TargetTuple::from_tuple(host_tuple()),
2481 }
2482}
2483
2484fn parse_opt_level(
2485 early_dcx: &EarlyDiagCtxt,
2486 matches: &getopts::Matches,
2487 cg: &CodegenOptions,
2488) -> OptLevel {
2489 let max_o = matches.opt_positions("O").into_iter().max();
2496 let max_c = matches
2497 .opt_strs_pos("C")
2498 .into_iter()
2499 .flat_map(|(i, s)| {
2500 if let Some("opt-level") = s.split('=').next() { Some(i) } else { None }
2502 })
2503 .max();
2504 if max_o > max_c {
2505 OptLevel::Aggressive
2506 } else {
2507 match cg.opt_level.as_ref() {
2508 "0" => OptLevel::No,
2509 "1" => OptLevel::Less,
2510 "2" => OptLevel::More,
2511 "3" => OptLevel::Aggressive,
2512 "s" => OptLevel::Size,
2513 "z" => OptLevel::SizeMin,
2514 arg => {
2515 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!(
2516 "optimization level needs to be \
2517 between 0-3, s or z (instead was `{arg}`)"
2518 ));
2519 }
2520 }
2521 }
2522}
2523
2524fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInfo {
2525 let max_g = matches.opt_positions("g").into_iter().max();
2526 let max_c = matches
2527 .opt_strs_pos("C")
2528 .into_iter()
2529 .flat_map(|(i, s)| {
2530 if let Some("debuginfo") = s.split('=').next() { Some(i) } else { None }
2532 })
2533 .max();
2534 if max_g > max_c { DebugInfo::Full } else { cg.debuginfo }
2535}
2536
2537pub fn parse_externs(
2538 early_dcx: &EarlyDiagCtxt,
2539 matches: &getopts::Matches,
2540 unstable_opts: &UnstableOptions,
2541) -> Externs {
2542 let is_unstable_enabled = unstable_opts.unstable_options;
2543 let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
2544 for arg in matches.opt_strs("extern") {
2545 let ExternOpt { crate_name: name, path, options } =
2546 split_extern_opt(early_dcx, unstable_opts, &arg).unwrap_or_else(|e| e.emit());
2547
2548 let entry = externs.entry(name.to_owned());
2549
2550 use std::collections::btree_map::Entry;
2551
2552 let entry = if let Some(path) = path {
2553 let path = CanonicalizedPath::new(path);
2555 match entry {
2556 Entry::Vacant(vacant) => {
2557 let files = BTreeSet::from_iter(iter::once(path));
2558 vacant.insert(ExternEntry::new(ExternLocation::ExactPaths(files)))
2559 }
2560 Entry::Occupied(occupied) => {
2561 let ext_ent = occupied.into_mut();
2562 match ext_ent {
2563 ExternEntry { location: ExternLocation::ExactPaths(files), .. } => {
2564 files.insert(path);
2565 }
2566 ExternEntry {
2567 location: location @ ExternLocation::FoundInLibrarySearchDirectories,
2568 ..
2569 } => {
2570 let files = BTreeSet::from_iter(iter::once(path));
2572 *location = ExternLocation::ExactPaths(files);
2573 }
2574 }
2575 ext_ent
2576 }
2577 }
2578 } else {
2579 match entry {
2581 Entry::Vacant(vacant) => {
2582 vacant.insert(ExternEntry::new(ExternLocation::FoundInLibrarySearchDirectories))
2583 }
2584 Entry::Occupied(occupied) => {
2585 occupied.into_mut()
2587 }
2588 }
2589 };
2590
2591 let mut is_private_dep = false;
2592 let mut add_prelude = true;
2593 let mut nounused_dep = false;
2594 let mut force = false;
2595 if let Some(opts) = options {
2596 if !is_unstable_enabled {
2597 early_dcx.early_fatal(
2598 "the `-Z unstable-options` flag must also be passed to \
2599 enable `--extern` options",
2600 );
2601 }
2602 for opt in opts.split(',') {
2603 match opt {
2604 "priv" => is_private_dep = true,
2605 "noprelude" => {
2606 if let ExternLocation::ExactPaths(_) = &entry.location {
2607 add_prelude = false;
2608 } else {
2609 early_dcx.early_fatal(
2610 "the `noprelude` --extern option requires a file path",
2611 );
2612 }
2613 }
2614 "nounused" => nounused_dep = true,
2615 "force" => force = true,
2616 _ => early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("unknown --extern option `{0}`",
opt))
})format!("unknown --extern option `{opt}`")),
2617 }
2618 }
2619 }
2620
2621 entry.is_private_dep |= is_private_dep;
2624 entry.nounused_dep |= nounused_dep;
2626 entry.force |= force;
2628 entry.add_prelude |= add_prelude;
2630 }
2631 Externs(externs)
2632}
2633
2634fn parse_remap_path_prefix(
2635 early_dcx: &EarlyDiagCtxt,
2636 matches: &getopts::Matches,
2637) -> Vec<(PathBuf, PathBuf)> {
2638 matches
2639 .opt_strs("remap-path-prefix")
2640 .into_iter()
2641 .map(|remap| match remap.rsplit_once('=') {
2642 None => {
2643 early_dcx.early_fatal("--remap-path-prefix must contain '=' between FROM and TO")
2644 }
2645 Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)),
2646 })
2647 .collect()
2648}
2649
2650fn parse_logical_env(
2651 early_dcx: &EarlyDiagCtxt,
2652 matches: &getopts::Matches,
2653) -> FxIndexMap<String, String> {
2654 let mut vars = FxIndexMap::default();
2655
2656 for arg in matches.opt_strs("env-set") {
2657 if let Some((name, val)) = arg.split_once('=') {
2658 vars.insert(name.to_string(), val.to_string());
2659 } else {
2660 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}`"));
2661 }
2662 }
2663
2664 vars
2665}
2666
2667#[allow(rustc::bad_opt_access)]
2669pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::Matches) -> Options {
2670 let color = parse_color(early_dcx, matches);
2671
2672 let edition = parse_crate_edition(early_dcx, matches);
2673
2674 let crate_name = matches.opt_str("crate-name");
2675 let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
2676 let JsonConfig {
2677 json_rendered,
2678 json_color,
2679 json_artifact_notifications,
2680 json_timings,
2681 json_unused_externs,
2682 json_future_incompat,
2683 } = parse_json(early_dcx, matches);
2684
2685 let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered);
2686
2687 early_dcx.set_error_format(error_format);
2688
2689 let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
2690 early_dcx.early_fatal("`--diagnostic-width` must be an positive integer");
2691 });
2692
2693 let unparsed_crate_types = matches.opt_strs("crate-type");
2694 let crate_types = parse_crate_types_from_list(unparsed_crate_types)
2695 .unwrap_or_else(|e| early_dcx.early_fatal(e));
2696
2697 let mut collected_options = Default::default();
2698
2699 let mut unstable_opts = UnstableOptions::build(early_dcx, matches, &mut collected_options);
2700
2701 if unstable_opts.staticlib_hide_internal_symbols && !crate_types.contains(&CrateType::StaticLib)
2702 {
2703 early_dcx.early_warn(
2704 "-Zstaticlib-hide-internal-symbols has no effect without `--crate-type staticlib`",
2705 );
2706 }
2707
2708 if unstable_opts.staticlib_rename_internal_symbols
2709 && !crate_types.contains(&CrateType::StaticLib)
2710 {
2711 early_dcx.early_warn(
2712 "-Zstaticlib-rename-internal-symbols has no effect without `--crate-type staticlib`",
2713 );
2714 }
2715
2716 let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches);
2717
2718 if !unstable_opts.unstable_options && json_timings {
2719 early_dcx.early_fatal("--json=timings is unstable and requires using `-Zunstable-options`");
2720 }
2721
2722 check_error_format_stability(
2723 early_dcx,
2724 &unstable_opts,
2725 unstable_features.is_nightly_build(),
2726 error_format,
2727 );
2728
2729 let output_types = parse_output_types(early_dcx, &unstable_opts, matches);
2730
2731 let mut cg = CodegenOptions::build(early_dcx, matches, &mut collected_options);
2732 let (disable_local_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto(
2733 early_dcx,
2734 &output_types,
2735 matches,
2736 cg.codegen_units,
2737 );
2738
2739 let incremental = cg.incremental.as_ref().map(PathBuf::from);
2740
2741 if cg.profile_generate.enabled() && cg.profile_use.is_some() {
2742 early_dcx.early_fatal("options `-C profile-generate` and `-C profile-use` are exclusive");
2743 }
2744
2745 if unstable_opts.profile_sample_use.is_some()
2746 && (cg.profile_generate.enabled() || cg.profile_use.is_some())
2747 {
2748 early_dcx.early_fatal(
2749 "option `-Z profile-sample-use` cannot be used with `-C profile-generate` or `-C profile-use`",
2750 );
2751 }
2752
2753 match cg.symbol_mangling_version {
2756 None | Some(SymbolManglingVersion::V0) => {}
2758
2759 Some(SymbolManglingVersion::Legacy) => {
2761 if !unstable_opts.unstable_options {
2762 early_dcx.early_fatal(
2763 "`-C symbol-mangling-version=legacy` requires `-Z unstable-options`",
2764 );
2765 }
2766 }
2767 Some(SymbolManglingVersion::Hashed) => {
2768 if !unstable_opts.unstable_options {
2769 early_dcx.early_fatal(
2770 "`-C symbol-mangling-version=hashed` requires `-Z unstable-options`",
2771 );
2772 }
2773 }
2774 }
2775
2776 if cg.instrument_coverage != InstrumentCoverage::No {
2777 if cg.profile_generate.enabled() || cg.profile_use.is_some() {
2778 early_dcx.early_fatal(
2779 "option `-C instrument-coverage` is not compatible with either `-C profile-use` \
2780 or `-C profile-generate`",
2781 );
2782 }
2783
2784 match cg.symbol_mangling_version {
2789 None => cg.symbol_mangling_version = Some(SymbolManglingVersion::V0),
2790 Some(SymbolManglingVersion::Legacy) => {
2791 early_dcx.early_warn(
2792 "-C instrument-coverage requires symbol mangling version `v0`, \
2793 but `-C symbol-mangling-version=legacy` was specified",
2794 );
2795 }
2796 Some(SymbolManglingVersion::V0) => {}
2797 Some(SymbolManglingVersion::Hashed) => {
2798 early_dcx.early_warn(
2799 "-C instrument-coverage requires symbol mangling version `v0`, \
2800 but `-C symbol-mangling-version=hashed` was specified",
2801 );
2802 }
2803 }
2804 }
2805
2806 if let Ok(graphviz_font) = std::env::var("RUSTC_GRAPHVIZ_FONT") {
2807 unstable_opts.graphviz_font = graphviz_font;
2810 }
2811
2812 if !cg.embed_bitcode {
2813 match cg.lto {
2814 LtoCli::No | LtoCli::Unspecified => {}
2815 LtoCli::Yes | LtoCli::NoParam | LtoCli::Thin | LtoCli::Fat => {
2816 early_dcx.early_fatal("options `-C embed-bitcode=no` and `-C lto` are incompatible")
2817 }
2818 }
2819 }
2820
2821 let unstable_options_enabled = nightly_options::is_unstable_enabled(matches);
2822 if !unstable_options_enabled && cg.force_frame_pointers == FramePointer::NonLeaf {
2823 early_dcx.early_fatal(
2824 "`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \
2825 and a nightly compiler",
2826 )
2827 }
2828
2829 if !nightly_options::is_unstable_enabled(matches) && !unstable_opts.offload.is_empty() {
2830 early_dcx.early_fatal(
2831 "`-Zoffload=Enable` also requires `-Zunstable-options` \
2832 and a nightly compiler",
2833 )
2834 }
2835
2836 let target_triple = parse_target_triple(early_dcx, matches);
2837
2838 if !unstable_options_enabled {
2841 if let Err(error) = cg.link_self_contained.check_unstable_variants(&target_triple) {
2842 early_dcx.early_fatal(error);
2843 }
2844
2845 if let Some(flavor) = cg.linker_flavor {
2846 if flavor.is_unstable() {
2847 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!(
2848 "the linker flavor `{}` is unstable, the `-Z unstable-options` \
2849 flag must also be passed to use the unstable values",
2850 flavor.desc()
2851 ));
2852 }
2853 }
2854 }
2855
2856 if let Some(erroneous_components) = cg.link_self_contained.check_consistency() {
2859 let names: String = erroneous_components
2860 .into_iter()
2861 .map(|c| c.as_str().unwrap())
2862 .intersperse(", ")
2863 .collect();
2864 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!(
2865 "some `-C link-self-contained` components were both enabled and disabled: {names}"
2866 ));
2867 }
2868
2869 let prints = print_request::collect_print_requests(early_dcx, &mut cg, &unstable_opts, matches);
2870
2871 if unstable_opts.retpoline_external_thunk {
2873 unstable_opts.retpoline = true;
2874 collected_options.target_modifiers.insert(
2875 OptionsTargetModifiers::UnstableOptions(UnstableOptionsTargetModifiers::Retpoline),
2876 "true".to_string(),
2877 );
2878 }
2879
2880 let cg = cg;
2881
2882 let opt_level = parse_opt_level(early_dcx, matches, &cg);
2883 let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
2887 let debuginfo = select_debuginfo(matches, &cg);
2888
2889 if !unstable_options_enabled {
2890 if let Err(error) = cg.linker_features.check_unstable_variants(&target_triple) {
2891 early_dcx.early_fatal(error);
2892 }
2893 }
2894
2895 if !unstable_options_enabled && cg.panic == Some(PanicStrategy::ImmediateAbort) {
2896 early_dcx.early_fatal(
2897 "`-Cpanic=immediate-abort` requires `-Zunstable-options` and a nightly compiler",
2898 )
2899 }
2900
2901 let libs = parse_native_libs(early_dcx, &unstable_opts, unstable_features, matches);
2903
2904 let test = matches.opt_present("test");
2905
2906 if !cg.remark.is_empty() && debuginfo == DebugInfo::None {
2907 early_dcx.early_warn("-C remark requires \"-C debuginfo=n\" to show source locations");
2908 }
2909
2910 if cg.remark.is_empty() && unstable_opts.remark_dir.is_some() {
2911 early_dcx
2912 .early_warn("using -Z remark-dir without enabling remarks using e.g. -C remark=all");
2913 }
2914
2915 let externs = parse_externs(early_dcx, matches, &unstable_opts);
2916
2917 let remap_path_prefix = parse_remap_path_prefix(early_dcx, matches);
2918 let remap_path_scope = parse_remap_path_scope(early_dcx, matches, &unstable_opts);
2919
2920 let pretty = parse_pretty(early_dcx, &unstable_opts);
2921
2922 if unstable_opts.dump_dep_graph && !unstable_opts.query_dep_graph {
2924 early_dcx.early_fatal("can't dump dependency graph without `-Z query-dep-graph`");
2925 }
2926
2927 let logical_env = parse_logical_env(early_dcx, matches);
2928
2929 let sysroot = Sysroot::new(matches.opt_str("sysroot").map(PathBuf::from));
2930
2931 let real_source_base_dir = |suffix: &str, confirm: &str| {
2932 let mut candidate = sysroot.path().join(suffix);
2933 if let Ok(metadata) = candidate.symlink_metadata() {
2934 if metadata.file_type().is_symlink() {
2938 if let Ok(symlink_dest) = std::fs::read_link(&candidate) {
2939 candidate = symlink_dest;
2940 }
2941 }
2942 }
2943
2944 candidate.join(confirm).is_file().then_some(candidate)
2946 };
2947
2948 let real_rust_source_base_dir =
2949 real_source_base_dir("lib/rustlib/src/rust", "library/std/src/lib.rs");
2951
2952 let real_rustc_dev_source_base_dir =
2953 real_source_base_dir("lib/rustlib/rustc-src/rust", "compiler/rustc/src/main.rs");
2955
2956 let search_paths: Vec<SearchPath> = {
2961 let mut seen_search_paths = FxHashSet::default();
2962 let search_path_matches: Vec<String> = matches.opt_strs("L");
2963 search_path_matches
2964 .iter()
2965 .filter(|p| seen_search_paths.insert(*p))
2966 .map(|path| {
2967 SearchPath::from_cli_opt(
2968 sysroot.path(),
2969 &target_triple,
2970 early_dcx,
2971 &path,
2972 unstable_opts.unstable_options,
2973 )
2974 })
2975 .collect()
2976 };
2977
2978 let working_dir = {
2981 let working_dir = std::env::current_dir().unwrap_or_else(|e| {
2982 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}"));
2983 });
2984
2985 let file_mapping = file_path_mapping(
2986 remap_path_prefix.clone(),
2987 unstable_opts.remap_cwd_prefix.as_deref(),
2988 remap_path_scope,
2989 );
2990 file_mapping.to_real_filename(&RealFileName::empty(), &working_dir)
2991 };
2992
2993 let verbose = matches.opt_present("verbose") || unstable_opts.verbose_internals;
2994
2995 let jobs = parse_jobs_all(
2996 early_dcx,
2997 matches,
2998 unstable_opts.threads.as_deref(),
2999 unstable_opts.no_parallel_backend,
3000 unstable_opts.unstable_options,
3001 );
3002
3003 Options {
3004 crate_types,
3005 optimize: opt_level,
3006 debuginfo,
3007 lint_opts,
3008 lint_cap,
3009 describe_lints,
3010 output_types,
3011 search_paths,
3012 sysroot,
3013 target_triple,
3014 test,
3015 incremental,
3016 unstable_opts,
3017 prints,
3018 cg,
3019 error_format,
3020 diagnostic_width,
3021 externs,
3022 unstable_features,
3023 crate_name,
3024 libs,
3025 debug_assertions,
3026 actually_rustdoc: false,
3027 resolve_doc_links: ResolveDocLinks::ExportedMetadata,
3028 trimmed_def_paths: false,
3029 cli_forced_codegen_units: codegen_units,
3030 cli_forced_local_thinlto_off: disable_local_thinlto,
3031 remap_path_prefix,
3032 remap_path_scope,
3033 real_rust_source_base_dir,
3034 real_rustc_dev_source_base_dir,
3035 edition,
3036 json_artifact_notifications,
3037 json_timings,
3038 json_unused_externs,
3039 json_future_incompat,
3040 pretty,
3041 working_dir,
3042 color,
3043 logical_env,
3044 verbose,
3045 target_modifiers: collected_options.target_modifiers,
3046 mitigation_coverage_map: collected_options.mitigations,
3047 jobs,
3048 }
3049}
3050
3051fn parse_pretty(early_dcx: &EarlyDiagCtxt, unstable_opts: &UnstableOptions) -> Option<PpMode> {
3052 use PpMode::*;
3053
3054 let first = match unstable_opts.unpretty.as_deref()? {
3055 "normal" => Source(PpSourceMode::Normal),
3056 "expanded" => Source(PpSourceMode::Expanded),
3057 "expanded,identified" => Source(PpSourceMode::ExpandedIdentified),
3058 "expanded,hygiene" => Source(PpSourceMode::ExpandedHygiene),
3059 "ast-tree" => AstTree,
3060 "ast-tree,expanded" => AstTreeExpanded,
3061 "hir" => Hir(PpHirMode::Normal),
3062 "hir,identified" => Hir(PpHirMode::Identified),
3063 "hir,typed" => Hir(PpHirMode::Typed),
3064 "hir-tree" => HirTree,
3065 "thir-tree" => ThirTree,
3066 "thir-flat" => ThirFlat,
3067 "mir" => Mir,
3068 "stable-mir" => StableMir,
3069 "mir-cfg" => MirCFG,
3070 name => early_dcx.early_fatal(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("argument to `unpretty` must be one of `normal`, `expanded`, `expanded,identified`, `expanded,hygiene`, `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, `hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir`, `stable-mir`, or `mir-cfg`; got {0}",
name))
})format!(
3071 "argument to `unpretty` must be one of `normal`, \
3072 `expanded`, `expanded,identified`, `expanded,hygiene`, \
3073 `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
3074 `hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir`, `stable-mir`, or \
3075 `mir-cfg`; got {name}"
3076 )),
3077 };
3078 {
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:3078",
"rustc_session::config", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_session/src/config.rs"),
::tracing_core::__macro_support::Option::Some(3078u32),
::tracing_core::__macro_support::Option::Some("rustc_session::config"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
__CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("got unpretty option: {0:?}",
first) as &dyn ::tracing::field::Value))])
});
} else { ; }
};debug!("got unpretty option: {first:?}");
3079 Some(first)
3080}
3081
3082pub fn make_crate_type_option() -> RustcOptGroup {
3083 make_opt(
3084 OptionStability::Stable,
3085 OptionKind::Multi,
3086 "",
3087 "crate-type",
3088 "Comma separated list of types of crates
3089 for the compiler to emit",
3090 "<bin|lib|rlib|dylib|cdylib|staticlib|proc-macro>",
3091 )
3092}
3093
3094pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> {
3095 let mut crate_types: Vec<CrateType> = Vec::new();
3096 for unparsed_crate_type in &list_list {
3097 for part in unparsed_crate_type.split(',') {
3098 let new_part = match part {
3099 "lib" => CrateType::default(),
3100 "rlib" => CrateType::Rlib,
3101 "staticlib" => CrateType::StaticLib,
3102 "dylib" => CrateType::Dylib,
3103 "cdylib" => CrateType::Cdylib,
3104 "bin" => CrateType::Executable,
3105 "proc-macro" => CrateType::ProcMacro,
3106 "sdylib" => CrateType::Sdylib,
3107 _ => {
3108 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!(
3109 "unknown crate type: `{part}`, expected one of: \
3110 `lib`, `rlib`, `staticlib`, `dylib`, `cdylib`, `bin`, `proc-macro`",
3111 ));
3112 }
3113 };
3114 if !crate_types.contains(&new_part) {
3115 crate_types.push(new_part)
3116 }
3117 }
3118 }
3119
3120 Ok(crate_types)
3121}
3122
3123pub mod nightly_options {
3124 use rustc_feature::UnstableFeatures;
3125
3126 use super::{OptionStability, RustcOptGroup};
3127 use crate::EarlyDiagCtxt;
3128
3129 pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
3130 match_is_nightly_build(matches)
3131 && matches.opt_strs("Z").iter().any(|x| *x == "unstable-options")
3132 }
3133
3134 pub fn match_is_nightly_build(matches: &getopts::Matches) -> bool {
3135 is_nightly_build(matches.opt_str("crate-name").as_deref())
3136 }
3137
3138 fn is_nightly_build(krate: Option<&str>) -> bool {
3139 UnstableFeatures::from_environment(krate).is_nightly_build()
3140 }
3141
3142 pub fn check_nightly_options(
3143 early_dcx: &EarlyDiagCtxt,
3144 matches: &getopts::Matches,
3145 flags: &[RustcOptGroup],
3146 ) {
3147 let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options");
3148 let really_allows_unstable_options = match_is_nightly_build(matches);
3149 let mut nightly_options_on_stable = 0;
3150
3151 for opt in flags.iter() {
3152 if opt.stability == OptionStability::Stable {
3153 continue;
3154 }
3155 if !matches.opt_present(opt.name) {
3156 continue;
3157 }
3158 if opt.name != "Z" && !has_z_unstable_option {
3159 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!(
3160 "the `-Z unstable-options` flag must also be passed to enable \
3161 the flag `{}`",
3162 opt.name
3163 ));
3164 }
3165 if really_allows_unstable_options {
3166 continue;
3167 }
3168 match opt.stability {
3169 OptionStability::Unstable => {
3170 nightly_options_on_stable += 1;
3171 let msg = ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("the option `{0}` is only accepted on the nightly compiler",
opt.name))
})format!(
3172 "the option `{}` is only accepted on the nightly compiler",
3173 opt.name
3174 );
3175 let _ = early_dcx.early_err(msg);
3177 }
3178 OptionStability::Stable => {}
3179 }
3180 }
3181 if nightly_options_on_stable > 0 {
3182 early_dcx
3183 .early_help("consider switching to a nightly toolchain: `rustup default nightly`");
3184 early_dcx.early_note("selecting a toolchain with `+toolchain` arguments require a rustup proxy; see <https://rust-lang.github.io/rustup/concepts/index.html>");
3185 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>");
3186 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!(
3187 "{} nightly option{} were parsed",
3188 nightly_options_on_stable,
3189 if nightly_options_on_stable > 1 { "s" } else { "" }
3190 ));
3191 }
3192 }
3193}
3194
3195#[derive(#[automatically_derived]
impl ::core::marker::Copy for PpSourceMode { }Copy, #[automatically_derived]
impl ::core::clone::Clone for PpSourceMode {
#[inline]
fn clone(&self) -> PpSourceMode { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for PpSourceMode {
#[inline]
fn eq(&self, other: &PpSourceMode) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq, #[automatically_derived]
impl ::core::fmt::Debug for PpSourceMode {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
PpSourceMode::Normal => "Normal",
PpSourceMode::Expanded => "Expanded",
PpSourceMode::ExpandedIdentified => "ExpandedIdentified",
PpSourceMode::ExpandedHygiene => "ExpandedHygiene",
})
}
}Debug)]
3196pub enum PpSourceMode {
3197 Normal,
3199 Expanded,
3201 ExpandedIdentified,
3203 ExpandedHygiene,
3205}
3206
3207#[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)]
3208pub enum PpHirMode {
3209 Normal,
3211 Identified,
3213 Typed,
3215}
3216
3217#[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)]
3218pub enum PpMode {
3220 Source(PpSourceMode),
3223 AstTree,
3225 AstTreeExpanded,
3227 Hir(PpHirMode),
3229 HirTree,
3231 ThirTree,
3233 ThirFlat,
3235 Mir,
3237 MirCFG,
3239 StableMir,
3241}
3242
3243impl PpMode {
3244 pub fn needs_ast_map(&self) -> bool {
3245 use PpMode::*;
3246 use PpSourceMode::*;
3247 match *self {
3248 Source(Normal) | AstTree => false,
3249
3250 Source(Expanded | ExpandedIdentified | ExpandedHygiene)
3251 | AstTreeExpanded
3252 | Hir(_)
3253 | HirTree
3254 | ThirTree
3255 | ThirFlat
3256 | Mir
3257 | MirCFG
3258 | StableMir => true,
3259 }
3260 }
3261
3262 pub fn needs_analysis(&self) -> bool {
3263 use PpMode::*;
3264 #[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)
3265 }
3266}
3267
3268#[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)]
3269pub enum WasiExecModel {
3270 Command,
3271 Reactor,
3272}
3273
3274pub(crate) mod dep_tracking {
3293 use std::collections::BTreeMap;
3294 use std::hash::Hash;
3295 use std::num::NonZero;
3296 use std::path::PathBuf;
3297
3298 use rustc_abi::Align;
3299 use rustc_ast::attr::version::RustcVersion;
3300 use rustc_data_structures::fx::FxIndexMap;
3301 use rustc_data_structures::stable_hash::StableHasher;
3302 use rustc_errors::LanguageIdentifier;
3303 use rustc_feature::UnstableFeatures;
3304 use rustc_hashes::Hash64;
3305 use rustc_hir::attrs::CollapseMacroDebuginfo;
3306 use rustc_span::edition::Edition;
3307 use rustc_span::{RealFileName, RemapPathScopeComponents};
3308 use rustc_target::spec::{
3309 CodeModel, FramePointer, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel,
3310 RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility, TargetTuple,
3311 TlsModel,
3312 };
3313
3314 use super::{
3315 AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CodegenRetagOptions,
3316 CoverageOptions, CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug,
3317 FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentMcount, InstrumentXRay,
3318 LinkerPluginLto, LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, Offload,
3319 OptLevel, OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, PointerAuthOption,
3320 Polonius, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath,
3321 SymbolManglingVersion, WasiExecModel,
3322 };
3323 use crate::lint;
3324 use crate::utils::NativeLib;
3325
3326 pub(crate) trait DepTrackingHash {
3327 fn hash(
3328 &self,
3329 hasher: &mut StableHasher,
3330 error_format: ErrorOutputType,
3331 for_crate_hash: bool,
3332 );
3333 }
3334
3335 macro_rules! impl_dep_tracking_hash_via_hash {
3336 ($($t:ty),+ $(,)?) => {$(
3337 impl DepTrackingHash for $t {
3338 fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType, _for_crate_hash: bool) {
3339 Hash::hash(self, hasher);
3340 }
3341 }
3342 )+};
3343 }
3344
3345 impl<T: DepTrackingHash> DepTrackingHash for Option<T> {
3346 fn hash(
3347 &self,
3348 hasher: &mut StableHasher,
3349 error_format: ErrorOutputType,
3350 for_crate_hash: bool,
3351 ) {
3352 match self {
3353 Some(x) => {
3354 Hash::hash(&1, hasher);
3355 DepTrackingHash::hash(x, hasher, error_format, for_crate_hash);
3356 }
3357 None => Hash::hash(&0, hasher),
3358 }
3359 }
3360 }
3361
3362 impl DepTrackingHash for PointerAuthOption {
fn hash(&self, hasher: &mut StableHasher, _: ErrorOutputType,
_for_crate_hash: bool) {
Hash::hash(self, hasher);
}
}impl_dep_tracking_hash_via_hash!(
3363 (),
3364 AnnotateMoves,
3365 AutoDiff,
3366 Offload,
3367 bool,
3368 usize,
3369 NonZero<usize>,
3370 u64,
3371 Hash64,
3372 String,
3373 PathBuf,
3374 lint::Level,
3375 WasiExecModel,
3376 u32,
3377 FramePointer,
3378 RelocModel,
3379 CodeModel,
3380 TlsModel,
3381 InstrumentCoverage,
3382 CoverageOptions,
3383 InstrumentMcount,
3384 InstrumentXRay,
3385 CrateType,
3386 MergeFunctions,
3387 OnBrokenPipe,
3388 PanicStrategy,
3389 RelroLevel,
3390 OptLevel,
3391 LtoCli,
3392 DebugInfo,
3393 DebugInfoCompression,
3394 MirStripDebugInfo,
3395 CollapseMacroDebuginfo,
3396 UnstableFeatures,
3397 NativeLib,
3398 SanitizerSet,
3399 CFGuard,
3400 CFProtection,
3401 TargetTuple,
3402 Edition,
3403 LinkerPluginLto,
3404 ResolveDocLinks,
3405 SplitDebuginfo,
3406 SplitDwarfKind,
3407 StackProtector,
3408 SwitchWithOptPath,
3409 SymbolManglingVersion,
3410 SymbolVisibility,
3411 RemapPathScopeComponents,
3412 SourceFileHashAlgorithm,
3413 OutFileName,
3414 OutputType,
3415 RealFileName,
3416 LocationDetail,
3417 FmtDebug,
3418 BranchProtection,
3419 LanguageIdentifier,
3420 NextSolverConfig,
3421 PatchableFunctionEntry,
3422 Polonius,
3423 InliningThreshold,
3424 FunctionReturn,
3425 Align,
3426 CodegenRetagOptions,
3427 RustcVersion,
3428 PointerAuthOption,
3429 );
3430
3431 impl<T1, T2> DepTrackingHash for (T1, T2)
3432 where
3433 T1: DepTrackingHash,
3434 T2: DepTrackingHash,
3435 {
3436 fn hash(
3437 &self,
3438 hasher: &mut StableHasher,
3439 error_format: ErrorOutputType,
3440 for_crate_hash: bool,
3441 ) {
3442 Hash::hash(&0, hasher);
3443 DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash);
3444 Hash::hash(&1, hasher);
3445 DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash);
3446 }
3447 }
3448
3449 impl<T1, T2, T3> DepTrackingHash for (T1, T2, T3)
3450 where
3451 T1: DepTrackingHash,
3452 T2: DepTrackingHash,
3453 T3: DepTrackingHash,
3454 {
3455 fn hash(
3456 &self,
3457 hasher: &mut StableHasher,
3458 error_format: ErrorOutputType,
3459 for_crate_hash: bool,
3460 ) {
3461 Hash::hash(&0, hasher);
3462 DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash);
3463 Hash::hash(&1, hasher);
3464 DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash);
3465 Hash::hash(&2, hasher);
3466 DepTrackingHash::hash(&self.2, hasher, error_format, for_crate_hash);
3467 }
3468 }
3469
3470 impl<T: DepTrackingHash> DepTrackingHash for Vec<T> {
3471 fn hash(
3472 &self,
3473 hasher: &mut StableHasher,
3474 error_format: ErrorOutputType,
3475 for_crate_hash: bool,
3476 ) {
3477 Hash::hash(&self.len(), hasher);
3478 for (index, elem) in self.iter().enumerate() {
3479 Hash::hash(&index, hasher);
3480 DepTrackingHash::hash(elem, hasher, error_format, for_crate_hash);
3481 }
3482 }
3483 }
3484
3485 impl<T: DepTrackingHash, V: DepTrackingHash> DepTrackingHash for FxIndexMap<T, V> {
3486 fn hash(
3487 &self,
3488 hasher: &mut StableHasher,
3489 error_format: ErrorOutputType,
3490 for_crate_hash: bool,
3491 ) {
3492 Hash::hash(&self.len(), hasher);
3493 for (key, value) in self.iter() {
3494 DepTrackingHash::hash(key, hasher, error_format, for_crate_hash);
3495 DepTrackingHash::hash(value, hasher, error_format, for_crate_hash);
3496 }
3497 }
3498 }
3499
3500 impl DepTrackingHash for OutputTypes {
3501 fn hash(
3502 &self,
3503 hasher: &mut StableHasher,
3504 error_format: ErrorOutputType,
3505 for_crate_hash: bool,
3506 ) {
3507 Hash::hash(&self.0.len(), hasher);
3508 for (key, val) in &self.0 {
3509 DepTrackingHash::hash(key, hasher, error_format, for_crate_hash);
3510 if !for_crate_hash {
3511 DepTrackingHash::hash(val, hasher, error_format, for_crate_hash);
3512 }
3513 }
3514 }
3515 }
3516
3517 pub(crate) fn stable_hash(
3519 sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>,
3520 hasher: &mut StableHasher,
3521 error_format: ErrorOutputType,
3522 for_crate_hash: bool,
3523 ) {
3524 for (key, sub_hash) in sub_hashes {
3525 Hash::hash(&key.len(), hasher);
3528 Hash::hash(key, hasher);
3529 sub_hash.hash(hasher, error_format, for_crate_hash);
3530 }
3531 }
3532}
3533
3534#[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)]
3536pub enum ProcMacroExecutionStrategy {
3537 SameThread,
3539
3540 CrossThread,
3542}
3543
3544#[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)]
3546pub enum DumpMonoStatsFormat {
3547 Markdown,
3549 Json,
3551}
3552
3553impl DumpMonoStatsFormat {
3554 pub fn extension(self) -> &'static str {
3555 match self {
3556 Self::Markdown => "md",
3557 Self::Json => "json",
3558 }
3559 }
3560}
3561
3562#[derive(#[automatically_derived]
impl ::core::clone::Clone for PatchableFunctionEntry {
#[inline]
fn clone(&self) -> PatchableFunctionEntry {
PatchableFunctionEntry {
prefix: ::core::clone::Clone::clone(&self.prefix),
entry: ::core::clone::Clone::clone(&self.entry),
section: ::core::clone::Clone::clone(&self.section),
}
}
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for PatchableFunctionEntry {
#[inline]
fn eq(&self, other: &PatchableFunctionEntry) -> bool {
self.prefix == other.prefix && self.entry == other.entry &&
self.section == other.section
}
}PartialEq, #[automatically_derived]
impl ::core::hash::Hash for PatchableFunctionEntry {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.prefix, state);
::core::hash::Hash::hash(&self.entry, state);
::core::hash::Hash::hash(&self.section, state)
}
}Hash, #[automatically_derived]
impl ::core::fmt::Debug for PatchableFunctionEntry {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field3_finish(f,
"PatchableFunctionEntry", "prefix", &self.prefix, "entry",
&self.entry, "section", &&self.section)
}
}Debug, #[automatically_derived]
impl ::core::default::Default for PatchableFunctionEntry {
#[inline]
fn default() -> PatchableFunctionEntry {
PatchableFunctionEntry {
prefix: ::core::default::Default::default(),
entry: ::core::default::Default::default(),
section: ::core::default::Default::default(),
}
}
}Default)]
3565pub struct PatchableFunctionEntry {
3566 prefix: u8,
3568 entry: u8,
3570 section: Option<String>,
3572}
3573
3574impl PatchableFunctionEntry {
3575 pub fn from_parts(
3576 total_nops: u8,
3577 prefix_nops: u8,
3578 section: Option<String>,
3579 ) -> Option<PatchableFunctionEntry> {
3580 if total_nops < prefix_nops {
3581 None
3582 } else if section.as_ref().map(|x| x.contains('\0') || x.is_empty()).unwrap_or(false) {
3584 None
3585 } else {
3586 Some(Self { prefix: prefix_nops, entry: total_nops - prefix_nops, section })
3587 }
3588 }
3589 pub fn prefix(&self) -> u8 {
3590 self.prefix
3591 }
3592 pub fn entry(&self) -> u8 {
3593 self.entry
3594 }
3595 pub fn section(&self) -> Option<&str> {
3596 self.section.as_ref().map(|x| x.as_str())
3597 }
3598}
3599
3600#[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)]
3603pub enum Polonius {
3604 #[default]
3606 Off,
3607
3608 Legacy,
3610
3611 Next,
3613}
3614
3615impl Polonius {
3616 pub fn is_legacy_enabled(&self) -> bool {
3618 #[allow(non_exhaustive_omitted_patterns)] match self {
Polonius::Legacy => true,
_ => false,
}matches!(self, Polonius::Legacy)
3619 }
3620
3621 pub fn is_next_enabled(&self) -> bool {
3623 #[allow(non_exhaustive_omitted_patterns)] match self {
Polonius::Next => true,
_ => false,
}matches!(self, Polonius::Next)
3624 }
3625}
3626
3627#[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)]
3628pub enum InliningThreshold {
3629 Always,
3630 Sometimes(usize),
3631 Never,
3632}
3633
3634impl Default for InliningThreshold {
3635 fn default() -> Self {
3636 Self::Sometimes(100)
3637 }
3638}
3639
3640#[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)]
3642pub enum FunctionReturn {
3643 #[default]
3645 Keep,
3646
3647 ThunkExtern,
3649}
3650
3651#[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)]
3654pub enum MirIncludeSpans {
3655 Off,
3656 On,
3657 #[default]
3660 Nll,
3661}
3662
3663impl MirIncludeSpans {
3664 pub fn is_enabled(self) -> bool {
3669 self == MirIncludeSpans::On
3670 }
3671}