Stream: t-compiler

Topic: Name resolution librarification


matklad (Jul 30 2019 at 14:06, on Zulip):

In rust-analyzer, we need to do name resolution. Our current support is pretty limited (main limitation: items inside blocks don't participate in name res at all), and I wonder what is the best path forward for improving this...

Realistically, I think we have no one who can, at this point, spearhead the real name resolution librarification effort. So, for the time being, it seems best if rust-analyzer continues with its own thing. I wonder, however, how to make this "own thing" useful long-term.

@Vadim Petrochenkov do you have any suggestions as to what is the best path forward here? Should we, at rust-analyzer, just write something that works? Should we perhaps try some specific experimental approaches which are hard to use in current rustc? Should we put special effort into writing design documents/specifications?

As a remainder, the main thing we need to do differently for IDEs is to have the ability to not look into function bodies for name resolution. This technically doesn't work in Rust in edge cases (b/c #[macro_export] and impls are global), but this is a very important optimization for IDEs, so I'm betting on separate code-paths for rustc and rust-analyzer here, and future language-level tweaks to make item bodies more isolated.

simulacrum (Jul 30 2019 at 14:14, on Zulip):

Why can't IDEs look into function bodies? I would sort of expect that you have to parse the body to find the end anyway, at which point you're not really gaining anything by ignoring struct/enum/etc definitions

simulacrum (Jul 30 2019 at 14:14, on Zulip):

OTOH, I believe current rules mean that in order to find the definition of a struct/enum it's fine to ignore function bodies unless it's the current function because there's no way to export them

matklad (Jul 30 2019 at 14:17, on Zulip):

@simulacrum almost all code is in bodies. If we ignore bodies, we'll get significantly less data to process. You don't even need to parse bodies, because counting {} would be enough

simulacrum (Jul 30 2019 at 14:18, on Zulip):

Hm, I guess I sort of presumed counting {} would be approximately as slow as fast-parsing for e.g. keywords struct/union etc

matklad (Jul 30 2019 at 14:18, on Zulip):

OTOH, I believe current rules mean that in order to find the definition of a struct/enum it's fine to ignore function bodies unless it's the current function because there's no way to export them

macros break that :sob:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7ebc99813e42c705a66b7705d2165a7c

simulacrum (Jul 30 2019 at 14:20, on Zulip):

I would expect current resolution to be able to work with a partial view of the world -- e.g. everybody_loops applied to functions essentially

simulacrum (Jul 30 2019 at 14:20, on Zulip):

Is that not the case?

matklad (Jul 30 2019 at 14:22, on Zulip):

It could work that way, yeah. And that's basically how rust-analyzer now works. But, when you actually look into the body of the current function, you need to glue together results of local resolution and global resolution. This is the bit that is missing from rust-analyzer.

matklad (Jul 30 2019 at 14:22, on Zulip):

Like, I think it's realitevely straightforward to just do this, and we can add this to rust-analyzer. But I feel that's the case where a bit of up-front design can be helpful

simulacrum (Jul 30 2019 at 14:26, on Zulip):

Sure, yeah -- maybe a simple bit would be to make rustc's resolver a bit more generic so it can be used as a library by rust-analyzer more easily (without needing to port to libsyntax types and such)

simulacrum (Jul 30 2019 at 14:26, on Zulip):

I would sort of expect that even rustc's analyzer wants to be able to do incremental resolution based (just not today, since incremental comp. starts after it IIRC)

matklad (Jul 30 2019 at 14:28, on Zulip):

maybe a simple bit would be to make rustc's resolver a bit more generic so it can be used as a library by rust-analyzer more easily

I fear that this simple bit is on order of half a year of work full time. We definitely should do this eventually, but I am not sure that right now is the best time, given that, for example, there's unfinished chalk work

simulacrum (Jul 30 2019 at 14:29, on Zulip):

Sure, yeah, "simple" in terms of describing it I guess :)

simulacrum (Jul 30 2019 at 14:29, on Zulip):

Chalk seems orthogonal to this though? i.e. trait-related vs. name resolution

matklad (Jul 30 2019 at 14:30, on Zulip):

But yeah, just sharing the nameres code would be ideal. However, it took me a long time to do this for lexer (#59706), and lexer is like infinitely more simple than name res

matklad (Jul 30 2019 at 14:30, on Zulip):

@simulacrum yeah, chalk is orthogonal but I am not sure that having many parallel (pun intended) efforts is good

simulacrum (Jul 30 2019 at 14:32, on Zulip):

That's true. name resolution's complexity includes HIR and AST and such so I agree it is much harder to do (presumably)

matklad (Jul 30 2019 at 14:32, on Zulip):

Though, I think I can maybe drive this effort, after I finish the remainig bits of lexer.... I don't know a lot about name res, but I'd like to learn more

simulacrum (Jul 30 2019 at 14:33, on Zulip):

The main complication I think is how tightly coupled name resolution is to the compiler in terms of driving macro expansion, etc.

simulacrum (Jul 30 2019 at 14:33, on Zulip):

It wants to know a lot

matklad (Jul 30 2019 at 14:35, on Zulip):

Yeah: there's no clear name resolution "intermediate language", though it seems like there should be one (sets of names indexed by scopes and namespaces)

Last update: Nov 20 2019 at 01:05UTC