Skip to content

Reorder inline asm operands in pretty printer to satisfy grammar constraints#154088

Merged
rust-bors[bot] merged 2 commits intorust-lang:mainfrom
aytey:fix-asm-operand-ordering
Mar 26, 2026
Merged

Reorder inline asm operands in pretty printer to satisfy grammar constraints#154088
rust-bors[bot] merged 2 commits intorust-lang:mainfrom
aytey:fix-asm-operand-ordering

Conversation

@aytey
Copy link
Copy Markdown
Contributor

@aytey aytey commented Mar 19, 2026

After macro expansion, named asm! operands are converted to positional operands and the template string uses numeric indices. However, the pretty printer previously emitted operands in their original AST order, which could place positional (formerly named) register-class operands after explicit register operands. This violates the asm! grammar rule that positional arguments cannot follow explicit register arguments, causing the expanded output from rustc -Zunpretty=expanded to fail to reparse.

When reordering is needed, the fix partitions operands into non-explicit and explicit register groups, emits non-explicit operands first, then explicit register operands, and remaps template placeholder indices ({N}) to match the new positions. When operands are already correctly ordered, the original code path is used unchanged.

Example

before (rustc 1.96.0-nightly (3b1b0ef4d 2026-03-11)):

#![feature(prelude_import)]
#![no_std]
extern crate std;
#[prelude_import]
use ::std::prelude::rust_2015::*;
//@ pretty-mode:expanded
//@ pp-exact:asm-operand-order.pp
//@ only-x86_64

use std::arch::asm;

pub fn main() {
    unsafe {
        asm!("{1}", out("rax") _, in(reg) 4);
        asm!("{1}", out("rax") _, in(reg) 4, options(nostack));
        asm!("{1} {2}", out("rax") _, in(reg) 4, in(reg) 5);
    }
}

after (this branch):

#![feature(prelude_import)]
#![no_std]
extern crate std;
#[prelude_import]
use ::std::prelude::rust_2015::*;
//@ pretty-mode:expanded
//@ pp-exact:asm-operand-order.pp
//@ only-x86_64

use std::arch::asm;

pub fn main() {
    unsafe {
        asm!("{0}", in(reg) 4, out("rax") _);
        asm!("{0}", in(reg) 4, out("rax") _, options(nostack));
        asm!("{0} {1}", in(reg) 4, in(reg) 5, out("rax") _);
    }
}

Notice the operand reordering: in the before, explicit register operands (out("rax")) appear before positional operands (in(reg)), violating the grammar (E0662). The template references are also wrong ({1} instead of {0}). The after moves positional operands first and renumbers the template references accordingly.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 19, 2026
@rustbot
Copy link
Copy Markdown
Collaborator

rustbot commented Mar 19, 2026

r? @davidtwco

rustbot has assigned @davidtwco.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 69 candidates
  • Random selection from 15 candidates

@aytey aytey force-pushed the fix-asm-operand-ordering branch from 1d98bca to f2ef828 Compare March 19, 2026 10:36
…traints

After macro expansion, named `asm!` operands are converted to positional
operands and the template string uses numeric indices. However, the pretty
printer previously emitted operands in their original AST order, which could
place positional (formerly named) register-class operands after explicit
register operands. This violates the `asm!` grammar rule that positional
arguments cannot follow explicit register arguments, causing the expanded
output from `rustc -Zunpretty=expanded` to fail to reparse.

When reordering is needed, the fix partitions operands into non-explicit and
explicit register groups, emits non-explicit operands first, then explicit
register operands, and remaps template placeholder indices (`{N}`) to match
the new positions. When operands are already correctly ordered, the original
code path is used unchanged.

Signed-off-by: Andrew V. Teylu <andrew.teylu@vector.com>
@aytey aytey force-pushed the fix-asm-operand-ordering branch from f2ef828 to 9975d47 Compare March 19, 2026 10:44
@aytey aytey changed the title Reorder inline asm operands in pretty printer to satisfy grammar cons… Reorder inline asm operands in pretty printer to satisfy grammar constraints Mar 19, 2026
…overage

Extract the inline asm operand reorder/remap logic into a dedicated helper so
`print_inline_asm` stays focused on assembling the printed argument list.
This keeps the reordered-template logic local to the AST pretty printer while
making the main printing path easier to read.

Also extend the pretty regression test with a `const` operand case. That checks
that non-register operands other than `in(reg)` are also moved ahead of explicit
register operands and that the remapped template indices still match the new
operand order.

Signed-off-by: Andrew V. Teylu <andrew.teylu@vector.com>
@davidtwco
Copy link
Copy Markdown
Member

@bors r+ rollup

@rust-bors
Copy link
Copy Markdown
Contributor

rust-bors Bot commented Mar 26, 2026

📌 Commit 23411ce has been approved by davidtwco

It is now in the queue for this repository.

@rust-bors rust-bors Bot added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 26, 2026
rust-bors Bot pushed a commit that referenced this pull request Mar 26, 2026
…uwer

Rollup of 5 pull requests

Successful merges:

 - #152757 (Add x86_64-unknown-linux-gnu{m,t}san target which enables {M,T}San by default)
 - #154354 (Add more tests for the parallel frontend)
 - #154088 (Reorder inline asm operands in pretty printer to satisfy grammar constraints)
 - #154407 (Link from `assert_matches` to `debug_assert_matches`)
 - #154420 (Use extended regex syntax)
@rust-bors rust-bors Bot merged commit 774370a into rust-lang:main Mar 26, 2026
11 checks passed
@rustbot rustbot added this to the 1.96.0 milestone Mar 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants