Stream: t-compiler/rust-analyzer

Topic: resolution in the hir_def crate


kev (Dec 11 2020 at 12:53, on Zulip):

@matklad I noticed the resolver.rs and nameres.rs were in the hir_def crate, whereas I was under the impression that they were done on the CST. So would logically be in, maybe the syntax crate. Can you see the fault in my logic ?

matklad (Dec 11 2020 at 12:55, on Zulip):

I think so

matklad (Dec 11 2020 at 12:55, on Zulip):

We intentionally don't use CST for name resolution

matklad (Dec 11 2020 at 12:55, on Zulip):

The reason for that is that CST is very volatile -- even adding whitespace invalidates CST

matklad (Dec 11 2020 at 12:56, on Zulip):

So that's why we have that item-tree layer in between, which you've looked at previously -- after typing, we invalidate CST and recmopute item tree

kev (Dec 11 2020 at 12:57, on Zulip):

Oh so the CST is only for parsing and then you lower it to hir, to do resolution and type checking?

matklad (Dec 11 2020 at 12:57, on Zulip):

item tree, however, probably is the same (unless you indeed add new top-level item). So we can skip re-computing name resolution results, as they don't depend on cst directly

matklad (Dec 11 2020 at 12:57, on Zulip):

@kev right!

Jonas Schievink [he/him] (Dec 11 2020 at 12:57, on Zulip):

Also note that the location of those files doesn't necessarily mean that they don't use data structures from a different crate – nameres used to use the CST, but was still in the hir_def crate

kev (Dec 11 2020 at 12:58, on Zulip):

Oh right that's a good point

matklad (Dec 11 2020 at 12:58, on Zulip):

More specificically, the folow is like this:

text (base_db) -> CST (syntax) -> item_tree (def) -> crate_def_map (def)
                            \---> body (def) -> ty (ty)
kev (Dec 11 2020 at 13:01, on Zulip):

Oh I see, the ty probably does not deal with scoping information?

matklad (Dec 11 2020 at 13:01, on Zulip):

@kev there are two kinds of scopes

matklad (Dec 11 2020 at 13:01, on Zulip):

module-level scope for items. It is handled by crate_def_map

matklad (Dec 11 2020 at 13:02, on Zulip):

block-level scope for local variable. It is handled by body/scope thing, and is pretty ad-hoc

matklad (Dec 11 2020 at 13:02, on Zulip):

The reson for this split is so that we can resovle names in function bodies lazily

kev (Dec 11 2020 at 13:03, on Zulip):

kev said:

Oh I see, the ty probably does not deal with scoping information?

Oh, I was referring to lexical scope or block-level scope

kev (Dec 11 2020 at 13:04, on Zulip):

matklad said:

The reson for this split is so that we can resovle names in function bodies lazily

Hmm what do you mean by resolving names lazily?

matklad (Dec 11 2020 at 13:04, on Zulip):

Yeah, lexical scopes is handled by ExprScopes which is in def crate, not in ty

matklad (Dec 11 2020 at 13:05, on Zulip):

Hmm what do you mean by resolving names lazily?

rust-analyzer resolve names in the modules eagarly. That is, after every typing, we recompute the set of names visible in every module.

For function bodies however, we postpone this computation until we actually need it. So typically only bodis in the currently opened file are processed, all other function bodies are unresolved.

kev (Dec 11 2020 at 13:07, on Zulip):

Oh right, that makes sense!

kev (Dec 11 2020 at 14:04, on Zulip):

matklad said:

More specificically, the folow is like this:

text (base_db) -> CST (syntax) -> item_tree (def) -> crate_def_map (def)
                            \---> body (def) -> ty (ty)

Are imports resolved before the CST is transformed to body(def) is called?

kev (Dec 11 2020 at 14:06, on Zulip):

Expressions can be checked with just a Body, so it seems that this must be the case. Link: https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/hir_def/src/body/scope.rs#L51

Jonas Schievink [he/him] (Dec 11 2020 at 14:10, on Zulip):

It uses the name resolution results during body lowering (CrateDefMap)

kev (Dec 11 2020 at 14:14, on Zulip):

Is there something like api-walkthrough where you can see the whole flow?

kev (Dec 11 2020 at 14:14, on Zulip):

There probably is, I'm just super blind :)

Jonas Schievink [he/him] (Dec 11 2020 at 14:16, on Zulip):

There's a few design docs here: https://github.com/rust-analyzer/rust-analyzer/tree/master/docs/dev

I don't think they cover what you're looking for though

kev (Dec 11 2020 at 14:18, on Zulip):

Jonas Schievink said:

It uses the name resolution results during body lowering (CrateDefMap)

so before the ast::Expr is lowered, it is resolved?

kev (Dec 11 2020 at 14:19, on Zulip):

I was under the impression that it was lowered first and then resolved

Jonas Schievink [he/him] (Dec 11 2020 at 14:22, on Zulip):

Ah, no, seems like only macro calls in the body are really resolved if I'm reading the code correctly

kev (Dec 11 2020 at 14:22, on Zulip):

Jonas Schievink said:

There's a few design docs here: https://github.com/rust-analyzer/rust-analyzer/tree/master/docs/dev

I don't think they cover what you're looking for though

Will re-read the syntax and architecture files incase I missed anything!

kev (Dec 11 2020 at 14:24, on Zulip):

Jonas Schievink said:

Ah, no, seems like only macro calls in the body are really resolved if I'm reading the code correctly

This would make a lot of sense for me, because the tests are predominately include macro calls, without any use trees or inlined modules

Last update: Jul 24 2021 at 20:00UTC