Skip to content

Commit 9d862dd

Browse files
committed
Auto merge of #157948 - jhpratt:rollup-2ojt35M, r=jhpratt
Rollup of 6 pull requests Successful merges: - #157707 (Introduce `-Z lint-rust-version`) - #157748 (rustc_public: make sure hidden fields have their accessors) - #157831 (test `carryless_mul` codegen) - #157879 (bootstrap: fix inverted success check in PowerShell download fallback) - #157933 (Use constant for detecting thin pointer formatting) - #157934 (update AttributeTemplate docs)
2 parents 01dfd79 + cdeae29 commit 9d862dd

18 files changed

Lines changed: 260 additions & 19 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4298,6 +4298,7 @@ dependencies = [
42984298
name = "rustc_lint_defs"
42994299
version = "0.0.0"
43004300
dependencies = [
4301+
"rustc_ast",
43014302
"rustc_data_structures",
43024303
"rustc_error_messages",
43034304
"rustc_hir_id",

compiler/rustc_ast/src/attr/version.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,24 @@ impl RustcVersion {
2424
}
2525
})
2626
}
27+
28+
/// Parse a [`RustcVersion`] with an optional patch version, ignoring suffixes such as `-dev` or `-nightly`.
2729
fn parse_str(value: &str) -> Option<Self> {
28-
// Ignore any suffixes such as "-dev" or "-nightly".
2930
let mut components = value.split('-').next().unwrap().splitn(3, '.');
3031
let major = components.next()?.parse().ok()?;
3132
let minor = components.next()?.parse().ok()?;
3233
let patch = components.next().unwrap_or("0").parse().ok()?;
3334
Some(RustcVersion { major, minor, patch })
3435
}
36+
37+
/// Parse a [`RustcVersion`] which is exactly `<major>.<minor>.<patch>`, with no suffix.
38+
pub fn parse_str_strict(value: &str) -> Option<Self> {
39+
let mut components = value.splitn(3, '.');
40+
let major = components.next()?.parse().ok()?;
41+
let minor = components.next()?.parse().ok()?;
42+
let patch = components.next()?.parse().ok()?;
43+
Some(RustcVersion { major, minor, patch })
44+
}
3545
}
3646

3747
static CURRENT_OVERRIDABLE: OnceLock<RustcVersion> = OnceLock::new();

compiler/rustc_attr_parsing/src/template.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ use rustc_ast::ast::Safety;
22
use rustc_hir::AttrStyle;
33
use rustc_span::Symbol;
44

5-
/// A template that the attribute input must match.
5+
/// A template to suggest the correct syntax of an attribute.
6+
///
7+
/// This is not used to *check* attributes. The attribute's parser is responsible for that.
68
/// Only top-level shape (`#[attr]` vs `#[attr(...)]` vs `#[attr = ...]`) is considered now.
79
#[derive(Clone, Copy, Default)]
810
pub struct AttributeTemplate {

compiler/rustc_errors/src/diagnostic.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::panic;
77
use std::path::PathBuf;
88
use std::thread::panicking;
99

10+
use rustc_ast::attr::version::RustcVersion;
1011
use rustc_data_structures::sync::{DynSend, DynSync};
1112
use rustc_error_messages::{DiagArgMap, DiagArgName, DiagArgValue, IntoDiagArg};
1213
use rustc_lint_defs::{Applicability, LintExpectationId};
@@ -175,6 +176,8 @@ pub struct IsLint {
175176
pub(crate) name: String,
176177
/// Indicates whether this lint should show up in cargo's future breakage report.
177178
has_future_breakage: bool,
179+
/// Indicates the minimum rust version this lint applies to
180+
rust_version: Option<RustcVersion>,
178181
}
179182

180183
#[derive(Debug, PartialEq, Eq)]
@@ -308,6 +311,11 @@ impl DiagInner {
308311
matches!(self.is_lint, Some(IsLint { has_future_breakage: true, .. }))
309312
}
310313

314+
/// Indicates the minimum rust version this lint applies to.
315+
pub(crate) fn rust_version(&self) -> Option<RustcVersion> {
316+
self.is_lint.as_ref().and_then(|is| is.rust_version)
317+
}
318+
311319
pub(crate) fn is_force_warn(&self) -> bool {
312320
match self.level {
313321
Level::ForceWarning => {
@@ -1152,8 +1160,13 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
11521160
self
11531161
} }
11541162

1155-
pub fn is_lint(&mut self, name: String, has_future_breakage: bool) -> &mut Self {
1156-
self.is_lint = Some(IsLint { name, has_future_breakage });
1163+
pub fn is_lint(
1164+
&mut self,
1165+
name: String,
1166+
has_future_breakage: bool,
1167+
rust_version: Option<RustcVersion>,
1168+
) -> &mut Self {
1169+
self.is_lint = Some(IsLint { name, has_future_breakage, rust_version });
11571170
self
11581171
}
11591172

compiler/rustc_errors/src/lib.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub use diagnostic_impls::{
4646
};
4747
pub use emitter::ColorConfig;
4848
use emitter::{DynEmitter, Emitter};
49+
use rustc_ast::attr::version::RustcVersion;
4950
use rustc_data_structures::AtomicRef;
5051
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
5152
use rustc_data_structures::stable_hash::StableHasher;
@@ -365,6 +366,9 @@ struct DiagCtxtInner {
365366
/// The file where the ICE information is stored. This allows delayed_span_bug backtraces to be
366367
/// stored along side the main panic backtrace.
367368
ice_file: Option<PathBuf>,
369+
370+
/// Controlled by `-Z lint-rust-version`; this allows avoiding emitting lints which would raise MSRV.
371+
msrv: Option<RustcVersion>,
368372
}
369373

370374
/// A key denoting where from a diagnostic was stashed.
@@ -479,6 +483,11 @@ impl DiagCtxt {
479483
self
480484
}
481485

486+
pub fn with_msrv(mut self, msrv: RustcVersion) -> Self {
487+
self.inner.get_mut().msrv = Some(msrv);
488+
self
489+
}
490+
482491
pub fn new(emitter: Box<DynEmitter>) -> Self {
483492
Self { inner: Lock::new(DiagCtxtInner::new(emitter)) }
484493
}
@@ -526,6 +535,7 @@ impl DiagCtxt {
526535
future_breakage_diagnostics,
527536
fulfilled_expectations,
528537
ice_file: _,
538+
msrv: _,
529539
} = inner.deref_mut();
530540

531541
// For the `Vec`s and `HashMap`s, we overwrite with an empty container to free the
@@ -1193,6 +1203,7 @@ impl DiagCtxtInner {
11931203
future_breakage_diagnostics: Vec::new(),
11941204
fulfilled_expectations: Default::default(),
11951205
ice_file: None,
1206+
msrv: None,
11961207
}
11971208
}
11981209

@@ -1307,6 +1318,12 @@ impl DiagCtxtInner {
13071318
}
13081319
}
13091320

1321+
if let (Some(msrv), Some(diag_msrv)) = (self.msrv, diagnostic.rust_version())
1322+
&& diag_msrv > msrv
1323+
{
1324+
return None;
1325+
}
1326+
13101327
TRACK_DIAGNOSTIC(diagnostic, &mut |mut diagnostic| {
13111328
if let Some(code) = diagnostic.code {
13121329
self.emitted_diagnostic_codes.insert(code);

compiler/rustc_lint_defs/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ edition = "2024"
55

66
[dependencies]
77
# tidy-alphabetical-start
8+
rustc_ast = { path = "../rustc_ast" }
89
rustc_data_structures = { path = "../rustc_data_structures" }
910
rustc_error_messages = { path = "../rustc_error_messages" }
1011
rustc_hir_id = { path = "../rustc_hir_id" }

compiler/rustc_lint_defs/src/lib.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::borrow::Cow;
22
use std::fmt::Display;
33

4+
use rustc_ast::attr::version::RustcVersion;
45
use rustc_data_structures::fx::FxIndexSet;
56
use rustc_data_structures::stable_hash::{StableCompare, StableHash, StableHashCtxt, StableHasher};
67
use rustc_error_messages::{DiagArgValue, IntoDiagArg};
@@ -305,6 +306,9 @@ pub struct Lint {
305306

306307
/// `true` if this lint is unaffected by `-D warnings`
307308
pub ignore_deny_warnings: bool,
309+
310+
/// Used to avoid lints which would affect MSRV
311+
pub rust_version: Option<RustcVersion>,
308312
}
309313

310314
/// Extra information for a future incompatibility lint.
@@ -521,7 +525,40 @@ impl Lint {
521525
crate_level_only: false,
522526
eval_always: false,
523527
ignore_deny_warnings: false,
528+
rust_version: None,
529+
}
530+
}
531+
532+
// FIXME(const-hack): This is used so that `declare_lint` can declare an MSRV statically.
533+
// `RustcVersion::parse_str_strict` should ideally be used instead.
534+
pub const fn parse_rust_version(version: &str) -> RustcVersion {
535+
const fn parse_part(input: &mut &[u8]) -> u16 {
536+
let mut val = 0;
537+
let mut idx = 0;
538+
while idx < input.len() {
539+
let v = input[idx];
540+
match v {
541+
b'0'..=b'9' => {
542+
val = val * 10 + (v - b'0') as u16;
543+
}
544+
b'.' => {
545+
idx += 1;
546+
break;
547+
}
548+
_ => panic!("invalid character in version"),
549+
}
550+
idx += 1;
551+
}
552+
*input = input.split_at(idx).1;
553+
val
524554
}
555+
556+
let mut bytes = version.as_bytes();
557+
let major = parse_part(&mut bytes);
558+
let minor = parse_part(&mut bytes);
559+
let patch = parse_part(&mut bytes);
560+
assert!(bytes.is_empty());
561+
RustcVersion { major, minor, patch }
525562
}
526563

527564
/// Gets the lint's name, with ASCII letters converted to lowercase.
@@ -671,6 +708,7 @@ macro_rules! declare_lint {
671708
$($field:ident : $val:expr),* $(,)*
672709
}; )?
673710
$(@edition $lint_edition:ident => $edition_level:ident;)?
711+
$(@msrv = $msrv:literal;)?
674712
$($v:ident),*) => (
675713
$(#[$attr])*
676714
$vis static $NAME: &$crate::Lint = &$crate::Lint {
@@ -687,6 +725,7 @@ macro_rules! declare_lint {
687725
}),)?
688726
$(edition_lint_opts: Some(($crate::Edition::$lint_edition, $crate::$edition_level)),)?
689727
$(eval_always: $eval_always,)?
728+
$(rust_version: Some($crate::Lint::parse_rust_version($msrv)),)?
690729
..$crate::Lint::default_fields_for_macro()
691730
};
692731
);

compiler/rustc_middle/src/lint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ pub fn emit_lint_base<'a, D: Diagnostic<'a, ()> + 'a>(
514514
err.disable_suggestions();
515515
}
516516

517-
err.is_lint(lint.name_lower(), has_future_breakage);
517+
err.is_lint(lint.name_lower(), has_future_breakage, lint.rust_version);
518518
// Lint diagnostics that are covered by the expect level will not be emitted outside
519519
// the compiler. It is therefore not necessary to add any information for the user.
520520
// This will therefore directly call the decorate function which will in turn emit

compiler/rustc_public/src/ty.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,16 @@ impl VariantDef {
895895
pub fn fields(&self) -> Vec<FieldDef> {
896896
with(|cx| cx.variant_fields(*self))
897897
}
898+
899+
/// Returns the variant index.
900+
pub fn idx(&self) -> VariantIdx {
901+
self.idx
902+
}
903+
904+
/// Returns the `AdtDef` which this variant comes from.
905+
pub fn adt_def(&self) -> AdtDef {
906+
self.adt_def
907+
}
898908
}
899909

900910
crate_def_with_ty! {

compiler/rustc_session/src/config.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3059,6 +3059,7 @@ pub(crate) mod dep_tracking {
30593059
use std::path::PathBuf;
30603060

30613061
use rustc_abi::Align;
3062+
use rustc_ast::attr::version::RustcVersion;
30623063
use rustc_data_structures::fx::FxIndexMap;
30633064
use rustc_data_structures::stable_hash::StableHasher;
30643065
use rustc_errors::LanguageIdentifier;
@@ -3184,7 +3185,8 @@ pub(crate) mod dep_tracking {
31843185
InliningThreshold,
31853186
FunctionReturn,
31863187
Align,
3187-
CodegenRetagOptions
3188+
CodegenRetagOptions,
3189+
RustcVersion,
31883190
);
31893191

31903192
impl<T1, T2> DepTrackingHash for (T1, T2)

0 commit comments

Comments
 (0)