mirror of https://github.com/rust-lang/rust.git
Rollup merge of #130146 - folkertdev:bootstrap-naked-asm, r=Amanieu
bootstrap `naked_asm!` for `compiler-builtins` tracking issue: https://github.com/rust-lang/rust/issues/90957 parent PR: https://github.com/rust-lang/rust/pull/128651 in this PR, `naked_asm!` is added as 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. The `naked_asm!` macro must be introduced first so that we can upgrade `compiler-builtins` to use it, and can then change the implementation of `naked_asm!` in https://github.com/rust-lang/rust/pull/128651 I've added some usages for `naked_asm!` in the tests, so we can be confident that it works, but I've left upgrading the whole test suite to the parent PR. r? ``@Amanieu``
This commit is contained in:
commit
57273d82a8
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -1255,6 +1255,7 @@ symbols! {
|
||||||
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,
|
||||||
|
|
|
@ -17,6 +17,20 @@ pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) {
|
||||||
/* 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
|
||||||
|
|
|
@ -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!("");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue