switch to an allowlist approach
- merge error codes - use attribute name that is incompatible in error message - add test for conditional incompatible attribute - add `linkage` to the allowlist
This commit is contained in:
parent
4d082b77af
commit
c6a166bac2
16 changed files with 185 additions and 65 deletions
|
@ -418,17 +418,53 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
|
|||
target: Target,
|
||||
attrs: &[Attribute],
|
||||
) -> bool {
|
||||
const FORBIDDEN: [rustc_span::Symbol; 3] =
|
||||
[sym::track_caller, sym::inline, sym::target_feature];
|
||||
// many attributes don't make sense in combination with #[naked].
|
||||
// Notable attributes that are incompatible with `#[naked]` are:
|
||||
//
|
||||
// * `#[inline]`
|
||||
// * `#[track_caller]`
|
||||
// * `#[target_feature]`
|
||||
// * `#[test]`, `#[ignore]`, `#[should_panic]`
|
||||
//
|
||||
// NOTE: when making changes to this list, check that `error_codes/E0736.md` remains accurate
|
||||
const ALLOW_LIST: &[rustc_span::Symbol] = &[
|
||||
// conditional compilation
|
||||
sym::cfg,
|
||||
sym::cfg_attr,
|
||||
// testing (allowed here so better errors can be generated in `rustc_builtin_macros::test`)
|
||||
sym::test,
|
||||
sym::ignore,
|
||||
sym::should_panic,
|
||||
sym::bench,
|
||||
// diagnostics
|
||||
sym::allow,
|
||||
sym::warn,
|
||||
sym::deny,
|
||||
sym::forbid,
|
||||
sym::deprecated,
|
||||
sym::must_use,
|
||||
// abi, linking and FFI
|
||||
sym::export_name,
|
||||
sym::link_section,
|
||||
sym::linkage,
|
||||
sym::no_mangle,
|
||||
sym::naked,
|
||||
sym::instruction_set,
|
||||
// code generation
|
||||
sym::cold,
|
||||
// documentation
|
||||
sym::doc,
|
||||
];
|
||||
|
||||
match target {
|
||||
Target::Fn
|
||||
| Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => {
|
||||
for other_attr in attrs {
|
||||
if FORBIDDEN.into_iter().any(|name| other_attr.has_name(name)) {
|
||||
self.dcx().emit_err(errors::NakedFunctionCodegenAttribute {
|
||||
if !ALLOW_LIST.iter().any(|name| other_attr.has_name(*name)) {
|
||||
self.dcx().emit_err(errors::NakedFunctionIncompatibleAttribute {
|
||||
span: other_attr.span,
|
||||
naked_span: attr.span,
|
||||
attr: other_attr.name_or_empty(),
|
||||
});
|
||||
|
||||
return false;
|
||||
|
|
|
@ -1183,13 +1183,14 @@ pub struct NakedFunctionsMustUseNoreturn {
|
|||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(passes_naked_functions_codegen_attribute, code = E0736)]
|
||||
pub struct NakedFunctionCodegenAttribute {
|
||||
#[diag(passes_naked_functions_incompatible_attribute, code = E0736)]
|
||||
pub struct NakedFunctionIncompatibleAttribute {
|
||||
#[primary_span]
|
||||
#[label]
|
||||
pub span: Span,
|
||||
#[label(passes_naked_attribute)]
|
||||
pub naked_span: Span,
|
||||
pub attr: Symbol,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue