diff --git a/compiler/rustc_builtin_macros/src/test.rs b/compiler/rustc_builtin_macros/src/test.rs index 9459bb7047f5c..fbe747c3bd2ed 100644 --- a/compiler/rustc_builtin_macros/src/test.rs +++ b/compiler/rustc_builtin_macros/src/test.rs @@ -6,6 +6,7 @@ use rustc_ast as ast; use rustc_ast::attr; use rustc_ast::ptr::P; use rustc_ast_pretty::pprust; +use rustc_errors::struct_span_err; use rustc_expand::base::*; use rustc_session::Session; use rustc_span::symbol::{sym, Ident, Symbol}; @@ -110,6 +111,17 @@ pub fn expand_test_or_bench( return vec![Annotatable::Item(item)]; } + if let Some(attr) = cx.sess.find_by_name(&item.attrs, sym::naked) { + struct_span_err!( + cx.sess, + attr.span, + E0788, + "cannot use testing attributes with `#[naked]`", + ) + .emit(); + return vec![Annotatable::Item(item)]; + } + // has_*_signature will report any errors in the type so compilation // will fail. We shouldn't try to expand in this case because the errors // would be spurious. diff --git a/compiler/rustc_error_codes/src/error_codes.rs b/compiler/rustc_error_codes/src/error_codes.rs index c401f65eddaed..180b8989a9228 100644 --- a/compiler/rustc_error_codes/src/error_codes.rs +++ b/compiler/rustc_error_codes/src/error_codes.rs @@ -488,6 +488,7 @@ E0784: include_str!("./error_codes/E0784.md"), E0785: include_str!("./error_codes/E0785.md"), E0786: include_str!("./error_codes/E0786.md"), E0787: include_str!("./error_codes/E0787.md"), +E0788: include_str!("./error_codes/E0788.md"), ; // E0006, // merged with E0005 // E0008, // cannot bind by-move into a pattern guard diff --git a/compiler/rustc_error_codes/src/error_codes/E0736.md b/compiler/rustc_error_codes/src/error_codes/E0736.md index 0f3d41ba66dc4..5700cb8b252a6 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0736.md +++ b/compiler/rustc_error_codes/src/error_codes/E0736.md @@ -1,14 +1,24 @@ -`#[track_caller]` and `#[naked]` cannot both be applied to the same function. +Functions marked with the `#[naked]` attribute are restricted in what other +code generation attributes they may be marked with. + +The following code generation attributes are incompatible with `#[naked]`: + + * `#[inline]` + * `#[track_caller]` + * `#[target_feature]` Erroneous code example: ```compile_fail,E0736 +#[inline] #[naked] -#[track_caller] fn foo() {} ``` -This is primarily due to ABI incompatibilities between the two attributes. -See [RFC 2091] for details on this and other limitations. +These incompatibilities are due to the fact that naked functions impose +deliberately strict restrictions regarding the code that the compiler is +allowed to produce for this function. + +See [the reference page for codegen attributes] for more information. -[RFC 2091]: https://github.com/rust-lang/rfcs/blob/master/text/2091-inline-semantic.md +[the reference page for codegen attributes]: https://doc.rust-lang.org/reference/attributes/codegen.html diff --git a/compiler/rustc_error_codes/src/error_codes/E0739.md b/compiler/rustc_error_codes/src/error_codes/E0739.md index 8d9039bef93f6..caecceb638963 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0739.md +++ b/compiler/rustc_error_codes/src/error_codes/E0739.md @@ -1,4 +1,4 @@ -`#[track_caller]` can not be applied on struct. +`#[track_caller]` must be applied to a function. Erroneous code example: diff --git a/compiler/rustc_error_codes/src/error_codes/E0788.md b/compiler/rustc_error_codes/src/error_codes/E0788.md new file mode 100644 index 0000000000000..4eb96cff95908 --- /dev/null +++ b/compiler/rustc_error_codes/src/error_codes/E0788.md @@ -0,0 +1,14 @@ +Testing attributes cannot be applied to functions marked with `#[naked]`. + +Erroneous code example: + +```ignore (requires test runner) +#[test] +#[should_panic] +#[naked] +fn foo() {} +``` + +See [the reference page for codegen attributes] for more information. + +[the reference page for codegen attributes]: https://doc.rust-lang.org/reference/attributes/codegen.html diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index f4eba25475eee..304f32e7ad34f 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -3036,6 +3036,7 @@ declare_lint_pass! { UNINHABITED_STATIC, FUNCTION_ITEM_REFERENCES, USELESS_DEPRECATED, + UNDEFINED_NAKED_FUNCTION_ABI, MISSING_ABI, INVALID_DOC_ATTRIBUTES, SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index ca511f7b814be..41fda6ce597ad 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -80,9 +80,7 @@ impl CheckAttrVisitor<'_> { self.check_rustc_must_implement_one_of(attr, span, target) } sym::target_feature => self.check_target_feature(hir_id, attr, span, target), - sym::track_caller => { - self.check_track_caller(hir_id, attr.span, attrs, span, target) - } + sym::track_caller => self.check_track_caller(hir_id, attr, span, target), sym::doc => self.check_doc_attrs( attr, hir_id, @@ -90,41 +88,41 @@ impl CheckAttrVisitor<'_> { &mut specified_inline, &mut doc_aliases, ), - sym::no_link => self.check_no_link(hir_id, &attr, span, target), - sym::export_name => self.check_export_name(hir_id, &attr, span, target), + sym::no_link => self.check_no_link(hir_id, attr, span, target), + sym::export_name => self.check_export_name(hir_id, attr, span, target), sym::rustc_layout_scalar_valid_range_start | sym::rustc_layout_scalar_valid_range_end => { - self.check_rustc_layout_scalar_valid_range(&attr, span, target) + self.check_rustc_layout_scalar_valid_range(attr, span, target) } sym::allow_internal_unstable => { - self.check_allow_internal_unstable(hir_id, &attr, span, target, &attrs) + self.check_allow_internal_unstable(hir_id, attr, span, target, attrs) } sym::rustc_allow_const_fn_unstable => { - self.check_rustc_allow_const_fn_unstable(hir_id, &attr, span, target) + self.check_rustc_allow_const_fn_unstable(hir_id, attr, span, target) } - sym::naked => self.check_naked(hir_id, attr, span, target), + sym::naked => self.check_naked(hir_id, attr, span, target, attrs), sym::rustc_legacy_const_generics => { - self.check_rustc_legacy_const_generics(&attr, span, target, item) + self.check_rustc_legacy_const_generics(attr, span, target, item) } sym::rustc_lint_query_instability => { - self.check_rustc_lint_query_instability(&attr, span, target) + self.check_rustc_lint_query_instability(attr, span, target) } sym::rustc_clean | sym::rustc_dirty | sym::rustc_if_this_changed - | sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr), + | sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(attr), sym::cmse_nonsecure_entry => self.check_cmse_nonsecure_entry(attr, span, target), sym::default_method_body_is_const => { self.check_default_method_body_is_const(attr, span, target) } - sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target), - sym::must_use => self.check_must_use(hir_id, &attr, span, target), - sym::rustc_pass_by_value => self.check_pass_by_value(&attr, span, target), + sym::must_not_suspend => self.check_must_not_suspend(attr, span, target), + sym::must_use => self.check_must_use(hir_id, attr, span, target), + sym::rustc_pass_by_value => self.check_pass_by_value(attr, span, target), sym::rustc_const_unstable | sym::rustc_const_stable | sym::unstable | sym::stable - | sym::rustc_promotable => self.check_stability_promotable(&attr, span, target), + | sym::rustc_promotable => self.check_stability_promotable(attr, span, target), _ => true, }; is_valid &= attr_is_valid; @@ -338,12 +336,35 @@ impl CheckAttrVisitor<'_> { } /// Checks if `#[naked]` is applied to a function definition. - fn check_naked(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) -> bool { + fn check_naked( + &self, + hir_id: HirId, + attr: &Attribute, + span: Span, + target: Target, + attrs: &[Attribute], + ) -> bool { + for any_attr in attrs { + if any_attr.has_name(sym::track_caller) + || any_attr.has_name(sym::inline) + || any_attr.has_name(sym::target_feature) + { + struct_span_err!( + self.tcx.sess, + any_attr.span, + E0736, + "cannot use additional code generation attributes with `#[naked]`", + ) + .emit(); + return false; + } + } + match target { Target::Fn | Target::Method(MethodKind::Trait { body: true } | MethodKind::Inherent) => true, // FIXME(#80564): We permit struct fields, match arms and macro defs to have an - // `#[allow_internal_unstable]` attribute with just a lint, because we previously + // `#[naked]` attribute with just a lint, because we previously // erroneously allowed it and some crates used it accidentally, to to be compatible // with crates depending on them, we can't throw an error here. Target::Field | Target::Arm | Target::MacroDef => { @@ -383,41 +404,28 @@ impl CheckAttrVisitor<'_> { } } - /// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid. + /// Checks if a `#[track_caller]` is applied to a function. Returns `true` if valid. fn check_track_caller( &self, hir_id: HirId, - attr_span: Span, - attrs: &[Attribute], + attr: &Attribute, span: Span, target: Target, ) -> bool { match target { - _ if attrs.iter().any(|attr| attr.has_name(sym::naked)) => { - struct_span_err!( - self.tcx.sess, - attr_span, - E0736, - "cannot use `#[track_caller]` with `#[naked]`", - ) - .emit(); - false - } Target::Fn | Target::Method(..) | Target::ForeignFn | Target::Closure => true, // FIXME(#80564): We permit struct fields, match arms and macro defs to have an // `#[track_caller]` attribute with just a lint, because we previously // erroneously allowed it and some crates used it accidentally, to to be compatible // with crates depending on them, we can't throw an error here. Target::Field | Target::Arm | Target::MacroDef => { - for attr in attrs { - self.inline_attr_str_error_with_macro_def(hir_id, attr, "track_caller"); - } + self.inline_attr_str_error_with_macro_def(hir_id, attr, "track_caller"); true } _ => { struct_span_err!( self.tcx.sess, - attr_span, + attr.span, E0739, "attribute should be applied to function" ) @@ -1210,8 +1218,8 @@ impl CheckAttrVisitor<'_> { self.inline_attr_str_error_with_macro_def(hir_id, attr, "link_name"); } _ => { - // FIXME: #[cold] was previously allowed on non-functions/statics and some crates - // used this, so only emit a warning. + // FIXME: #[link_name] was previously allowed on non-functions/statics and + // some crates used this, so only emit a warning. self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| { let mut diag = lint.build("attribute should be applied to a foreign function or static"); @@ -1796,7 +1804,7 @@ impl CheckAttrVisitor<'_> { } } - /// Outputs an error for `#[allow_internal_unstable]` which can only be applied to macros. + /// Outputs an error for `#[allow_const_fn_unstable]` which can only be applied to macros. /// (Allows proc_macro functions) fn check_rustc_allow_const_fn_unstable( &self, @@ -1812,11 +1820,11 @@ impl CheckAttrVisitor<'_> { true } // FIXME(#80564): We permit struct fields and match arms to have an - // `#[allow_internal_unstable]` attribute with just a lint, because we previously + // `#[allow_const_fn_unstable]` attribute with just a lint, because we previously // erroneously allowed it and some crates used it accidentally, to to be compatible // with crates depending on them, we can't throw an error here. Target::Field | Target::Arm | Target::MacroDef => { - self.inline_attr_str_error_with_macro_def(hir_id, attr, "allow_internal_unstable"); + self.inline_attr_str_error_with_macro_def(hir_id, attr, "allow_const_fn_unstable"); true } _ => { diff --git a/compiler/rustc_passes/src/naked_functions.rs b/compiler/rustc_passes/src/naked_functions.rs index 00a93ccc9aa09..676f7defac94a 100644 --- a/compiler/rustc_passes/src/naked_functions.rs +++ b/compiler/rustc_passes/src/naked_functions.rs @@ -1,6 +1,6 @@ //! Checks validity of naked functions. -use rustc_ast::{Attribute, InlineAsmOptions}; +use rustc_ast::InlineAsmOptions; use rustc_errors::struct_span_err; use rustc_hir as hir; use rustc_hir::def_id::LocalDefId; @@ -65,18 +65,10 @@ impl<'tcx> Visitor<'tcx> for CheckNakedFunctions<'tcx> { check_no_patterns(self.tcx, body.params); check_no_parameters_use(self.tcx, body); check_asm(self.tcx, body, span); - check_inline(self.tcx, attrs); } } } -/// Check that the function isn't inlined. -fn check_inline(tcx: TyCtxt<'_>, attrs: &[Attribute]) { - for attr in attrs.iter().filter(|attr| attr.has_name(sym::inline)) { - tcx.sess.struct_span_err(attr.span, "naked functions cannot be inlined").emit(); - } -} - /// Checks that function uses non-Rust ABI. fn check_abi(tcx: TyCtxt<'_>, hir_id: HirId, abi: Abi, fn_ident_span: Span) { if abi == Abi::Rust { diff --git a/src/test/ui/asm/naked-functions-inline.rs b/src/test/ui/asm/naked-functions-inline.rs new file mode 100644 index 0000000000000..9e62cf8d58550 --- /dev/null +++ b/src/test/ui/asm/naked-functions-inline.rs @@ -0,0 +1,32 @@ +// needs-asm-support + +#![feature(naked_functions)] +#![crate_type = "lib"] + +use std::arch::asm; + +#[naked] +pub unsafe extern "C" fn inline_none() { + asm!("", options(noreturn)); +} + +#[naked] +#[inline] +//~^ ERROR cannot use additional code generation attributes with `#[naked]` +pub unsafe extern "C" fn inline_hint() { + asm!("", options(noreturn)); +} + +#[naked] +#[inline(always)] +//~^ ERROR cannot use additional code generation attributes with `#[naked]` +pub unsafe extern "C" fn inline_always() { + asm!("", options(noreturn)); +} + +#[naked] +#[inline(never)] +//~^ ERROR cannot use additional code generation attributes with `#[naked]` +pub unsafe extern "C" fn inline_never() { + asm!("", options(noreturn)); +} diff --git a/src/test/ui/asm/naked-functions-inline.stderr b/src/test/ui/asm/naked-functions-inline.stderr new file mode 100644 index 0000000000000..37441def724e6 --- /dev/null +++ b/src/test/ui/asm/naked-functions-inline.stderr @@ -0,0 +1,21 @@ +error[E0736]: cannot use additional code generation attributes with `#[naked]` + --> $DIR/naked-functions-inline.rs:14:1 + | +LL | #[inline] + | ^^^^^^^^^ + +error[E0736]: cannot use additional code generation attributes with `#[naked]` + --> $DIR/naked-functions-inline.rs:21:1 + | +LL | #[inline(always)] + | ^^^^^^^^^^^^^^^^^ + +error[E0736]: cannot use additional code generation attributes with `#[naked]` + --> $DIR/naked-functions-inline.rs:28:1 + | +LL | #[inline(never)] + | ^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0736`. diff --git a/src/test/ui/asm/naked-functions-target-feature.rs b/src/test/ui/asm/naked-functions-target-feature.rs new file mode 100644 index 0000000000000..68d7ed1170f13 --- /dev/null +++ b/src/test/ui/asm/naked-functions-target-feature.rs @@ -0,0 +1,26 @@ +// ignore-arm +// ignore-aarch64 +// ignore-wasm +// ignore-emscripten +// ignore-mips +// ignore-mips64 +// ignore-powerpc +// ignore-powerpc64 +// ignore-powerpc64le +// ignore-riscv64 +// ignore-s390x +// ignore-sparc +// ignore-sparc64 +// needs-asm-support + +#![feature(naked_functions)] +#![crate_type = "lib"] + +use std::arch::asm; + +#[target_feature(enable = "sse2")] +//~^ ERROR cannot use additional code generation attributes with `#[naked]` +#[naked] +pub unsafe extern "C" fn naked_target_feature() { + asm!("", options(noreturn)); +} diff --git a/src/test/ui/asm/naked-functions-target-feature.stderr b/src/test/ui/asm/naked-functions-target-feature.stderr new file mode 100644 index 0000000000000..9370dceaf9f2c --- /dev/null +++ b/src/test/ui/asm/naked-functions-target-feature.stderr @@ -0,0 +1,9 @@ +error[E0736]: cannot use additional code generation attributes with `#[naked]` + --> $DIR/naked-functions-target-feature.rs:21:1 + | +LL | #[target_feature(enable = "sse2")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0736`. diff --git a/src/test/ui/asm/naked-functions-testattrs.rs b/src/test/ui/asm/naked-functions-testattrs.rs new file mode 100644 index 0000000000000..d7cd0f41f2434 --- /dev/null +++ b/src/test/ui/asm/naked-functions-testattrs.rs @@ -0,0 +1,39 @@ +// needs-asm-support +// compile-flags: --test + +#![allow(undefined_naked_function_abi)] +#![feature(naked_functions)] +#![feature(test)] +#![crate_type = "lib"] + +use std::arch::asm; + +#[test] +#[naked] +//~^ ERROR cannot use testing attributes with `#[naked]` +fn test_naked() { + unsafe { asm!("", options(noreturn)) }; +} + +#[should_panic] +#[test] +#[naked] +//~^ ERROR cannot use testing attributes with `#[naked]` +fn test_naked_should_panic() { + unsafe { asm!("", options(noreturn)) }; +} + +#[ignore] +#[test] +#[naked] +//~^ ERROR cannot use testing attributes with `#[naked]` +fn test_naked_ignore() { + unsafe { asm!("", options(noreturn)) }; +} + +#[bench] +#[naked] +//~^ ERROR cannot use testing attributes with `#[naked]` +fn bench_naked() { + unsafe { asm!("", options(noreturn)) }; +} diff --git a/src/test/ui/asm/naked-functions-testattrs.stderr b/src/test/ui/asm/naked-functions-testattrs.stderr new file mode 100644 index 0000000000000..644c3795acbd7 --- /dev/null +++ b/src/test/ui/asm/naked-functions-testattrs.stderr @@ -0,0 +1,27 @@ +error[E0788]: cannot use testing attributes with `#[naked]` + --> $DIR/naked-functions-testattrs.rs:12:1 + | +LL | #[naked] + | ^^^^^^^^ + +error[E0788]: cannot use testing attributes with `#[naked]` + --> $DIR/naked-functions-testattrs.rs:20:1 + | +LL | #[naked] + | ^^^^^^^^ + +error[E0788]: cannot use testing attributes with `#[naked]` + --> $DIR/naked-functions-testattrs.rs:28:1 + | +LL | #[naked] + | ^^^^^^^^ + +error[E0788]: cannot use testing attributes with `#[naked]` + --> $DIR/naked-functions-testattrs.rs:35:1 + | +LL | #[naked] + | ^^^^^^^^ + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0788`. diff --git a/src/test/ui/asm/naked-functions.rs b/src/test/ui/asm/naked-functions.rs index 5b4293972ea21..963183db1a5e2 100644 --- a/src/test/ui/asm/naked-functions.rs +++ b/src/test/ui/asm/naked-functions.rs @@ -160,40 +160,3 @@ pub unsafe extern "C" fn valid_c() { pub unsafe extern "C" fn valid_att_syntax() { asm!("", options(noreturn, att_syntax)); } - -#[naked] -pub unsafe extern "C" fn inline_none() { - asm!("", options(noreturn)); -} - -#[naked] -#[inline] -//~^ ERROR naked functions cannot be inlined -pub unsafe extern "C" fn inline_hint() { - asm!("", options(noreturn)); -} - -#[naked] -#[inline(always)] -//~^ ERROR naked functions cannot be inlined -pub unsafe extern "C" fn inline_always() { - asm!("", options(noreturn)); -} - -#[naked] -#[inline(never)] -//~^ ERROR naked functions cannot be inlined -pub unsafe extern "C" fn inline_never() { - asm!("", options(noreturn)); -} - -#[naked] -#[inline] -//~^ ERROR naked functions cannot be inlined -#[inline(always)] -//~^ ERROR naked functions cannot be inlined -#[inline(never)] -//~^ ERROR naked functions cannot be inlined -pub unsafe extern "C" fn inline_all() { - asm!("", options(noreturn)); -} diff --git a/src/test/ui/asm/naked-functions.stderr b/src/test/ui/asm/naked-functions.stderr index c1dcc433db6c6..76bf5873ccb69 100644 --- a/src/test/ui/asm/naked-functions.stderr +++ b/src/test/ui/asm/naked-functions.stderr @@ -219,42 +219,6 @@ warning: Rust ABI is unsupported in naked functions LL | pub unsafe fn rust_abi() { | ^^^^^^^^ -error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:170:1 - | -LL | #[inline] - | ^^^^^^^^^ - -error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:177:1 - | -LL | #[inline(always)] - | ^^^^^^^^^^^^^^^^^ - -error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:184:1 - | -LL | #[inline(never)] - | ^^^^^^^^^^^^^^^^ - -error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:191:1 - | -LL | #[inline] - | ^^^^^^^^^ - -error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:193:1 - | -LL | #[inline(always)] - | ^^^^^^^^^^^^^^^^^ - -error: naked functions cannot be inlined - --> $DIR/naked-functions.rs:195:1 - | -LL | #[inline(never)] - | ^^^^^^^^^^^^^^^^ - -error: aborting due to 30 previous errors; 2 warnings emitted +error: aborting due to 24 previous errors; 2 warnings emitted For more information about this error, try `rustc --explain E0787`. diff --git a/src/test/ui/rfc-2091-track-caller/error-with-naked.rs b/src/test/ui/rfc-2091-track-caller/error-with-naked.rs index 0045d608133a6..90ce95ac16924 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-naked.rs +++ b/src/test/ui/rfc-2091-track-caller/error-with-naked.rs @@ -3,7 +3,7 @@ use std::arch::asm; -#[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]` +#[track_caller] //~ ERROR cannot use additional code generation attributes with `#[naked]` #[naked] extern "C" fn f() { asm!("", options(noreturn)); @@ -12,7 +12,7 @@ extern "C" fn f() { struct S; impl S { - #[track_caller] //~ ERROR cannot use `#[track_caller]` with `#[naked]` + #[track_caller] //~ ERROR cannot use additional code generation attributes with `#[naked]` #[naked] extern "C" fn g() { asm!("", options(noreturn)); diff --git a/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr b/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr index d33aecc0f97bf..33eef27b87fb6 100644 --- a/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr +++ b/src/test/ui/rfc-2091-track-caller/error-with-naked.stderr @@ -1,10 +1,10 @@ -error[E0736]: cannot use `#[track_caller]` with `#[naked]` +error[E0736]: cannot use additional code generation attributes with `#[naked]` --> $DIR/error-with-naked.rs:6:1 | LL | #[track_caller] | ^^^^^^^^^^^^^^^ -error[E0736]: cannot use `#[track_caller]` with `#[naked]` +error[E0736]: cannot use additional code generation attributes with `#[naked]` --> $DIR/error-with-naked.rs:15:5 | LL | #[track_caller]