mirror of
https://github.com/rust-lang/rust.git
synced 2025-11-09 02:50:10 +00:00
`rustc_errors` depends on numerous crates, solely to implement its `IntoDiagArg` trait on types from those crates. Many crates depend on `rustc_errors`, and it's on the critical path. We can't swap things around to make all of those crates depend on `rustc_errors` instead, because `rustc_errors` would end up in dependency cycles. Instead, move `IntoDiagArg` into `rustc_error_messages`, which has far fewer dependencies, and then have most of these crates depend on `rustc_error_messages`. This allows `rustc_errors` to drop dependencies on several crates, including the large `rustc_target`. (This doesn't fully reduce dependency chains yet, as `rustc_errors` still depends on `rustc_hir` which depends on `rustc_target`. That will get fixed in a subsequent commit.)
56 lines
1.8 KiB
Rust
56 lines
1.8 KiB
Rust
use std::borrow::Cow;
|
|
use std::fmt::{self, Display};
|
|
use std::sync::OnceLock;
|
|
|
|
use rustc_error_messages::{DiagArgValue, IntoDiagArg};
|
|
use rustc_macros::{
|
|
Decodable, Encodable, HashStable_Generic, PrintAttribute, current_rustc_version,
|
|
};
|
|
|
|
use crate::attrs::PrintAttribute;
|
|
|
|
#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
#[derive(HashStable_Generic, PrintAttribute)]
|
|
pub struct RustcVersion {
|
|
pub major: u16,
|
|
pub minor: u16,
|
|
pub patch: u16,
|
|
}
|
|
|
|
impl RustcVersion {
|
|
pub const CURRENT: Self = current_rustc_version!();
|
|
pub fn current_overridable() -> Self {
|
|
*CURRENT_OVERRIDABLE.get_or_init(|| {
|
|
if let Ok(override_var) = std::env::var("RUSTC_OVERRIDE_VERSION_STRING")
|
|
&& let Some(override_) = Self::parse_str(&override_var)
|
|
{
|
|
override_
|
|
} else {
|
|
Self::CURRENT
|
|
}
|
|
})
|
|
}
|
|
fn parse_str(value: &str) -> Option<Self> {
|
|
// Ignore any suffixes such as "-dev" or "-nightly".
|
|
let mut components = value.split('-').next().unwrap().splitn(3, '.');
|
|
let major = components.next()?.parse().ok()?;
|
|
let minor = components.next()?.parse().ok()?;
|
|
let patch = components.next().unwrap_or("0").parse().ok()?;
|
|
Some(RustcVersion { major, minor, patch })
|
|
}
|
|
}
|
|
|
|
static CURRENT_OVERRIDABLE: OnceLock<RustcVersion> = OnceLock::new();
|
|
|
|
impl Display for RustcVersion {
|
|
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch)
|
|
}
|
|
}
|
|
|
|
impl IntoDiagArg for RustcVersion {
|
|
fn into_diag_arg(self, _: &mut Option<std::path::PathBuf>) -> DiagArgValue {
|
|
DiagArgValue::Str(Cow::Owned(self.to_string()))
|
|
}
|
|
}
|