-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Rewrite and refactor format_args!() builtin macro. #100996
Conversation
@Alexendoo I saw you've sent a few PRs touching this code recently. In case you were planning to send more of those, be aware I'm refactoring the entire thing. ^^ |
c8de89a
to
9a62d8d
Compare
Thanks for the heads up! The main one I was planning to do was #101000 so that is handy 😄 |
This comment was marked as outdated.
This comment was marked as outdated.
16441de
to
d813966
Compare
This comment was marked as outdated.
This comment was marked as outdated.
746295f
to
46505b5
Compare
@bors try @rust-timer queue |
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
⌛ Trying commit 46505b5ee3d606a643d19a2322bff8cb52dce760 with merge f0b6903fbee6a3632b1b3059d24324e030e0430b... |
This comment was marked as outdated.
This comment was marked as outdated.
💔 Test failed - checks-actions |
@bors try |
⌛ Trying commit fe3eb3dcf6547820441af4c4f8fcb4bbc22b1b4e with merge 83ba636722d8a682cc06767b5b8577368ad42ed9... |
With efficient lookup through a hash map.
13d187a
to
20bb600
Compare
@bors r=estebank |
⌛ Testing commit 20bb600 with merge 87338df73726f7517d94a980dd56de09bf6cc975... |
💔 Test failed - checks-actions |
Weird, the relevant logs seem to be empty. @bors retry |
☀️ Test successful - checks-actions |
Finished benchmarking commit (d6734be): comparison URL. Overall result: ❌✅ regressions and improvements - ACTION NEEDEDNext Steps: If you can justify the regressions found in this perf run, please indicate this with @rustbot label: +perf-regression Instruction countThis is a highly reliable metric that was used to determine the overall result at the top of this comment.
Max RSS (memory usage)ResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
CyclesResultsThis is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.
Footnotes |
@rustbot label: +perf-regression-triaged |
…-ou-se Fix `format_args` capture for macro expanded format strings Since rust-lang#100996 `format_args` capture for macro expanded strings aren't prevented when the span of the expansion points to a string literal, e.g. ```rust // not a terribly realistic example, but also happens for proc_macros that set // the span of the output to an input str literal, such as indoc macro_rules! x { ($e:expr) => { $e } } fn main() { let a = 1; println!(x!("{a}")); } ``` The tests didn't catch it as the span of `concat!()` points to the macro invocation r? `@m-ou-se`
…-ou-se Fix `format_args` capture for macro expanded format strings Since rust-lang#100996 `format_args` capture for macro expanded strings aren't prevented when the span of the expansion points to a string literal, e.g. ```rust // not a terribly realistic example, but also happens for proc_macros that set // the span of the output to an input str literal, such as indoc macro_rules! x { ($e:expr) => { $e } } fn main() { let a = 1; println!(x!("{a}")); } ``` The tests didn't catch it as the span of `concat!()` points to the macro invocation r? `@m-ou-se`
This is a near complete rewrite of
compiler/rustc_builtin_macros/src/format.rs
.This gets rid of the massive unmaintanable
Context
struct, and splits the macro expansion into three parts:parse_args
will parse the(literal, arg, arg, name=arg, name=arg)
syntax, but doesn't parse the template (the literal) itself.make_format_args
will parse the template, the format options, resolve argument references, produce diagnostics, and turn the whole thing into aFormatArgs
structure.expand_parsed_format_args
will turn thatFormatArgs
structure into the expression that the macro expands to.In other words, the
format_args
builtin macro used to be a hard-to-maintain 'single pass compiler', which I've split into a three phase compiler with a parser/tokenizer (step 1), semantic analysis (step 2), and backend (step 3). (It's compilers all the way down. ^^)This can serve as a great starting point for #99012, which will only need to change the implementation of 3, while leaving step 1 and 2 unchanged.
It also makes rust-lang/compiler-team#541 easier, which could then upgrade the new
FormatArgs
struct to anast
node and remove step 3, moving that step to later in the compilation process.It also fixes a few diagnostics bugs.
This also significantly reduces the amount of generated code for cases with arguments in non-default order without formatting options, like
"{1} {0}"
or"{a} {}"
, etc.