Open
Description
An issue I've observed in several contexts discussing the new asm!
syntax for inline assembly: everyone formats asm!
statements differently, and we should 1) come up with guidance on how to do so, and 2) implement that guidance in rustfmt
.
Notably, this includes how to format both single-line and multi-line assembly statements.
EDIT: I've updated these guidelines to use the new support for multiple template string arguments, implemented in rust-lang/rust#73364 .
With my style team hat on, I would propose the following guidelines:
- Single-line assembly code should be formatted as a single string argument and treated as any other argument to a format macro.
- Multi-line assembly code should be formatted with one string argument per line of assembly, indented as separate arguments:
asm!( "instruction 1", "instruction 2", ..., );
- Common assembly formatting such as
\n\t
(often seen in inline assembly for other compilers that directly copy the provided string into their assembly output) is not necessary with Rust inline assembly. Focus on keeping the assembly readable. Note that Rust is not prescriptive about the formatting of your assembly, so if you wish to put multiple instructions or directives or labels on one line (and thus within one assembly string), you can do so, and rustfmt will treat each assembly string as a line. - Use the opening
"
of each string as the base for any indentation within the assembly code; for instance, if you want to indent instructions four spaces past labels, include the indentation inside the string before the instructions. That way, Rust formatting can keep the strings aligned and your assembly code will remain aligned within them:asm!( "1:", " instruction 1", " instruction 2", "2:", " instruction 3", );
- Simple
asm!
with only one assembly string can have the entireasm!
including all its arguments on the same line, if the whole thing fromasm!(
to);
(plus indentation) fits in the line width. - Any
asm!
block that needs breaking across multiple lines, or anyasm!
block that has multiple assembly strings no matter how short, should always put each argument on its own line, aligned one indentation level past theasm!
, with a trailing comma on each, just like a function. options(...)
goes on one line if it fits; otherwise, format it as though it were a nested function call to a function namedoptions
.- Never place any space or line breaks inside of
in(reg)
orout(reg)
orinout(reg)
orin("regname")
orout("regname")
or similar; always treat them as a single atomic unit. - If an
inout
orinlateout
pair of expressions are too long to fit on one line, break before (never after) the=>
, and indent the=>
one level further:asm!( "instruction {}", inout(reg) very_long_expression => very_long_out_expression, )
- If an
in(reg)
orout(reg)
orlateout(reg)
expression is too long, break between the)
and the expression and indent one level, then format from there; however, if the expression can be broken internally, follow same the rules for when to leave the head of the expression on the same line as thein(reg)
or similar as ifin(reg)
were the opener of a function:asm!( "instruction {}", in(reg) extremely_long_unbreakable_expression, in(reg) function_name() .method_name(method_arg) .further_chained_method(), out(reg) long_function_name( long_function_argument_expression, ), );
- For named arguments like
name = in(reg) expression
, line-break it as you would an assignment statement with the same indentation, treating thein(reg) expression
as the right-hand side of the assignment, and following all the same rules as above.
Metadata
Metadata
Assignees
Labels
No labels