Description
So I have an idea for how to improve performance in cases like html5ever where there are tons of borrows in scope at certain points. Right now, we have a pretty naive algorithm that implements over all borrows in scope:
rust/src/librustc_mir/borrow_check/path_utils.rs
Lines 40 to 52 in 18925de
I think we would do better if we stored the "borrows in scope" organized by the "root local" of the borrow:
rust/src/librustc_mir/borrow_check/place_ext.rs
Lines 20 to 23 in 18925de
In fact, I think we could do a "quick hack" to make this work. The BorrowSet
already has an index of borrow indices based on their "root locals":
rust/src/librustc_mir/borrow_check/borrow_set.rs
Lines 44 to 45 in 18925de
So what we can do is to modify each_borrow_involving_path
. Instead of taking an iterator over borrows in scope, it would take some sort of is_borrow_in_scope: impl Fn(BorrowIndex) -> bool
function. It would then find the root local (if any) of the access path, find all borrows that apply to that root local, and iterate over those, testing if each of them is in scope.
We could make this more efficient in many ways -- e.g., using bitsets and things -- but this basic change should already eliminate some of the horrible O(n^2)
behavior.