Skip to content

Commit d774fbe

Browse files
authored
Rollup merge of rust-lang#119365 - nbdd0121:asm-goto, r=Amanieu
Add asm goto support to `asm!` Tracking issue: rust-lang#119364 This PR implements asm-goto support, using the syntax described in "future possibilities" section of [RFC2873](https://rust-lang.github.io/rfcs/2873-inline-asm.html#asm-goto). Currently I have only implemented the `label` part, not the `fallthrough` part (i.e. fallthrough is implicit). This doesn't reduce the expressive though, since you can use label-break to get arbitrary control flow or simply set a value and rely on jump threading optimisation to get the desired control flow. I can add that later if deemed necessary. r? ``@Amanieu`` cc ``@ojeda``
2 parents 876847b + 0ee0f29 commit d774fbe

File tree

76 files changed

+857
-200
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+857
-200
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2302,6 +2302,9 @@ pub enum InlineAsmOperand {
23022302
Sym {
23032303
sym: InlineAsmSym,
23042304
},
2305+
Label {
2306+
block: P<Block>,
2307+
},
23052308
}
23062309

23072310
impl InlineAsmOperand {
@@ -2311,7 +2314,7 @@ impl InlineAsmOperand {
23112314
| Self::Out { reg, .. }
23122315
| Self::InOut { reg, .. }
23132316
| Self::SplitInOut { reg, .. } => Some(reg),
2314-
Self::Const { .. } | Self::Sym { .. } => None,
2317+
Self::Const { .. } | Self::Sym { .. } | Self::Label { .. } => None,
23152318
}
23162319
}
23172320
}

compiler/rustc_ast/src/mut_visit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,7 @@ pub fn noop_visit_inline_asm<T: MutVisitor>(asm: &mut InlineAsm, vis: &mut T) {
13311331
}
13321332
InlineAsmOperand::Const { anon_const } => vis.visit_anon_const(anon_const),
13331333
InlineAsmOperand::Sym { sym } => vis.visit_inline_asm_sym(sym),
1334+
InlineAsmOperand::Label { block } => vis.visit_block(block),
13341335
}
13351336
}
13361337
}

compiler/rustc_ast/src/visit.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -823,6 +823,7 @@ pub fn walk_inline_asm<'a, V: Visitor<'a>>(visitor: &mut V, asm: &'a InlineAsm)
823823
try_visit!(visitor.visit_anon_const(anon_const))
824824
}
825825
InlineAsmOperand::Sym { sym } => try_visit!(visitor.visit_inline_asm_sym(sym)),
826+
InlineAsmOperand::Label { block } => try_visit!(visitor.visit_block(block)),
826827
}
827828
}
828829
V::Result::output()

compiler/rustc_ast_lowering/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ ast_lowering_invalid_abi_suggestion = did you mean
8888
ast_lowering_invalid_asm_template_modifier_const =
8989
asm template modifiers are not allowed for `const` arguments
9090
91+
ast_lowering_invalid_asm_template_modifier_label =
92+
asm template modifiers are not allowed for `label` arguments
93+
9194
ast_lowering_invalid_asm_template_modifier_reg_class =
9295
invalid asm template modifier for this register class
9396

compiler/rustc_ast_lowering/src/asm.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ use crate::{ImplTraitContext, ImplTraitPosition, ParamMode, ResolverAstLoweringE
33
use super::errors::{
44
AbiSpecifiedMultipleTimes, AttSyntaxOnlyX86, ClobberAbiNotSupported,
55
InlineAsmUnsupportedTarget, InvalidAbiClobberAbi, InvalidAsmTemplateModifierConst,
6-
InvalidAsmTemplateModifierRegClass, InvalidAsmTemplateModifierRegClassSub,
7-
InvalidAsmTemplateModifierSym, InvalidRegister, InvalidRegisterClass, RegisterClassOnlyClobber,
8-
RegisterConflict,
6+
InvalidAsmTemplateModifierLabel, InvalidAsmTemplateModifierRegClass,
7+
InvalidAsmTemplateModifierRegClassSub, InvalidAsmTemplateModifierSym, InvalidRegister,
8+
InvalidRegisterClass, RegisterClassOnlyClobber, RegisterConflict,
99
};
1010
use super::LoweringContext;
1111

@@ -237,6 +237,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
237237
}
238238
}
239239
}
240+
InlineAsmOperand::Label { block } => {
241+
if !self.tcx.features().asm_goto {
242+
feature_err(
243+
sess,
244+
sym::asm_goto,
245+
*op_sp,
246+
"label operands for inline assembly are unstable",
247+
)
248+
.emit();
249+
}
250+
hir::InlineAsmOperand::Label { block: self.lower_block(block, false) }
251+
}
240252
};
241253
(op, self.lower_span(*op_sp))
242254
})
@@ -296,6 +308,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
296308
op_span: op_sp,
297309
});
298310
}
311+
hir::InlineAsmOperand::Label { .. } => {
312+
self.dcx().emit_err(InvalidAsmTemplateModifierLabel {
313+
placeholder_span,
314+
op_span: op_sp,
315+
});
316+
}
299317
}
300318
}
301319
}
@@ -335,7 +353,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
335353

336354
hir::InlineAsmOperand::Const { .. }
337355
| hir::InlineAsmOperand::SymFn { .. }
338-
| hir::InlineAsmOperand::SymStatic { .. } => {
356+
| hir::InlineAsmOperand::SymStatic { .. }
357+
| hir::InlineAsmOperand::Label { .. } => {
339358
unreachable!("{op:?} is not a register operand");
340359
}
341360
};

compiler/rustc_ast_lowering/src/errors.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,16 @@ pub struct InvalidAsmTemplateModifierSym {
261261
pub op_span: Span,
262262
}
263263

264+
#[derive(Diagnostic, Clone, Copy)]
265+
#[diag(ast_lowering_invalid_asm_template_modifier_label)]
266+
pub struct InvalidAsmTemplateModifierLabel {
267+
#[primary_span]
268+
#[label(ast_lowering_template_modifier)]
269+
pub placeholder_span: Span,
270+
#[label(ast_lowering_argument)]
271+
pub op_span: Span,
272+
}
273+
264274
#[derive(Diagnostic, Clone, Copy)]
265275
#[diag(ast_lowering_register_class_only_clobber)]
266276
pub struct RegisterClassOnlyClobber {

compiler/rustc_ast_pretty/src/pprust/state.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,6 +1452,10 @@ impl<'a> State<'a> {
14521452
s.print_path(&sym.path, true, 0);
14531453
}
14541454
}
1455+
InlineAsmOperand::Label { block } => {
1456+
s.head("label");
1457+
s.print_block(block);
1458+
}
14551459
}
14561460
}
14571461
AsmArg::ClobberAbi(abi) => {

compiler/rustc_borrowck/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -723,7 +723,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
723723
operands,
724724
options: _,
725725
line_spans: _,
726-
destination: _,
726+
targets: _,
727727
unwind: _,
728728
} => {
729729
for op in operands {
@@ -749,7 +749,8 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
749749
}
750750
InlineAsmOperand::Const { value: _ }
751751
| InlineAsmOperand::SymFn { value: _ }
752-
| InlineAsmOperand::SymStatic { def_id: _ } => {}
752+
| InlineAsmOperand::SymStatic { def_id: _ }
753+
| InlineAsmOperand::Label { target_index: _ } => {}
753754
}
754755
}
755756
}

compiler/rustc_borrowck/src/polonius/loan_invalidations.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'cx, 'tcx> {
161161
operands,
162162
options: _,
163163
line_spans: _,
164-
destination: _,
164+
targets: _,
165165
unwind: _,
166166
} => {
167167
for op in operands {
@@ -182,7 +182,8 @@ impl<'cx, 'tcx> Visitor<'tcx> for LoanInvalidationsGenerator<'cx, 'tcx> {
182182
}
183183
InlineAsmOperand::Const { value: _ }
184184
| InlineAsmOperand::SymFn { value: _ }
185-
| InlineAsmOperand::SymStatic { def_id: _ } => {}
185+
| InlineAsmOperand::SymStatic { def_id: _ }
186+
| InlineAsmOperand::Label { target_index: _ } => {}
186187
}
187188
}
188189
}

compiler/rustc_borrowck/src/type_check/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1770,8 +1770,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
17701770
self.assert_iscleanup(body, block_data, real_target, is_cleanup);
17711771
self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup);
17721772
}
1773-
TerminatorKind::InlineAsm { destination, unwind, .. } => {
1774-
if let Some(target) = destination {
1773+
TerminatorKind::InlineAsm { ref targets, unwind, .. } => {
1774+
for &target in targets {
17751775
self.assert_iscleanup(body, block_data, target, is_cleanup);
17761776
}
17771777
self.assert_iscleanup_unwind(body, block_data, unwind, is_cleanup);

0 commit comments

Comments
 (0)