Skip to content

split asm! parsing and validation #140490

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 18, 2025
Merged

Conversation

folkertdev
Copy link
Contributor

@folkertdev folkertdev commented Apr 29, 2025

This PR splits asm! parsing and validation into two separate steps.

The parser constructs a Vec<RawAsmArg>, with each element corresponding to an argument to one of the asm! macros.
The validation then checks things like ordering of arguments or that options are not provided twice.

The motivation is #140279, which wants to add #[cfg(...)] support to these arguments. This support can now be added in a straightforward way by adding an attributes: ast::AttrVec field to RawAsmArg.

An extra reason for this split is that rustfmt probably wants to format the assembly at some point (currently that appears to be stubbed out, and the formatting is unstable rust-lang/style-team#152).

r? @ghost (just want to look at CI for now)

cc @ytmimi we discussed asm formatting a little while ago in rust-lang/rustfmt#6526. Am I correct in assuming that AsmArgs does not give enough information for formatting, but that RawAsmArgs would (it e.g. does not join information from multiple lines). This must have been an issue before?

try-job: aarch64-apple

@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 Apr 29, 2025
@rust-log-analyzer

This comment has been minimized.

@folkertdev folkertdev force-pushed the asm-parser-changes branch 2 times, most recently from c53bbd4 to d30124a Compare April 30, 2025 09:33
Copy link
Contributor Author

@folkertdev folkertdev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

r? @Amanieu (I suspect you're most familiar with this code).

I've left some inline comments to hopefully make reviewing this easier.

Comment on lines 21 to 33
/// An argument to one of the `asm!` macros. The argument is syntactically valid, but is otherwise
/// not validated at all.
pub struct RawAsmArg {
pub kind: RawAsmArgKind,
pub span: Span,
}

pub enum RawAsmArgKind {
Template(P<ast::Expr>),
Operand(Option<Symbol>, ast::InlineAsmOperand),
Options(Vec<(Symbol, ast::InlineAsmOptions, Span, Span)>),
ClobberAbi(Vec<(Symbol, Span)>),
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main idea of this PR is to parse into these data structures first, and then validate them in to the pre-existing AsmArgs.

Comment on lines +83 to +97
Ok(Some(if eat_operand_keyword(p, exp!(In), asm_macro)? {
let reg = parse_reg(p)?;
if p.eat_keyword(exp!(Underscore)) {
let err = dcx.create_err(errors::AsmUnderscoreInput { span: p.token.span });
return Err(err);
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a messy diff, but this is just the old operand parsing code extracted into its own function. No changes were made here.

Comment on lines 493 to 502
// NOTE: should this be handled during validation instead?
if !asm_macro.is_supported_option(option) {
// Tool-only output
p.dcx().emit_err(errors::AsmUnsupportedOption {
span,
symbol: exp.kw,
full_span,
macro_name: asm_macro.macro_name(),
});
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to emit this error later, but that changes some of the error messages. For example currently global_asm emits a (non-fatal) warning here when it encounters an unsupported option (e.g. noreturn) even if the remainder of its argument list causes a parse error. By emitting the unsupported option error later, no error is emitted if the argument causes a parse error.

I can add that, but not changing the error output at all in this PR seemed like a good idea to me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd at least be worth adding a FIXME(..) then about this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just made the change in a separate commit. I think this is the right call, and the error message change is acceptable: the user is now no longer hitting a "this option is not supported for this flavor of asm" error when there is a parse error in the list of options. When the parse error is resolved, of course the unsupported error is emitted.

Comment on lines 6 to 11
#[allow(dead_code)]
pub(crate) fn parse_asm(context: &RewriteContext<'_>, mac: &ast::MacCall) -> Option<AsmArgs> {
pub(crate) fn parse_asm(
context: &RewriteContext<'_>,
mac: &ast::MacCall,
) -> Option<Vec<RawAsmArg>> {
let ts = mac.args.tokens.clone();
let mut parser = super::build_parser(context, ts);
parse_asm_args(&mut parser, mac.span(), ast::AsmMacro::Asm).ok()
parse_raw_asm_args(&mut parser, mac.span(), ast::AsmMacro::Asm).ok()
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function is defined, but currently not used by rustfmt. I'm assuming that it will be if/when we start formatting the asm! operands, and that RawAsmArg can actually be used for that, while AsmArgs does not have enough information to faithfully reproduce the user's syntax.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rust-lang/rustfmt#5191, an old PR for asm! formatting, does a bunch of its own parsing that I think would not be needed with RawAsmArg.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Speaking with my t-style hat, we do not yet have any established formatting rules for asm!, just a general desire to do so with some fairly concrete thoughts on what those rules would look like.

Speaking with my t-rustfmt hat, this split does look like it'll make our lives much easier to handle asm! formatting whenever t-style does finalize the style rules for it, as it does seem to me this would allow us to avoid needing the custom parsing within rustfmt (though Yacin please correct me if I'm missing something)

@folkertdev folkertdev marked this pull request as ready for review April 30, 2025 10:43
@rustbot
Copy link
Collaborator

rustbot commented Apr 30, 2025

Some changes occurred in src/tools/rustfmt

cc @rust-lang/rustfmt

@folkertdev
Copy link
Contributor Author

#140367, specifically the last commit (currently feddf14) shows how #[cfg(...)] can be built on top of this change.

Copy link
Contributor

@traviscross traviscross left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some nits; seems OK overall to me. Along with the nits addressed and @Amanieu's review, r=me.

Comment on lines 493 to 502
// NOTE: should this be handled during validation instead?
if !asm_macro.is_supported_option(option) {
// Tool-only output
p.dcx().emit_err(errors::AsmUnsupportedOption {
span,
symbol: exp.kw,
full_span,
macro_name: asm_macro.macro_name(),
});
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'd at least be worth adding a FIXME(..) then about this.

@folkertdev folkertdev force-pushed the asm-parser-changes branch 3 times, most recently from 6c50ded to 16880b2 Compare May 3, 2025 10:22
pub struct AsmArgs {
/// An argument to one of the `asm!` macros. The argument is syntactically valid, but is otherwise
/// not validated at all.
pub struct RawAsmArg {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be renamed to AsmArgs (and in other places too).

pub enum RawAsmArgKind {
Template(P<ast::Expr>),
Operand(Option<Symbol>, ast::InlineAsmOperand),
Options(Vec<(Symbol, ast::InlineAsmOptions, Span, Span)>),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this 4-tuple be replaced with a struct.

@folkertdev folkertdev force-pushed the asm-parser-changes branch from 16880b2 to 2e788d1 Compare May 17, 2025 21:53
@rust-log-analyzer

This comment has been minimized.

@folkertdev folkertdev force-pushed the asm-parser-changes branch from 2e788d1 to d91e3d3 Compare May 17, 2025 22:09
@Amanieu
Copy link
Member

Amanieu commented May 17, 2025

r=me once CI passes

@traviscross
Copy link
Contributor

@bors r=Amanieu,traviscross rollup

@bors
Copy link
Collaborator

bors commented May 18, 2025

📌 Commit d91e3d3 has been approved by Amanieu,traviscross

It is now in the queue for this repository.

@bors bors 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 May 18, 2025
fmease added a commit to fmease/rust that referenced this pull request May 18, 2025
…manieu,traviscross

split `asm!` parsing and validation

This PR splits `asm!` parsing and validation into two separate steps.

The parser constructs a `Vec<RawAsmArg>`, with each element corresponding to an argument to one of the `asm!` macros.
The validation then checks things like ordering of arguments or that options are not provided twice.

The motivation is rust-lang#140279, which wants to add `#[cfg(...)]` support to these arguments. This support can now be added in a straightforward way by adding an `attributes: ast::AttrVec` field to `RawAsmArg`.

An extra reason for this split is that `rustfmt` probably wants to format the assembly at some point (currently that appears to be stubbed out, and the formatting is unstable rust-lang/style-team#152).

r? `@ghost` (just want to look at CI for now)

cc `@ytmimi` we discussed asm formatting a little while ago in rust-lang/rustfmt#6526. Am I correct in assuming that `AsmArgs` does not give enough information for formatting, but that `RawAsmArgs` would (it e.g. does not join information from multiple lines). This must have been an issue before?
fmease added a commit to fmease/rust that referenced this pull request May 18, 2025
…manieu,traviscross

split `asm!` parsing and validation

This PR splits `asm!` parsing and validation into two separate steps.

The parser constructs a `Vec<RawAsmArg>`, with each element corresponding to an argument to one of the `asm!` macros.
The validation then checks things like ordering of arguments or that options are not provided twice.

The motivation is rust-lang#140279, which wants to add `#[cfg(...)]` support to these arguments. This support can now be added in a straightforward way by adding an `attributes: ast::AttrVec` field to `RawAsmArg`.

An extra reason for this split is that `rustfmt` probably wants to format the assembly at some point (currently that appears to be stubbed out, and the formatting is unstable rust-lang/style-team#152).

r? ``@ghost`` (just want to look at CI for now)

cc ``@ytmimi`` we discussed asm formatting a little while ago in rust-lang/rustfmt#6526. Am I correct in assuming that `AsmArgs` does not give enough information for formatting, but that `RawAsmArgs` would (it e.g. does not join information from multiple lines). This must have been an issue before?
bors added a commit to rust-lang-ci/rust that referenced this pull request May 18, 2025
Rollup of 7 pull requests

Successful merges:

 - rust-lang#140113 (Add per page TOC in the `rustc` book)
 - rust-lang#140490 (split `asm!` parsing and validation)
 - rust-lang#140924 (Make some `f32`/`f64` tests also run in const-context)
 - rust-lang#141045 ([win][arm64] Remove 'Arm64 Hazard' undocumented MSVC option and instead disable problematic test)
 - rust-lang#141071 (Enable [behind-upstream] triagebot option for rust-lang/rust)
 - rust-lang#141132 (Use `crate::` prefix for root macro suggestions)
 - rust-lang#141139 (Fix Rust for Linux ping group label)

r? `@ghost`
`@rustbot` modify labels: rollup
@fmease
Copy link
Member

fmease commented May 18, 2025

Failure in rollup: #141209 (comment) (aarch64-apple).
@bors r-

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 18, 2025
@fmease
Copy link
Member

fmease commented May 18, 2025

Tangential note: Could you please squash some of the micro commits? Thanks!

@folkertdev folkertdev force-pushed the asm-parser-changes branch from d91e3d3 to 26e3a50 Compare May 18, 2025 09:29
@folkertdev
Copy link
Contributor Author

Right, of course. I updated the tests based on what I can run locally, I think that covers all of the changes but we should run the try job to make sure. I also squashed/reordered some commits.

@rustbot ready

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 18, 2025
@traviscross
Copy link
Contributor

@bors try

bors added a commit to rust-lang-ci/rust that referenced this pull request May 18, 2025
split `asm!` parsing and validation

This PR splits `asm!` parsing and validation into two separate steps.

The parser constructs a `Vec<RawAsmArg>`, with each element corresponding to an argument to one of the `asm!` macros.
The validation then checks things like ordering of arguments or that options are not provided twice.

The motivation is rust-lang#140279, which wants to add `#[cfg(...)]` support to these arguments. This support can now be added in a straightforward way by adding an `attributes: ast::AttrVec` field to `RawAsmArg`.

An extra reason for this split is that `rustfmt` probably wants to format the assembly at some point (currently that appears to be stubbed out, and the formatting is unstable rust-lang/style-team#152).

r? `@ghost` (just want to look at CI for now)

cc `@ytmimi` we discussed asm formatting a little while ago in rust-lang/rustfmt#6526. Am I correct in assuming that `AsmArgs` does not give enough information for formatting, but that `RawAsmArgs` would (it e.g. does not join information from multiple lines). This must have been an issue before?

try-job: aarch64-apple
@bors
Copy link
Collaborator

bors commented May 18, 2025

⌛ Trying commit 26e3a50 with merge 4a6811fe29e2641bcf7a28ff3c652311b32be60e...

@bors
Copy link
Collaborator

bors commented May 18, 2025

☀️ Try build successful - checks-actions
Build commit: 4a6811f (4a6811fe29e2641bcf7a28ff3c652311b32be60e)

@traviscross
Copy link
Contributor

@bors r=Amanieu,traviscross rollup

@bors
Copy link
Collaborator

bors commented May 18, 2025

📌 Commit 26e3a50 has been approved by Amanieu,traviscross

It is now in the queue for this repository.

@bors bors 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 May 18, 2025
fmease added a commit to fmease/rust that referenced this pull request May 18, 2025
…manieu,traviscross

split `asm!` parsing and validation

This PR splits `asm!` parsing and validation into two separate steps.

The parser constructs a `Vec<RawAsmArg>`, with each element corresponding to an argument to one of the `asm!` macros.
The validation then checks things like ordering of arguments or that options are not provided twice.

The motivation is rust-lang#140279, which wants to add `#[cfg(...)]` support to these arguments. This support can now be added in a straightforward way by adding an `attributes: ast::AttrVec` field to `RawAsmArg`.

An extra reason for this split is that `rustfmt` probably wants to format the assembly at some point (currently that appears to be stubbed out, and the formatting is unstable rust-lang/style-team#152).

r? `@ghost` (just want to look at CI for now)

cc `@ytmimi` we discussed asm formatting a little while ago in rust-lang/rustfmt#6526. Am I correct in assuming that `AsmArgs` does not give enough information for formatting, but that `RawAsmArgs` would (it e.g. does not join information from multiple lines). This must have been an issue before?

try-job: aarch64-apple
bors added a commit to rust-lang-ci/rust that referenced this pull request May 18, 2025
Rollup of 10 pull requests

Successful merges:

 - rust-lang#127013 (Add `f16` formatting and parsing)
 - rust-lang#138940 (Stabilize the avx512 target features)
 - rust-lang#140154 (Cygwin support in rustc)
 - rust-lang#140490 (split `asm!` parsing and validation)
 - rust-lang#140628 (std: stop using TLS in signal handler)
 - rust-lang#140746 (name resolution for guard patterns)
 - rust-lang#140926 (Return value of coroutine_layout fn changed to Result with LayoutError)
 - rust-lang#141127 (bump windows crate for compiler,bootstrap and tools)
 - rust-lang#141214 (Miri subtree update)
 - rust-lang#141218 (gvn: avoid creating overlapping assignments)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this pull request May 18, 2025
Rollup of 8 pull requests

Successful merges:

 - rust-lang#138940 (Stabilize the avx512 target features)
 - rust-lang#140490 (split `asm!` parsing and validation)
 - rust-lang#140628 (std: stop using TLS in signal handler)
 - rust-lang#140746 (name resolution for guard patterns)
 - rust-lang#140926 (Return value of coroutine_layout fn changed to Result with LayoutError)
 - rust-lang#141127 (bump windows crate for compiler,bootstrap and tools)
 - rust-lang#141214 (Miri subtree update)
 - rust-lang#141218 (gvn: avoid creating overlapping assignments)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 2f0c6e2 into rust-lang:master May 18, 2025
7 checks passed
@rustbot rustbot added this to the 1.89.0 milestone May 18, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request May 18, 2025
Rollup merge of rust-lang#140490 - folkertdev:asm-parser-changes, r=Amanieu,traviscross

split `asm!` parsing and validation

This PR splits `asm!` parsing and validation into two separate steps.

The parser constructs a `Vec<RawAsmArg>`, with each element corresponding to an argument to one of the `asm!` macros.
The validation then checks things like ordering of arguments or that options are not provided twice.

The motivation is rust-lang#140279, which wants to add `#[cfg(...)]` support to these arguments. This support can now be added in a straightforward way by adding an `attributes: ast::AttrVec` field to `RawAsmArg`.

An extra reason for this split is that `rustfmt` probably wants to format the assembly at some point (currently that appears to be stubbed out, and the formatting is unstable rust-lang/style-team#152).

r? ``@ghost`` (just want to look at CI for now)

cc ``@ytmimi`` we discussed asm formatting a little while ago in rust-lang/rustfmt#6526. Am I correct in assuming that `AsmArgs` does not give enough information for formatting, but that `RawAsmArgs` would (it e.g. does not join information from multiple lines). This must have been an issue before?

try-job: aarch64-apple
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.

8 participants