diff options
Diffstat (limited to 'compiler/rustc_passes')
| -rw-r--r-- | compiler/rustc_passes/messages.ftl | 6 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/check_attr.rs | 44 | ||||
| -rw-r--r-- | compiler/rustc_passes/src/errors.rs | 5 |
3 files changed, 46 insertions, 9 deletions
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl index 8dec24feeba..bfe0d54e645 100644 --- a/compiler/rustc_passes/messages.ftl +++ b/compiler/rustc_passes/messages.ftl @@ -482,9 +482,9 @@ passes_naked_functions_asm_block = passes_naked_functions_asm_options = asm options unsupported in naked functions: {$unsupported_options} -passes_naked_functions_codegen_attribute = - cannot use additional code generation attributes with `#[naked]` - .label = this attribute is incompatible with `#[naked]` +passes_naked_functions_incompatible_attribute = + attribute incompatible with `#[naked]` + .label = the `{$attr}` attribute is incompatible with `#[naked]` .naked_attribute = function marked with `#[naked]` here passes_naked_functions_must_use_noreturn = diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 311c11a0388..ba0dbfbac12 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -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; diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index b6be096b43b..b195ba973ce 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -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)] |
