Repository navigation
Remove repeated work from lowering and name resolution in long chains of bindings - #294
Merged
Merged
Conversation
- Test cycles of three or more declarations, one cycle reaching another, mutually recursive inline functions, a constant that cycles through a function, and a declaration reached from a cycle more than once - Test names that are a symbol, a type, or both, in either position - Drop the redundant `placed` vector from `group_symbols` and count the rounds once - Keep each declaration's index in its visit instead of looking it up again - Shorten the fallback lookup in path resolution
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Several compiler passes redid work for every binding or declaration in a chain, which made them quadratic or worse in its length and made a few tests much slower than they need to be. This removes that repeated work.
Changes
rue-hir/src/lower.rs)group_symbolsis now a topological layering in a single pass, instead of repeatedly scanning for symbols whose dependencies are ready.lower_let_stmtsnow drains the leading statements at once rather than callingremove(0)in a loop.check_recursion.rs)tests/symbols/invalid_recursionnow covers that case.const X = Y + Z; const Y = X; const Z = X;) is now reported once, where it used to be reported twice.compile/path.rs)compiler.rs)symbol_type_inwalks the scope chain only for symbols whose type is overridden in some scope, which is tracked inpush_mappings.exports.rs)used_exportsnow shares one visited set across all exports, so types reached from one signature aren't walked again from the next.long_runs_of_bindings_are_grouped, which compiles 1000 chained bindings on the small stack (about 1.5s in debug).tests/symbols/recursion_cycles: cycles of three or more, one cycle reaching another, mutually recursive inline functions, a constant that cycles through a function, and the deduplicated case above.tests/symbols/symbol_and_type_names, which covers a type where a symbol is expected, a symbol where a type is expected, and a name that is both.Timings
These are debug builds, compared against
65b2f24d. They were measured together with #295, but these tests only touch the code changed here:chains_beyond_the_lowering_limit_are_an_errordeep_types_are_checkedlong_chains_of_bindings_are_followedWith the debug CLI, a function containing 300 chained bindings went from 71s to 0.35s.
Not done here
group_symbolsis still quadratic in the worst case.DependencyGraph::dependenciesreturns transitive sets, so a chain of n bindings has about n²/2 edges. In a debug CLI, 1000 bindings of the formlet x{i+1} = x{i} * x{i} + a;take about 35s, against more than 8 minutes onmain. Making it linear would mean computing rounds from direct edges, carrying them through the symbols that aren't in the set (Grouping a long chain of bindings is still quadratic #296).