1use std::path::PathBuf;
2use std::sync::OnceLock;
3
4use rustc_data_structures::profiling::VerboseTimingGuard;
5use rustc_fs_util::try_canonicalize;
6use rustc_hir::attrs::NativeLibKind;
7use rustc_macros::{Decodable, Encodable, HashStable_Generic};
8
9use crate::session::Session;
10
11impl Session {
12 pub fn timer(&self, what: &'static str) -> VerboseTimingGuard<'_> {
13 self.prof.verbose_generic_activity(what)
14 }
15 pub fn time<R>(&self, what: &'static str, f: impl FnOnce() -> R) -> R {
17 self.prof.verbose_generic_activity(what).run(f)
18 }
19}
20
21#[derive(#[automatically_derived]
impl ::core::clone::Clone for NativeLib {
#[inline]
fn clone(&self) -> NativeLib {
NativeLib {
name: ::core::clone::Clone::clone(&self.name),
new_name: ::core::clone::Clone::clone(&self.new_name),
kind: ::core::clone::Clone::clone(&self.kind),
verbatim: ::core::clone::Clone::clone(&self.verbatim),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for NativeLib {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field4_finish(f, "NativeLib",
"name", &self.name, "new_name", &self.new_name, "kind",
&self.kind, "verbatim", &&self.verbatim)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for NativeLib {
#[inline]
fn eq(&self, other: &NativeLib) -> bool {
self.name == other.name && self.new_name == other.new_name &&
self.kind == other.kind && self.verbatim == other.verbatim
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for NativeLib {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<String>;
let _: ::core::cmp::AssertParamIsEq<Option<String>>;
let _: ::core::cmp::AssertParamIsEq<NativeLibKind>;
let _: ::core::cmp::AssertParamIsEq<Option<bool>>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for NativeLib {
#[inline]
fn partial_cmp(&self, other: &NativeLib)
-> ::core::option::Option<::core::cmp::Ordering> {
match ::core::cmp::PartialOrd::partial_cmp(&self.name, &other.name) {
::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
match ::core::cmp::PartialOrd::partial_cmp(&self.new_name,
&other.new_name) {
::core::option::Option::Some(::core::cmp::Ordering::Equal)
=>
match ::core::cmp::PartialOrd::partial_cmp(&self.kind,
&other.kind) {
::core::option::Option::Some(::core::cmp::Ordering::Equal)
=>
::core::cmp::PartialOrd::partial_cmp(&self.verbatim,
&other.verbatim),
cmp => cmp,
},
cmp => cmp,
},
cmp => cmp,
}
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for NativeLib {
#[inline]
fn cmp(&self, other: &NativeLib) -> ::core::cmp::Ordering {
match ::core::cmp::Ord::cmp(&self.name, &other.name) {
::core::cmp::Ordering::Equal =>
match ::core::cmp::Ord::cmp(&self.new_name, &other.new_name) {
::core::cmp::Ordering::Equal =>
match ::core::cmp::Ord::cmp(&self.kind, &other.kind) {
::core::cmp::Ordering::Equal =>
::core::cmp::Ord::cmp(&self.verbatim, &other.verbatim),
cmp => cmp,
},
cmp => cmp,
},
cmp => cmp,
}
}
}Ord, #[automatically_derived]
impl ::core::hash::Hash for NativeLib {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.name, state);
::core::hash::Hash::hash(&self.new_name, state);
::core::hash::Hash::hash(&self.kind, state);
::core::hash::Hash::hash(&self.verbatim, state)
}
}Hash, const _: () =
{
impl<__E: ::rustc_span::SpanEncoder> ::rustc_serialize::Encodable<__E>
for NativeLib {
fn encode(&self, __encoder: &mut __E) {
match *self {
NativeLib {
name: ref __binding_0,
new_name: ref __binding_1,
kind: ref __binding_2,
verbatim: ref __binding_3 } => {
::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);
}
}
}
}
};Encodable, const _: () =
{
impl<__D: ::rustc_span::SpanDecoder> ::rustc_serialize::Decodable<__D>
for NativeLib {
fn decode(__decoder: &mut __D) -> Self {
NativeLib {
name: ::rustc_serialize::Decodable::decode(__decoder),
new_name: ::rustc_serialize::Decodable::decode(__decoder),
kind: ::rustc_serialize::Decodable::decode(__decoder),
verbatim: ::rustc_serialize::Decodable::decode(__decoder),
}
}
}
};Decodable)]
22#[derive(const _: () =
{
impl<__CTX> ::rustc_data_structures::stable_hasher::HashStable<__CTX>
for NativeLib where __CTX: crate::HashStableContext {
#[inline]
fn hash_stable(&self, __hcx: &mut __CTX,
__hasher:
&mut ::rustc_data_structures::stable_hasher::StableHasher) {
match *self {
NativeLib {
name: ref __binding_0,
new_name: ref __binding_1,
kind: ref __binding_2,
verbatim: ref __binding_3 } => {
{ __binding_0.hash_stable(__hcx, __hasher); }
{ __binding_1.hash_stable(__hcx, __hasher); }
{ __binding_2.hash_stable(__hcx, __hasher); }
{ __binding_3.hash_stable(__hcx, __hasher); }
}
}
}
}
};HashStable_Generic)]
23pub struct NativeLib {
24 pub name: String,
25 pub new_name: Option<String>,
26 pub kind: NativeLibKind,
27 pub verbatim: Option<bool>,
28}
29
30impl NativeLib {
31 pub fn has_modifiers(&self) -> bool {
32 self.verbatim.is_some() || self.kind.has_modifiers()
33 }
34}
35
36#[derive(#[automatically_derived]
impl ::core::clone::Clone for CanonicalizedPath {
#[inline]
fn clone(&self) -> CanonicalizedPath {
CanonicalizedPath {
canonicalized: ::core::clone::Clone::clone(&self.canonicalized),
original: ::core::clone::Clone::clone(&self.original),
}
}
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for CanonicalizedPath {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"CanonicalizedPath", "canonicalized", &self.canonicalized,
"original", &&self.original)
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for CanonicalizedPath {
#[inline]
fn eq(&self, other: &CanonicalizedPath) -> bool {
self.canonicalized == other.canonicalized &&
self.original == other.original
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for CanonicalizedPath {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Option<PathBuf>>;
let _: ::core::cmp::AssertParamIsEq<PathBuf>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::PartialOrd for CanonicalizedPath {
#[inline]
fn partial_cmp(&self, other: &CanonicalizedPath)
-> ::core::option::Option<::core::cmp::Ordering> {
match ::core::cmp::PartialOrd::partial_cmp(&self.canonicalized,
&other.canonicalized) {
::core::option::Option::Some(::core::cmp::Ordering::Equal) =>
::core::cmp::PartialOrd::partial_cmp(&self.original,
&other.original),
cmp => cmp,
}
}
}PartialOrd, #[automatically_derived]
impl ::core::cmp::Ord for CanonicalizedPath {
#[inline]
fn cmp(&self, other: &CanonicalizedPath) -> ::core::cmp::Ordering {
match ::core::cmp::Ord::cmp(&self.canonicalized, &other.canonicalized)
{
::core::cmp::Ordering::Equal =>
::core::cmp::Ord::cmp(&self.original, &other.original),
cmp => cmp,
}
}
}Ord)]
38pub struct CanonicalizedPath {
39 canonicalized: Option<PathBuf>,
41 original: PathBuf,
42}
43
44impl CanonicalizedPath {
45 pub fn new(path: PathBuf) -> Self {
46 Self { canonicalized: try_canonicalize(&path).ok(), original: path }
47 }
48
49 pub fn canonicalized(&self) -> &PathBuf {
50 self.canonicalized.as_ref().unwrap_or(self.original())
51 }
52
53 pub fn original(&self) -> &PathBuf {
54 &self.original
55 }
56}
57
58pub fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
64 const ICE_REPORT_COMPILER_FLAGS: &[&str] = &["-Z", "-C", "--crate-type"];
65
66 const ICE_REPORT_COMPILER_FLAGS_EXCLUDE: &[&str] = &["metadata", "extra-filename"];
67
68 const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &[&str] = &["incremental"];
69
70 let mut args = std::env::args_os().map(|arg| arg.to_string_lossy().to_string());
71
72 let mut result = Vec::new();
73 let mut excluded_cargo_defaults = false;
74 while let Some(arg) = args.next() {
75 if let Some(a) = ICE_REPORT_COMPILER_FLAGS.iter().find(|a| arg.starts_with(*a)) {
76 let content = if arg.len() == a.len() {
77 match args.next() {
79 Some(arg) => arg,
80 None => continue,
81 }
82 } else if arg.get(a.len()..a.len() + 1) == Some("=") {
83 arg[a.len() + 1..].to_string()
85 } else {
86 arg[a.len()..].to_string()
88 };
89 let option = content.split_once('=').map(|s| s.0).unwrap_or(&content);
90 if ICE_REPORT_COMPILER_FLAGS_EXCLUDE.contains(&option) {
91 excluded_cargo_defaults = true;
92 } else {
93 result.push(a.to_string());
94 result.push(if ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE.contains(&option) {
95 ::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0}=[REDACTED]", option))
})format!("{option}=[REDACTED]")
96 } else {
97 content
98 });
99 }
100 }
101 }
102
103 if !result.is_empty() { Some((result, excluded_cargo_defaults)) } else { None }
104}
105
106pub fn was_invoked_from_cargo() -> bool {
111 static FROM_CARGO: OnceLock<bool> = OnceLock::new();
112
113 *FROM_CARGO.get_or_init(|| std::env::var_os("CARGO_CRATE_NAME").is_some())
119}