Skip to content

Commit 38ab330

Browse files
committed
Introduce optional Rust version for diagnostics
1 parent 2a27f5c commit 38ab330

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

compiler/rustc_errors/src/diagnostic.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::marker::PhantomData;
55
use std::ops::{Deref, DerefMut};
66
use std::panic;
77
use std::path::PathBuf;
8+
use std::str::FromStr;
89
use std::thread::panicking;
910

1011
use rustc_data_structures::fx::FxIndexMap;
@@ -263,6 +264,38 @@ pub struct DiagInner {
263264
/// With `-Ztrack_diagnostics` enabled,
264265
/// we print where in rustc this error was emitted.
265266
pub(crate) emitted_at: DiagLocation,
267+
/// Used to avoid lints which would affect MSRV
268+
pub rust_version: Option<RustVersion>,
269+
}
270+
271+
#[derive(Copy, Clone, Debug, Encodable, Decodable, PartialEq, Eq, PartialOrd, Ord)]
272+
pub struct RustVersion {
273+
pub major: u64,
274+
pub minor: u64,
275+
pub patch: u64,
276+
}
277+
278+
impl FromStr for RustVersion {
279+
type Err = ();
280+
281+
fn from_str(s: &str) -> Result<Self, Self::Err> {
282+
fn get_number(s: &str) -> Result<(u64, &str), ()> {
283+
let end = s.chars().take_while(char::is_ascii_digit).count();
284+
if end == 0 {
285+
return Err(());
286+
}
287+
// `is_ascii_digit` ensures that this will be on a char boundary
288+
let (num, rest) = s.split_at(end);
289+
Ok((num.parse().map_err(|_| ())?, rest))
290+
}
291+
292+
let (major, s) = get_number(s)?;
293+
let s = s.strip_prefix(".").ok_or(())?;
294+
let (minor, s) = get_number(s)?;
295+
let s = s.strip_prefix(".").ok_or(())?;
296+
let (patch, _) = get_number(s)?;
297+
Ok(Self { major, minor, patch })
298+
}
266299
}
267300

268301
impl DiagInner {
@@ -287,6 +320,7 @@ impl DiagInner {
287320
is_lint: None,
288321
long_ty_path: None,
289322
emitted_at: DiagLocation::caller(),
323+
rust_version: None,
290324
}
291325
}
292326

@@ -377,6 +411,10 @@ impl DiagInner {
377411
self.args = std::mem::take(&mut self.reserved_args);
378412
}
379413

414+
pub fn set_rust_version(&mut self, version: RustVersion) {
415+
self.rust_version = Some(version);
416+
}
417+
380418
pub fn emitted_at_sub_diag(&self) -> Subdiag {
381419
let track = format!("-Ztrack-diagnostics: created at {}", self.emitted_at);
382420
Subdiag {
@@ -410,6 +448,7 @@ impl DiagInner {
410448
// omit self.sort_span
411449
&self.is_lint,
412450
// omit self.emitted_at
451+
// omit rust_version
413452
)
414453
}
415454
}

compiler/rustc_errors/src/lib.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub use codes::*;
4646
pub use decorate_diag::{BufferedEarlyLint, DecorateDiagCompat, LintBuffer};
4747
pub use diagnostic::{
4848
BugAbort, Diag, DiagArgMap, DiagInner, DiagStyledString, Diagnostic, EmissionGuarantee,
49-
FatalAbort, LintDiagnostic, LintDiagnosticBox, StringPart, Subdiag, Subdiagnostic,
49+
FatalAbort, LintDiagnostic, LintDiagnosticBox, RustVersion, StringPart, Subdiag, Subdiagnostic,
5050
};
5151
pub use diagnostic_impls::{
5252
DiagSymbolList, ElidedLifetimeInPathSubdiag, ExpectedLifetimeParameter,
@@ -633,6 +633,9 @@ struct DiagCtxtInner {
633633
/// The file where the ICE information is stored. This allows delayed_span_bug backtraces to be
634634
/// stored along side the main panic backtrace.
635635
ice_file: Option<PathBuf>,
636+
637+
/// Controlled by `CARGO_PKG_RUST_VERSION`; this allows avoiding emitting lints which would raise MSRV.
638+
msrv: Option<RustVersion>,
636639
}
637640

638641
/// A key denoting where from a diagnostic was stashed.
@@ -822,6 +825,7 @@ impl DiagCtxt {
822825
future_breakage_diagnostics,
823826
fulfilled_expectations,
824827
ice_file: _,
828+
msrv: _,
825829
} = inner.deref_mut();
826830

827831
// For the `Vec`s and `HashMap`s, we overwrite with an empty container to free the
@@ -1503,6 +1507,7 @@ impl DiagCtxtInner {
15031507
future_breakage_diagnostics: Vec::new(),
15041508
fulfilled_expectations: Default::default(),
15051509
ice_file: None,
1510+
msrv: std::env::var("CARGO_PKG_RUST_VERSION").ok().and_then(|vers| vers.parse().ok()),
15061511
}
15071512
}
15081513

@@ -1617,6 +1622,12 @@ impl DiagCtxtInner {
16171622
}
16181623
}
16191624

1625+
if let (Some(msrv), Some(rv)) = (self.msrv, diagnostic.rust_version)
1626+
&& rv > msrv
1627+
{
1628+
return None;
1629+
};
1630+
16201631
TRACK_DIAGNOSTIC(diagnostic, &mut |mut diagnostic| {
16211632
if let Some(code) = diagnostic.code {
16221633
self.emitted_diagnostic_codes.insert(code);

0 commit comments

Comments
 (0)