-
Notifications
You must be signed in to change notification settings - Fork 13.3k
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
base: master
Are you sure you want to change the base?
Conversation
This comment has been minimized.
This comment has been minimized.
3316632
to
c53bbd4
Compare
apparently it doesn't really use the asm parsing at present, so this may work?
c53bbd4
to
d30124a
Compare
There was a problem hiding this 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.
/// 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)>), | ||
} |
There was a problem hiding this comment.
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
.
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); | ||
} |
There was a problem hiding this comment.
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.
// 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(), | ||
}); | ||
} |
There was a problem hiding this comment.
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.
#[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() | ||
} |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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)
Some changes occurred in src/tools/rustfmt cc @rust-lang/rustfmt |
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 theasm!
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 anattributes: ast::AttrVec
field toRawAsmArg
.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 thatRawAsmArgs
would (it e.g. does not join information from multiple lines). This must have been an issue before?