bootstrap naked_asm! for compiler-builtins

in this commit, `naked_asm!` is an alias for `asm!` with one difference: `options(noreturn)` is always enabled by `naked_asm!`. That makes it future-compatible for when `naked_asm!` starts disallowing `options(noreturn)` later.
This commit is contained in:
Folkert de Vries 2024-09-09 12:47:40 +02:00
parent d678b81485
commit 02378997ea
5 changed files with 60 additions and 6 deletions

View File

@ -812,6 +812,44 @@ pub(super) fn expand_asm<'cx>(
}) })
} }
pub(super) fn expand_naked_asm<'cx>(
ecx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
) -> MacroExpanderResult<'cx> {
ExpandResult::Ready(match parse_args(ecx, sp, tts, false) {
Ok(args) => {
let ExpandResult::Ready(mac) = expand_preparsed_asm(ecx, args) else {
return ExpandResult::Retry(());
};
let expr = match mac {
Ok(mut inline_asm) => {
// for future compatibility, we always set the NORETURN option.
//
// When we turn `asm!` into `naked_asm!` with this implementation, we can drop
// the `options(noreturn)`, which makes the upgrade smooth when `naked_asm!`
// starts disallowing the `noreturn` option in the future
inline_asm.options |= ast::InlineAsmOptions::NORETURN;
P(ast::Expr {
id: ast::DUMMY_NODE_ID,
kind: ast::ExprKind::InlineAsm(P(inline_asm)),
span: sp,
attrs: ast::AttrVec::new(),
tokens: None,
})
}
Err(guar) => DummyResult::raw_expr(sp, Some(guar)),
};
MacEager::expr(expr)
}
Err(err) => {
let guar = err.emit();
DummyResult::any(sp, guar)
}
})
}
pub(super) fn expand_global_asm<'cx>( pub(super) fn expand_global_asm<'cx>(
ecx: &'cx mut ExtCtxt<'_>, ecx: &'cx mut ExtCtxt<'_>,
sp: Span, sp: Span,

View File

@ -94,6 +94,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
line: source_util::expand_line, line: source_util::expand_line,
log_syntax: log_syntax::expand_log_syntax, log_syntax: log_syntax::expand_log_syntax,
module_path: source_util::expand_mod, module_path: source_util::expand_mod,
naked_asm: asm::expand_naked_asm,
option_env: env::expand_option_env, option_env: env::expand_option_env,
pattern_type: pattern_type::expand, pattern_type: pattern_type::expand,
std_panic: edition_panic::expand_panic, std_panic: edition_panic::expand_panic,

View File

@ -1254,6 +1254,7 @@
mut_preserve_binding_mode_2024, mut_preserve_binding_mode_2024,
mut_ref, mut_ref,
naked, naked,
naked_asm,
naked_functions, naked_functions,
name, name,
names, names,

View File

@ -26,6 +26,20 @@ fn dummy() {
/* compiler built-in */ /* compiler built-in */
} }
/// Inline assembly used in combination with `#[naked]` functions.
///
/// Refer to [Rust By Example] for a usage guide and the [reference] for
/// detailed information about the syntax and available options.
///
/// [Rust By Example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
/// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html
#[unstable(feature = "naked_functions", issue = "90957")]
#[rustc_builtin_macro]
#[cfg(not(bootstrap))]
pub macro naked_asm("assembly template", $(operands,)* $(options($(option),*))?) {
/* compiler built-in */
}
/// Module-level inline assembly. /// Module-level inline assembly.
/// ///
/// Refer to [Rust By Example] for a usage guide and the [reference] for /// Refer to [Rust By Example] for a usage guide and the [reference] for

View File

@ -2,37 +2,37 @@
#![feature(naked_functions)] #![feature(naked_functions)]
#![crate_type = "lib"] #![crate_type = "lib"]
use std::arch::asm; use std::arch::naked_asm;
#[naked] #[naked]
pub unsafe extern "C" fn inline_none() { pub unsafe extern "C" fn inline_none() {
asm!("", options(noreturn)); naked_asm!("");
} }
#[naked] #[naked]
#[inline] #[inline]
//~^ ERROR [E0736] //~^ ERROR [E0736]
pub unsafe extern "C" fn inline_hint() { pub unsafe extern "C" fn inline_hint() {
asm!("", options(noreturn)); naked_asm!("");
} }
#[naked] #[naked]
#[inline(always)] #[inline(always)]
//~^ ERROR [E0736] //~^ ERROR [E0736]
pub unsafe extern "C" fn inline_always() { pub unsafe extern "C" fn inline_always() {
asm!("", options(noreturn)); naked_asm!("");
} }
#[naked] #[naked]
#[inline(never)] #[inline(never)]
//~^ ERROR [E0736] //~^ ERROR [E0736]
pub unsafe extern "C" fn inline_never() { pub unsafe extern "C" fn inline_never() {
asm!("", options(noreturn)); naked_asm!("");
} }
#[naked] #[naked]
#[cfg_attr(all(), inline(never))] #[cfg_attr(all(), inline(never))]
//~^ ERROR [E0736] //~^ ERROR [E0736]
pub unsafe extern "C" fn conditional_inline_never() { pub unsafe extern "C" fn conditional_inline_never() {
asm!("", options(noreturn)); naked_asm!("");
} }