Defer closure method receivers to be inferred from body - #159829
Defer closure method receivers to be inferred from body#159829chenyukang wants to merge 9 commits into
Conversation
|
Let's do a perf run: @bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…erence, r=<try> Defer closure method receivers to be inferred from body
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (e17ab16): comparison URL. Overall result: no relevant changes - no action neededBenchmarking means the PR may be perf-sensitive. Consider adding rollup=never if this change is not fit for rolling up. @rustbot label: -S-waiting-on-perf -perf-regression Instruction countThis perf run didn't have relevant results for this metric. Max RSS (memory usage)Results (secondary 0.8%)A less reliable metric. May be of interest, but not used to determine the overall result above.
CyclesResults (secondary 3.5%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 488.104s -> 486.507s (-0.33%) |
053cf2e to
8dd1996
Compare
|
r? types |
|
I used this issue as a chance to learn more about how type checking and type inference work in rustc. I experimented with deferring method-call resolution until later constraints from the closure become available. Then I found two consequences:
so I don't think my current approach is ideal: it introduces additional deferred state, make the code more complicated becaused of a relatively narrow inference case. I would appreciate feedback from reviewers who are more familiar with this part. |
|
Hmm... there are various similar issues with type inference within closures when the closure doesn't have an expectation (e.g. by being inline in another method call that constrains the closure). Can we generally improve the situation for closures somehow? Delay the entire closure's body typeck until after its parent is typecked. So less fixed-point and more "tree of child bodies to typeck". Or do we need the closure body typeck in order for other code in the parent to behave? |
yes, follow your idea we can resolve other issues, such as #63702 and #106138 (both tests are added into this PR). the current approach creates the closure signature as usual, but delays checking the body when:
I need more tweak on the code, but generally seems the direction works out |
This comment has been minimized.
This comment has been minimized.
|
the latest commit remove the |
This comment has been minimized.
This comment has been minimized.
b7f4faa to
91b7704
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
I'm gonna bring this up as a topic in next week's types team meeting. You're very welcome to join if you want. Gonna mainly talk about the high-level change and how it affects inference and what the issues with it are. |
emm, there is a fail in #159829 (comment) the code can be minized into: struct Pattern;
fn visit_pattern(_: &Pattern) {}
fn main() {
let visit_subpattern = |pattern| visit_pattern(pattern);
let boxed_pattern = Box::new(Pattern);
// The body constrains `pattern` to `&Pattern`, so this applies a deref coercion.
visit_subpattern(&boxed_pattern);
visit_subpattern(&Pattern);
}Before this change, the closure body is checked first. The call to With deferred body checking, the first invocation is checked first and fixes the unresolved closure parameter to I haven't figured out a solution for this case. |
|
The job Click to see the possible cause of the failure (guessed by this bot) |
Fixes #76112
Defer method confirmation for unresolved intermediate receiver types until the enclosing body has added its inference constraints.
r? @ghost