-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Version 0.3.1995
rust-analyzer process spins out of control in macOS VSCode
#17409
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
Comments
It looks like @roife even predicted this case in #17381 (comment) ... but reading the PR thread, it's not clear to me if something was done to prevent that case. 🤔 |
I opened #17412 with one possible way to resolve this. |
For the example in #17381 (comment):
For rootA, we can just consider However, for more complex situations, we might need to consider in graph, such as computing the dominator node as the common ancestor in the graph. (I haven't figured out yet if there will be such complex cases.) |
#17412 papers over this but we should fix the map to not contain cycles |
fix: add a breaker to avoid infinite loops from source root cycles See #17409 This patch prevents infinite looping from cycles by giving up if the number of source roots checked for a config value reaches the total number of source roots. Alternative more precise options include creating a set of all source roots visited and giving up as soon as a cycle is encountered, but I wasn't sure how costly an allocation would be here for performance. Can confirm that locally this fixes the problem for me.
Should we use SourceRoot as the location for |
After reviewing However we may only take pkg_root into consideration🤔. I'll try to fix it. |
Hi @davidhewitt, is the project you are working on open-source? A reproducible example of the bug would be really helpful 🙏 Alternatively, I want to know if a configuration like this exists in the project? [lib] # or doc, etc.
path = "main.rs" |
Yep all open source - the PyO3 repo :) I like workspaces a lot, so I have a few related checkouts also included as workspace folders:
|
I cannot reproduce this bug on my machine. It's a bit strange. 🤔 |
In case it helps, relevant settings: // pyo3.code-workspace
{
"folders": [
{
"path": "pyo3"
},
{
"path": "pyo3-scratch"
},
{
"path": "setuptools-rust"
},
{
"path": "pyo3/pyo3-benches"
},
{
"path": "pythonize"
}
],
"settings": {
"rust-analyzer.cargo.features": [
"pyo3/full"
],
"rust-analyzer.interpret.tests": true,
"rust-analyzer.testExplorer": true,
}
} ... I don't think I've got any other settings which are relevant (I took a quick scan through my user settings). |
Thanks, I am now able to reproduce it successfully. |
I have figured out the cause of the issue:
Maybe when calculating @Veykril, could you provide some suggestions? update: An odd situation might still lead to the issue. Consider the following project structure: A/B/C. Assuming C uses A/a.rs as an extra target, so A/B/C/ and A/ are grouped into one SourceRoot. Meanwhile, project B/ is placed into a separate new SourceRoot. If we open both projects A, B, and C, it is still a circle. |
We should just try to recognize cycles and discard the cycle inducing edge. The source root system isn't ideal for this lookup in general but its the best we have right now hence why we use it. |
fix: ensure there are no cycles in the source_root_parent_map See #17409 We can view the connections between roots as a graph. The problem is that this graph may contain cycles, so when adding edges, it is necessary to check whether it will lead to a cycle. Since we ensure that each node has at most one outgoing edge (because each SourceRoot can have only one parent), we can use a disjoint-set to maintain the connectivity between nodes. If an edge’s two nodes belong to the same set, they are already connected. Additionally, this PR includes the following three changes: 1. Removed the workaround from #17409. 2. Added an optimization: If `map.contains_key(&SourceRootId(*root_id as u32))`, we can skip the current loop iteration since we have already found its parent. 3. Modified the inner loop to iterate in reverse order with `roots[..idx].iter().rev()` at line 319. This ensures that if we are looking for the parent of `a/b/c`, and both `a` and `a/b` meet the criteria, we will choose the longer match (`a/b`).
Followup of #17378 - as similar to #17378 (comment) I am also still experiencing the same issue of high CPU on version
0.3.1995
(and also onmain
at fa486e6).Doing some debugging locally, I find that the infinite loop mentioned in #17378 (comment) seems to still the culprit.
I inserted a debug print:
... and this is my output:
So I think the patch in #17381 is probably insufficient because here I don't have a source root with a parent of itself; instead somehow I have a cycle between two source roots 202 and 200.
I guess there's brute force solutions to prevent this infinite loop like bailing out if the number of iterations ever exceeds the total size of
source_root_parent_map
. Or maybe there's similar ideas to #17381 that can prune this graph.... I would go further and submit a patch but I really need to go to sleep, sorry 🙈
cc @Veykril @roife
The text was updated successfully, but these errors were encountered: