-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Implement intial version of name resolution for items #231
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
@aochagavia here's the issue |
Code wise, I expect this to be handled by two queries: fn module_resolution_scope(module_id: ModuleId) -> Arc<ModuleResolutionScope> {
let crate_root = module_id.crate_root();
Arc::clone(crate_resolution_scope(crate_root)[module_id])
}
fn crate_resolution_scope(root_module: ModuleId)
-> Arc<FxHashMap<ModuleId, ModuleResolutionScope>>
{
let res = FxHashMap::default();
for id in root_module.submodules_transitive() {
res.insert(id, ModuleResolutionScope::default())
}
// run fixed point algo
loop {
}
} |
For the reference, the IntelliJ version of name resolution is implemented here: When implementing it, I used a strategy significantly different from that of rustc. Specifically, I was trying to avoid computing a global per-crate import map, which is costly to do on every modification. So, the implementation uses a somewhat naive approach of recursively resolving each path by walking the module tree and guarding (in a very ad hoc way) against cycles. I hope that a whole crate implementation would be feasible for rust-analyzer though: because we use salsa, we'll need to recompute import only when a set of items, defined in module, changes. Curiously enough, this should also work in the new versions of IntelliJ Rust, which implement OutOfCodeBlockModificationCounts, so cc @vlad20012 |
Is there a difference between |
No, it’s just that half way through I’ve came up with a better name and forgot to update the first half |
Going to write some code for this issue now |
236: WIP: Module name resolution r=matklad a=matklad work towards #231 Co-authored-by: Aleksey Kladov <[email protected]>
Status update: #236 added the basic infra. It, however, misses pretty crucial bits:
|
Status update: #245 implementing proper caching. Now, module name resolution results are not recomputed if you type inside a function. |
E-easy issue for folks how want to help out with nameres: fix this test. I think this should be handled in use tree deshugaring Here's the entry point to the code which actually resolves the import: https://github.com/rust-analyzer/rust-analyzer/blob/0cda188621b792265c957bdf4ac54af31cbc9947/crates/ra_hir/src/module/nameres.rs |
I have some time, so I might try and get that working now. |
This was more complicated that I expected, so I've had to leave it for now - I didn't realise we also don't handle resolving |
@DJMcNab sure! Though, I don’t think this should handle enum a specifically? Handling of enums would be another, E-less-easy task. |
For “fixed point iteration”, |
Well I mean that handling enum members is a similar mechanism to handling |
That's true, but this assumption is not used in desugaring of use trees step, and I think we need only to tweak desugaring itself to fix the test. Handling of enums would mean adding a new kind of |
316: Fix handling of nested self in paths r=matklad a=DJMcNab See #231 (comment). Co-authored-by: DJMcNab <[email protected]>
455: Import fixpoint loop for name resolution r=matklad a=flodiebold This implements reexports, so only the glob import part of #231 remains. Co-authored-by: Florian Diebold <[email protected]>
This has been pinned as the finishing work (glob imports) is very important for improving how well our current infrastructure works (required to bring the prelude into scope). |
Is there a general plan for tackling glob imports? |
@kjeremy during name resolution, we should remember the set of glob imports in the form of "module X glob-imports from Z". When we add an item to X's namespace, we should (recursively) fill Z's namespace. When a glob-dependency edge is introduced, we should should run the same procedure for existing items. |
778: Glob imports r=matklad a=flodiebold This implements glob imports, completing #231 :) Co-authored-by: Florian Diebold <[email protected]>
Fixed in #778? |
Or at least superceded by #723? |
Uh oh!
There was an error while loading. Please reload this page.
The goal here is to implement just enough name resolution to account for imports. In particular, we don't want to resolve references in items other then use tree. We also don't want to handle macros, this time.
For the final
API
, I think we can reuse existingModuleScope
, but it now should contain imported items as well, including those imported via*
imports. OTOH, we will use unresolvedModuleScope
for other things probably, so it's also find to introduce some kind ofResolvedModuleScope
thing.Here's I think a struct analgous to this
ResolvedModuledScoped
in rustc:https://github.com/rust-lang/rust/blob/6b9b97bd9b704f85f0184f7a213cc4d62bd9654c/src/librustc_resolve/lib.rs#L1047
How do we actually implement this? First of all, we need to keep in mind that in rust name resolution is tricky, because
use
items not only import things, but they also define them, so one import can affect another import. Here's a couple of fun examples:To deal with this, I think we need to use a kind of fixed point name resolution algorithm.
The algorithm should build a crate-wite module scope map:
It should start with an empty scope for each module. Then, all directly defined items should be added (what current ModuleScope is). Than, we should repeat the following algorithm until there are changes (that is, we use fixed point iteration):
ModuleResolutionScope
s computed so far*
import, which imports modulea
intob
,a
tob
a
tob
I
into modulea
I
toa
's scopea
, addI
there as wellThe "updating glob imports" bit is implemented here in rustc.
There's a bunch of existing tests we can adapt for this in Intellij: https://github.com/intellij-rust/intellij-rust/blob/9561daee8cfb24a0f8f753b9d9c3a696491428c3/src/test/kotlin/org/rust/lang/core/resolve/RsUseResolveTest.kt
The text was updated successfully, but these errors were encountered: