Skip to content

Commit 7d4a0f5

Browse files
committed
add lint preventing attr target regression
1 parent 7334161 commit 7d4a0f5

6 files changed

Lines changed: 48 additions & 3 deletions

File tree

compiler/rustc_ast_lowering/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
209209
tcx.features(),
210210
registered_tools,
211211
Late,
212+
tcx.dcx(),
212213
),
213214
delayed_lints: Vec::new(),
214215
}

compiler/rustc_attr_parsing/messages.ftl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,10 @@ attr_parsing_stability_outside_std = stability attributes may not be used outsid
211211
attr_parsing_suffixed_literal_in_attribute = suffixed literals are not allowed in attributes
212212
.help = instead of using a suffixed literal (`1u8`, `1.0f32`, etc.), use an unsuffixed version (`1`, `1.0`, etc.)
213213
214+
attr_parsing_target_regression = attribute parser for `#[{$attribute_symbol}]` uses `AllowedTargets::AllowListWarnRest` but does not specify `Allow` or `Error` for target: `{$target}`
215+
.help = this target is already emitting errs for all unparsed attrs so omitting it in `AllowListWarnRest` would mean a regression from emitting an error, to emitting a warn
216+
.note = this is an internal rustc lint
217+
214218
attr_parsing_unknown_version_literal =
215219
unknown version literal format, assuming it refers to a future version
216220

compiler/rustc_attr_parsing/src/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ use crate::session_diagnostics::{
9090
};
9191
use crate::target_checking::AllowedTargets;
9292

93-
type GroupType<S> = LazyLock<GroupTypeInner<S>>;
93+
pub(crate) type GroupType<S> = LazyLock<GroupTypeInner<S>>;
9494

9595
pub(super) struct GroupTypeInner<S: Stage> {
9696
pub(super) accepters: BTreeMap<&'static [Symbol], Vec<GroupTypeInnerAccept<S>>>,

compiler/rustc_attr_parsing/src/interface.rs

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ use rustc_session::Session;
1212
use rustc_session::lint::BuiltinLintDiag;
1313
use rustc_span::{DUMMY_SP, Span, Symbol, sym};
1414

15-
use crate::context::{AcceptContext, FinalizeContext, SharedContext, Stage};
15+
use crate::context::{AcceptContext, FinalizeContext, GroupType, SharedContext, Stage};
1616
use crate::early_parsed::{EARLY_PARSED_ATTRIBUTES, EarlyParsedState};
1717
use crate::parser::{ArgParser, PathParser, RefPathParser};
18-
use crate::session_diagnostics::ParsedDescription;
18+
use crate::session_diagnostics::{AttributeTargetRegression, ParsedDescription};
19+
use crate::target_checking::AllowedTargets;
1920
use crate::{Early, Late, OmitDoc, ShouldEmit};
2021

2122
/// Context created once, for example as part of the ast lowering
@@ -237,7 +238,9 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
237238
features: &'sess Features,
238239
tools: Vec<Symbol>,
239240
stage: S,
241+
dcx: DiagCtxtHandle<'_>,
240242
) -> Self {
243+
Self::check_allowed_attrs(S::parsers(), dcx);
241244
Self { features: Some(features), tools, parse_only: None, sess, stage }
242245
}
243246

@@ -486,4 +489,31 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
486489
}
487490
}
488491
}
492+
493+
fn check_allowed_attrs(parsers: &'static GroupType<S>, dcx: DiagCtxtHandle<'_>) {
494+
use crate::target_checking::Policy::{Allow, Error, Warn};
495+
let targets = [Target::Param];
496+
for (syms, accepters) in &parsers.accepters {
497+
for accept in accepters {
498+
let AllowedTargets::AllowListWarnRest(allow_list) = accept.allowed_targets else {
499+
continue;
500+
};
501+
502+
let missing_targets = targets.into_iter().flat_map(|target| {
503+
(!allow_list.iter().any(|policy| {
504+
[Allow(target), Warn(target), Error(target)].contains(policy)
505+
}))
506+
.then_some(target)
507+
});
508+
for target in missing_targets {
509+
for sym in *syms {
510+
dcx.emit_warn(AttributeTargetRegression {
511+
attribute_symbol: *sym,
512+
target: target.name(),
513+
});
514+
}
515+
}
516+
}
517+
}
518+
}
489519
}

compiler/rustc_attr_parsing/src/session_diagnostics.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,3 +946,12 @@ pub(crate) struct UnsupportedInstructionSet<'a> {
946946
pub instruction_set: Symbol,
947947
pub current_target: &'a TargetTuple,
948948
}
949+
950+
#[derive(Diagnostic)]
951+
#[diag(attr_parsing_target_regression)]
952+
#[help]
953+
#[note]
954+
pub(crate) struct AttributeTargetRegression {
955+
pub attribute_symbol: Symbol,
956+
pub target: &'static str,
957+
}

compiler/rustc_resolve/src/def_collector.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
144144
self.resolver.tcx.features(),
145145
Vec::new(),
146146
Early { emit_errors: ShouldEmit::Nothing },
147+
self.resolver.dcx(),
147148
);
148149
let attrs = parser.parse_attribute_list(
149150
&i.attrs,

0 commit comments

Comments
 (0)