-
Notifications
You must be signed in to change notification settings - Fork 13.3k
delay expand macro bang when there has indeterminate path #121589
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
The right strategy here is for
|
What this PR does may be helpful too, but it's sort of luck based. Let's actually try to benchmark this solution. |
This comment has been minimized.
This comment has been minimized.
try to resolve under eager expander Fixes rust-lang#98291 I will attempt to clarify the root problem through several examples: Firstly, ```rs // rustc code.rs --edition=2018 macro_rules! wrap { () => { macro_rules! _a { () => { "Hello world" }; } }; } wrap!(); use _a as a; fn main() { format_args!(_a!()); } ``` The above case will compile successfully because `_a` is defined after the `wrap` expaned, ensuring `_a` can be resolved without any issues. And, ```rs // rustc code.rs --edition=2018 macro_rules! wrap { () => { macro_rules! _a { () => { "Hello world" }; } }; } wrap!(); use _a as a; fn main() { format_args!("{}", a!()); } ``` The above example will also compile successfully because the `parse_args` in `expand_format_args_impl` will return a value `MacroInput { fmtstr: Expr::Lit::Str, args: [Expr::MacroCall]}`. Since the graph for `args` will be build lately, `a` will eventually be resolved. However, in the case of: ```rs // rustc code.rs --edition=2018 macro_rules! wrap { () => { macro_rules! _a { () => { "Hello world" }; } }; } wrap!(); use _a as a; fn main() { format_args!(a!()); } ``` The result of `parse_args` is `MacroInput {fmtstr: Expr::Lit::Macro, args: [] }`, we attempt to expand `fmtstr` **eagerly** within `expr_to_spanned_string`. Although we have recorded `(root, _a)` into resolutions, `use _a as a` is an indeterminate import, which will not try to resolve under the conditions of `expander.monotonic = false`. Therefore, I've altered the strategy for resolving indeterminate imports, ensuring it will also resolve during eager expansion. This could be a significant change to the resolution infra. However, I think it's acceptable if the goal of avoiding resolution under eager expansion is to save time. r? `@petrochenkov`
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (8b0b849): comparison URL. Overall result: ❌ regressions - ACTION NEEDEDBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. Next Steps: If you can justify the regressions found in this try perf run, please indicate this with @bors rollup=never 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.
Binary sizeResultsThis 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.
Bootstrap: 644.654s -> 666.022s (3.31%) |
So, the current approach clearly won't work. |
Update: It will retry expand for |
ci is green. @rustbot ready |
{ | ||
return ExpandResult::Retry(()); | ||
} | ||
|
||
// Perform eager expansion on the expression. | ||
// We want to be able to handle e.g., `concat!("foo", "bar")`. | ||
let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr(); |
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.
Ideally, the whole fully_expand_fragment
would return Ready/Retry, but that's probably a much larger change.
The logic above is a good enough approximation.
@rustbot ready |
delay expand macro bang when there has indeterminate path Related rust-lang#98291 I will attempt to clarify the root problem through several examples: Firstly, ```rs // rustc code.rs --edition=2018 macro_rules! wrap { () => { macro_rules! _a { () => { "Hello world" }; } }; } wrap!(); use _a as a; fn main() { format_args!(_a!()); } ``` The above case will compile successfully because `_a` is defined after the `wrap` expaned, ensuring `_a` can be resolved without any issues. And, ```rs // rustc code.rs --edition=2018 macro_rules! wrap { () => { macro_rules! _a { () => { "Hello world" }; } }; } wrap!(); use _a as a; fn main() { format_args!("{}", a!()); } ``` The above example will also compile successfully because the `parse_args` in `expand_format_args_impl` will return a value `MacroInput { fmtstr: Expr::Lit::Str, args: [Expr::MacroCall]}`. Since the graph for `args` will be build lately, `a` will eventually be resolved. However, in the case of: ```rs // rustc code.rs --edition=2018 macro_rules! wrap { () => { macro_rules! _a { () => { "Hello world" }; } }; } wrap!(); use _a as a; fn main() { format_args!(a!()); } ``` The result of `parse_args` is `MacroInput {fmtstr: Expr::Lit::Macro, args: [] }`, we attempt to expand `fmtstr` **eagerly** within `expr_to_spanned_string`. Although we have recorded `(root, _a)` into resolutions, `use _a as a` is an indeterminate import, which will not try to resolve under the conditions of `expander.monotonic = false`. Therefore, I've altered the strategy for resolving indeterminate imports, ensuring it will also resolve during eager expansion. This could be a significant change to the resolution infra. However, I think it's acceptable if the goal of avoiding resolution under eager expansion is to save time. r? `@petrochenkov`
☀️ Try build successful - checks-actions |
This comment has been minimized.
This comment has been minimized.
Finished benchmarking commit (0af3b72): comparison URL. Overall result: ❌ regressions - no action neededBenchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf. @bors rollup=never 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)This benchmark run did not return any relevant results for this metric. 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.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 674.911s -> 674.04s (-0.13%) |
r=me with #121589 (comment) addressed. |
These commits modify the If this was unintentional then you should revert the changes before this PR is merged. |
@rustbot ready |
Thanks! |
☀️ Test successful - checks-actions |
Finished benchmarking commit (184c5ab): comparison URL. Overall result: no relevant changes - no action needed@rustbot label: -perf-regression Instruction countThis benchmark run did not return any relevant results for this metric. Max RSS (memory usage)This benchmark run did not return any relevant results for this metric. CyclesThis benchmark run did not return any relevant results for this metric. Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 675.369s -> 675.199s (-0.03%) |
Related #98291
I will attempt to clarify the root problem through several examples:
Firstly,
The above case will compile successfully because
_a
is defined after thewrap
expaned, ensuring_a
can be resolved without any issues.And,
The above example will also compile successfully because the
parse_args
inexpand_format_args_impl
will return a valueMacroInput { fmtstr: Expr::Lit::Str, args: [Expr::MacroCall]}
. Since the graph forargs
will be build lately,a
will eventually be resolved.However, in the case of:
The result of
parse_args
isMacroInput {fmtstr: Expr::Lit::Macro, args: [] }
, we attempt to expandfmtstr
eagerly withinexpr_to_spanned_string
. Although we have recorded(root, _a)
into resolutions,use _a as a
is an indeterminate import, which will not try to resolve under the conditions ofexpander.monotonic = false
.Therefore, I've altered the strategy for resolving indeterminate imports, ensuring it will also resolve during eager expansion. This could be a significant change to the resolution infra. However, I think it's acceptable if the goal of avoiding resolution under eager expansion is to save time.
r? @petrochenkov