Skip to content

Commit 12f8652

Browse files
authored
Unrolled build for #156582
Rollup merge of #156582 - daxpedda:global-asm-statement, r=petrochenkov Allow `global_asm!` in statement positions This PR makes it possible to put `global_asm!` in statement positions. This is particularly useful for proc-macros, where you otherwise have to wrap them in `mod foo { global_asm!(...); }`. I'm happy to open an ACP first (or a design meeting?). I would also assume this needs sign-off from the lang-team? Previously discussed on [Zulip](https://rust-lang.zulipchat.com/#narrow/channel/216763-project-inline-asm/topic/Item.20position.20global_asm/with/581784943). r? @Amanieu
2 parents 7517636 + 450cdb5 commit 12f8652

6 files changed

Lines changed: 104 additions & 37 deletions

File tree

compiler/rustc_builtin_macros/src/asm.rs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_parse_format as parse;
1010
use rustc_session::lint;
1111
use rustc_span::{ErrorGuaranteed, InnerSpan, Span, Symbol, sym};
1212
use rustc_target::asm::InlineAsmArch;
13-
use smallvec::smallvec;
13+
use smallvec::{SmallVec, smallvec};
1414

1515
use crate::errors;
1616
use crate::util::{ExprToSpannedString, expr_to_spanned_string};
@@ -26,6 +26,24 @@ struct ValidatedAsmArgs {
2626
pub options_spans: Vec<Span>,
2727
}
2828

29+
struct MacGlobalAsm {
30+
item: ast::Item,
31+
}
32+
33+
impl MacResult for MacGlobalAsm {
34+
fn make_items(self: Box<Self>) -> Option<SmallVec<[Box<ast::Item>; 1]>> {
35+
Some(smallvec![Box::new(self.item)])
36+
}
37+
38+
fn make_stmts(self: Box<Self>) -> Option<SmallVec<[ast::Stmt; 1]>> {
39+
Some(smallvec![ast::Stmt {
40+
id: ast::DUMMY_NODE_ID,
41+
span: self.item.span,
42+
kind: ast::StmtKind::Item(Box::new(self.item)),
43+
}])
44+
}
45+
}
46+
2947
fn parse_args<'a>(
3048
ecx: &ExtCtxt<'a>,
3149
sp: Span,
@@ -650,18 +668,20 @@ pub(super) fn expand_global_asm<'cx>(
650668
return ExpandResult::Retry(());
651669
};
652670
match mac {
653-
Ok(inline_asm) => MacEager::items(smallvec![Box::new(ast::Item {
654-
attrs: ast::AttrVec::new(),
655-
id: ast::DUMMY_NODE_ID,
656-
kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)),
657-
vis: ast::Visibility {
658-
span: sp.shrink_to_lo(),
659-
kind: ast::VisibilityKind::Inherited,
671+
Ok(inline_asm) => Box::new(MacGlobalAsm {
672+
item: ast::Item {
673+
attrs: ast::AttrVec::new(),
674+
id: ast::DUMMY_NODE_ID,
675+
kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)),
676+
vis: ast::Visibility {
677+
span: sp.shrink_to_lo(),
678+
kind: ast::VisibilityKind::Inherited,
679+
tokens: None,
680+
},
681+
span: sp,
660682
tokens: None,
661683
},
662-
span: sp,
663-
tokens: None,
664-
})]),
684+
}),
665685
Err(guar) => DummyResult::any(sp, guar),
666686
}
667687
}

tests/ui/asm/naked-functions.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,20 @@
66
#![feature(asm_unwind, linkage, rustc_attrs, cfg_target_object_format)]
77
#![crate_type = "lib"]
88

9-
use std::arch::{asm, naked_asm};
9+
use std::arch::{asm, global_asm, naked_asm};
1010

1111
#[unsafe(naked)]
1212
pub extern "C" fn inline_asm_macro() {
1313
unsafe { asm!("", options(raw)) };
1414
//~^ERROR the `asm!` macro is not allowed in naked functions
1515
}
1616

17+
#[unsafe(naked)]
18+
pub extern "C" fn global_asm_macro() {
19+
//~^ERROR naked functions must contain a single `naked_asm!` invocation
20+
global_asm!("");
21+
}
22+
1723
#[repr(C)]
1824
pub struct P {
1925
x: u8,
Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,71 @@
11
error: the `in` operand cannot be used with `naked_asm!`
2-
--> $DIR/naked-functions.rs:47:29
2+
--> $DIR/naked-functions.rs:53:29
33
|
44
LL | naked_asm!("/* {0} */", in(reg) a)
55
| ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it
66

77
error: the `in` operand cannot be used with `naked_asm!`
8-
--> $DIR/naked-functions.rs:68:10
8+
--> $DIR/naked-functions.rs:74:10
99
|
1010
LL | in(reg) a,
1111
| ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it
1212

1313
error: the `noreturn` option cannot be used with `naked_asm!`
14-
--> $DIR/naked-functions.rs:88:28
14+
--> $DIR/naked-functions.rs:94:28
1515
|
1616
LL | naked_asm!("", options(noreturn));
1717
| ^^^^^^^^ the `noreturn` option is not meaningful for global-scoped inline assembly
1818

1919
error: the `nomem` option cannot be used with `naked_asm!`
20-
--> $DIR/naked-functions.rs:105:28
20+
--> $DIR/naked-functions.rs:111:28
2121
|
2222
LL | naked_asm!("", options(nomem, preserves_flags));
2323
| ^^^^^ the `nomem` option is not meaningful for global-scoped inline assembly
2424

2525
error: the `preserves_flags` option cannot be used with `naked_asm!`
26-
--> $DIR/naked-functions.rs:105:35
26+
--> $DIR/naked-functions.rs:111:35
2727
|
2828
LL | naked_asm!("", options(nomem, preserves_flags));
2929
| ^^^^^^^^^^^^^^^ the `preserves_flags` option is not meaningful for global-scoped inline assembly
3030

3131
error: the `readonly` option cannot be used with `naked_asm!`
32-
--> $DIR/naked-functions.rs:112:28
32+
--> $DIR/naked-functions.rs:118:28
3333
|
3434
LL | naked_asm!("", options(readonly, nostack), options(pure));
3535
| ^^^^^^^^ the `readonly` option is not meaningful for global-scoped inline assembly
3636

3737
error: the `nostack` option cannot be used with `naked_asm!`
38-
--> $DIR/naked-functions.rs:112:38
38+
--> $DIR/naked-functions.rs:118:38
3939
|
4040
LL | naked_asm!("", options(readonly, nostack), options(pure));
4141
| ^^^^^^^ the `nostack` option is not meaningful for global-scoped inline assembly
4242

4343
error: the `pure` option cannot be used with `naked_asm!`
44-
--> $DIR/naked-functions.rs:112:56
44+
--> $DIR/naked-functions.rs:118:56
4545
|
4646
LL | naked_asm!("", options(readonly, nostack), options(pure));
4747
| ^^^^ the `pure` option is not meaningful for global-scoped inline assembly
4848

4949
error: the `may_unwind` option cannot be used with `naked_asm!`
50-
--> $DIR/naked-functions.rs:120:28
50+
--> $DIR/naked-functions.rs:126:28
5151
|
5252
LL | naked_asm!("", options(may_unwind));
5353
| ^^^^^^^^^^ the `may_unwind` option is not meaningful for global-scoped inline assembly
5454

5555
error: this is a user specified error
56-
--> $DIR/naked-functions.rs:151:5
56+
--> $DIR/naked-functions.rs:157:5
5757
|
5858
LL | compile_error!("this is a user specified error")
5959
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6060

6161
error: this is a user specified error
62-
--> $DIR/naked-functions.rs:157:5
62+
--> $DIR/naked-functions.rs:163:5
6363
|
6464
LL | compile_error!("this is a user specified error");
6565
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6666

6767
error: asm template must be a string literal
68-
--> $DIR/naked-functions.rs:164:16
68+
--> $DIR/naked-functions.rs:170:16
6969
|
7070
LL | naked_asm!(invalid_syntax)
7171
| ^^^^^^^^^^^^^^
@@ -76,40 +76,46 @@ error[E0787]: the `asm!` macro is not allowed in naked functions
7676
LL | unsafe { asm!("", options(raw)) };
7777
| ^^^^^^^^^^^^^^^^^^^^^^ consider using the `naked_asm!` macro instead
7878

79+
error[E0787]: naked functions must contain a single `naked_asm!` invocation
80+
--> $DIR/naked-functions.rs:18:1
81+
|
82+
LL | pub extern "C" fn global_asm_macro() {
83+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
84+
7985
error: patterns not allowed in naked function parameters
80-
--> $DIR/naked-functions.rs:25:5
86+
--> $DIR/naked-functions.rs:31:5
8187
|
8288
LL | mut a: u32,
8389
| ^^^^^
8490

8591
error: patterns not allowed in naked function parameters
86-
--> $DIR/naked-functions.rs:27:5
92+
--> $DIR/naked-functions.rs:33:5
8793
|
8894
LL | &b: &i32,
8995
| ^^
9096

9197
error: patterns not allowed in naked function parameters
92-
--> $DIR/naked-functions.rs:29:6
98+
--> $DIR/naked-functions.rs:35:6
9399
|
94100
LL | (None | Some(_)): Option<std::ptr::NonNull<u8>>,
95101
| ^^^^^^^^^^^^^^
96102

97103
error: patterns not allowed in naked function parameters
98-
--> $DIR/naked-functions.rs:31:5
104+
--> $DIR/naked-functions.rs:37:5
99105
|
100106
LL | P { x, y }: P,
101107
| ^^^^^^^^^^
102108

103109
error: referencing function parameters is not allowed in naked functions
104-
--> $DIR/naked-functions.rs:40:5
110+
--> $DIR/naked-functions.rs:46:5
105111
|
106112
LL | a + 1
107113
| ^
108114
|
109115
= help: follow the calling convention in asm block to use parameters
110116

111117
error[E0787]: naked functions must contain a single `naked_asm!` invocation
112-
--> $DIR/naked-functions.rs:38:1
118+
--> $DIR/naked-functions.rs:44:1
113119
|
114120
LL | pub extern "C" fn inc(a: u32) -> u32 {
115121
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -118,7 +124,7 @@ LL | a + 1
118124
| ----- not allowed in naked functions
119125

120126
error[E0787]: naked functions must contain a single `naked_asm!` invocation
121-
--> $DIR/naked-functions.rs:52:1
127+
--> $DIR/naked-functions.rs:58:1
122128
|
123129
LL | pub extern "C" fn inc_closure(a: u32) -> u32 {
124130
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -127,7 +133,7 @@ LL | (|| a + 1)()
127133
| ------------ not allowed in naked functions
128134

129135
error[E0787]: naked functions must contain a single `naked_asm!` invocation
130-
--> $DIR/naked-functions.rs:58:1
136+
--> $DIR/naked-functions.rs:64:1
131137
|
132138
LL | pub extern "C" fn unsupported_operands() {
133139
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -144,13 +150,13 @@ LL | let mut e = 0usize;
144150
| ------------------- not allowed in naked functions
145151

146152
error[E0787]: naked functions must contain a single `naked_asm!` invocation
147-
--> $DIR/naked-functions.rs:80:1
153+
--> $DIR/naked-functions.rs:86:1
148154
|
149155
LL | pub extern "C" fn missing_assembly() {
150156
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
151157

152158
error[E0787]: naked functions must contain a single `naked_asm!` invocation
153-
--> $DIR/naked-functions.rs:85:1
159+
--> $DIR/naked-functions.rs:91:1
154160
|
155161
LL | pub extern "C" fn too_many_asm_blocks() {
156162
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -159,22 +165,22 @@ LL | naked_asm!("");
159165
| -------------- multiple `naked_asm!` invocations are not allowed in naked functions
160166

161167
error: referencing function parameters is not allowed in naked functions
162-
--> $DIR/naked-functions.rs:97:11
168+
--> $DIR/naked-functions.rs:103:11
163169
|
164170
LL | *&y
165171
| ^
166172
|
167173
= help: follow the calling convention in asm block to use parameters
168174

169175
error[E0787]: naked functions must contain a single `naked_asm!` invocation
170-
--> $DIR/naked-functions.rs:95:5
176+
--> $DIR/naked-functions.rs:101:5
171177
|
172178
LL | pub extern "C" fn inner(y: usize) -> usize {
173179
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
174180
LL |
175181
LL | *&y
176182
| --- not allowed in naked functions
177183

178-
error: aborting due to 25 previous errors
184+
error: aborting due to 26 previous errors
179185

180186
For more information about this error, try `rustc --explain E0787`.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
//@ needs-asm-support
2+
3+
use std::arch::global_asm;
4+
5+
fn main() {
6+
let x = 42;
7+
global_asm!("{}", in(x));
8+
//~^ ERROR the `in` operand cannot be used with `global_asm!`
9+
//~^^ NOTE the `in` operand is not meaningful for global-scoped inline assembly, remove it
10+
11+
let y = global_asm!("");
12+
//~^ ERROR non-expression macro in expression position: global_asm
13+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: the `in` operand cannot be used with `global_asm!`
2+
--> $DIR/statement-global-asm-error.rs:7:23
3+
|
4+
LL | global_asm!("{}", in(x));
5+
| ^^ the `in` operand is not meaningful for global-scoped inline assembly, remove it
6+
7+
error: non-expression macro in expression position: global_asm
8+
--> $DIR/statement-global-asm-error.rs:11:13
9+
|
10+
LL | let y = global_asm!("");
11+
| ^^^^^^^^^^^^^^^
12+
13+
error: aborting due to 2 previous errors
14+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
//@ needs-asm-support
2+
//@ run-pass
3+
4+
use std::arch::global_asm;
5+
6+
fn main() {
7+
global_asm!("");
8+
}

0 commit comments

Comments
 (0)