-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Change the format_args! macro expansion for temporaries #12349
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
Conversation
ast::BindByRef(ast::MutImmutable)); | ||
let arm = self.ecx.arm(pat.span, ~[pat], body); | ||
self.ecx.expr_match(pat.span, arg, ~[arm]) | ||
}) |
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 looks like it translates where the right-most expression being formatted is evaluated first and then the left-most expression is evaluated last? I think we should keep the order of evaluation from left-to-right.
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.
Good catch.
In the past I've heard of codegen blowup whenever we're dealing with match statements. Do you have any numbers showing the codegen impact of this strategy vs the When I was first writing the Additionally, I'm worried about the codegen time with lots of nested match statements, so could you test the impact of 5 or more arguments as well? |
Also, what you were looking for in the original ticket is: static PRECOMPILED_FORMAT_STRING = ...;
match foo {
ref foo_addr => {
let arguments: &fmt::Arguments = unsafe { /* do things with foo_addr */ };
fmt::writeln(logger, arguments)
}
} But the patch translated the macro to: match foo {
ref foo_addr => {
static PRECOMPILED_FORMAT_STRING = ...;
let arguments: &fmt::Arguments = unsafe { /* do things with foo_addr */ };
fmt::writeln(logger, arguments)
}
} I had some mysterious errors when compiling |
Ah indeed that's fine, it doesn't matter so much where the format string goes as long as it's in its own scope. |
Alas, 10k lines of
|
Will matching against tuples be a improvement? match (x, y, z) {
(ref x_addr, ref y_addr, ref z_addr) => {
...
}
} |
That changes the semantics (it moves |
Ah, of course. I guess watching out for the move semantics of rust still isn't a knee jerk reflex for me, yet. |
Those codegen times are worrying, although they're not quite as bad as I expected. I expect build times to increase as a result of this patch, but perhaps the semantic differences are better such that the build time increase is worth it for now. |
I'm fiddling with the match unrolling idea. Hope it'll achieve something. |
I tried to construct the following snippet: let (idents, args) = get id and expression list somehow;
let pat = self.ecx.pat(self.fmtsp, ast::PatVec(
idents.map(|&x| self.ecx.pat_ident(self.fmtsp, x)),
None, ~[]));
let arm = self.ecx.arm(self.fmtsp, ~[pat], body);
let exp = self.ecx.expr_vec_slice(
self.fmtsp,
args.map(|&x| self.ecx.expr_addr_of(self.fmtsp, x)));
self.ecx.expr_match(self.fmtsp, exp, ~[arm]) It seems to work only for |
Never mind, I think I figured it out. Testing locally and benchmarking now. |
Some(result))); | ||
// Chop the argument list into 8-elements chunks and each chunk | ||
// becomes a match head to avoid deeply nested match expression. | ||
// The size of 8 is quite arbitrary though. |
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.
Why not just all of them at once?
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.
Can I? Isn't a tuple able to have 12 elements at most?
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.
No, they're arbitrarily large, but the stdlib only has traits for some convenient methods up to 12 (because if you're using larger tuples you've got bigger problems than the sugar that those traits provide).
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.
Then I shall just shovel them together.
The compiling time certainly improved.
|
I'm a little surprised that the tuple method worked, but nice thinking! Those numbers don't look too bad to me at all! |
Comments addressed, commits squashed and rebased. It should be ready for merging. |
amazing results, nice work! |
Looks like this needs a |
It is now |
Some(result))) | ||
let body = self.ecx.expr_block(self.ecx.block(self.fmtsp, lets, | ||
Some(result))); | ||
let pat = self.ecx.pat(self.fmtsp, ast::PatTup(pats)); |
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.
Can you put a comment about what and why is going on here? (i.e. why we need a match, and why that match needs to be one big tuple.)
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.
Certainly.
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.
Done. Is it a little bit verbose?
Currently, the format_args! macro and its downstream macros in turn expand to series of let statements, one for each of its arguments, and then the invocation of the macro function. If one or more of the arguments are RefCell's, the enclosing statement for the temporary of the let is the let itself, which leads to scope problem. This patch changes let's to a match expression. Closes rust-lang#12239.
r? @huonw |
Currently, the format_args! macro and its downstream macros in turn expand to series of let statements, one for each of its arguments, and then the invocation of the macro function. If one or more of the arguments are RefCell's, the enclosing statement for the temporary of the let is the let itself, which leads to scope problem. This patch changes let's to a match expression. Closes #12239.
internal: Publish universal VSIX to make VS happy
…olors, r=xFrednet style: sync GitHub Corner colors fixes rust-lang#12349. *Please write a short comment explaining your change (or "none" for internal only changes)* changelog: sync site GitHub Corner colors
Currently, the format_args! macro and its downstream macros in turn
expand to series of let statements, one for each of its arguments, and
then the invocation of the macro function. If one or more of the
arguments are RefCell's, the enclosing statement for the temporary of
the let is the let itself, which leads to scope problem. This patch
changes let's to a match expression.
Closes #12239.