Stream: t-compiler/wg-rls-2.0

Topic: Why lazy parsing won't work for rust-analyzer


matklad (Apr 16 2019 at 07:58, on Zulip):

I've been reading https://v8.dev/blog/preparser which mentions a useful trick for speedy parsing: not parsing function bodies at all.

It's a shame that we can't do this in Rust, because impls inside function bodies are globally visible. See https://github.com/rust-analyzer/rust-analyzer/issues/1152 for details.

I wonder if we can deprecate local impls for global types in the next edition. Alternatively, maybe I am missing a simple heuristic for determining if the function has to be parsed lazily?

detrumi (Apr 16 2019 at 08:03, on Zulip):

It's very unintuitive that nested impls are visible globally. But maybe it's problematic for the compiler to track impls at multiple levels?

matklad (Apr 16 2019 at 08:08, on Zulip):

its definitely easier to just track impls globally, per crate, but it doesn't have that much harder to add some restrictions a-la coherence here

Charles Lew (Apr 16 2019 at 08:50, on Zulip):

I agree that it's not useful at all to allow local impls for global types. But i think it's ok to skip function bodies that have neither impl keyword nor macro invocation items in it?

matklad (Apr 16 2019 at 08:52, on Zulip):

Hm, that indeed looks like a heuristic I've overlooked!

I wonder which proportion of functions invoke macros though...

Charles Lew (Apr 16 2019 at 08:54, on Zulip):

treat any ! that doesn't look like a unary ! or never type as maybe a macro? The guess doesn't have to be accurate at all.

Vadim Petrochenkov (Apr 16 2019 at 09:05, on Zulip):

cc https://github.com/rust-lang/rfcs/issues/1355

Florian Diebold (Apr 16 2019 at 11:38, on Zulip):

I assume this can't be prohibited backwards-compatibly, but if the compiler emitted a warning in such cases we could maybe just assume no one does it and go ahead with lazy parsing?

matklad (Apr 16 2019 at 11:40, on Zulip):

Yeah, that's my plan: emit deprecation warning, proceed with lazy parsing. Maaaaybe switch to deny by default warning after crater and some time. So perhaps I've closed the issue on rust-analyzer prematurely? Lazy parsing should save a ton of memory

matklad (Apr 16 2019 at 11:41, on Zulip):

and we sort-of have all the necessary infra for it already, for incremental block reparsign

matklad (Apr 16 2019 at 11:41, on Zulip):

this means though that I need to re-do rowan's API once again :D

weiznich (Apr 16 2019 at 12:11, on Zulip):

So to just add a point to no one implements traits inside of functions: We are doing this in diesel_derives as part of our code gen. We use functions to provide a new scope to don't pollute the outer namespace with imported/generated items. We've used mods at some point of time, but that was already disallowed (Or better, that only worked because of an bug that allowed to accessing items from the parent scope in proc macro generated modules.)

matklad (Apr 16 2019 at 12:24, on Zulip):

why can't that be fn #mod_name { use super::*; use diesel; use std; } ?

weiznich (Apr 16 2019 at 13:06, on Zulip):

You mean mod #mod_name { use super::*; …}?

weiznich (Apr 16 2019 at 13:07, on Zulip):

Because use super::* does not import things that are imported into the parent scope. (At least it worked that way when we switched to using functions there.)

matklad (Apr 16 2019 at 13:11, on Zulip):

@weiznich use super::* does import (privatly) used stuff from the parent scope now!

matklad (Apr 16 2019 at 13:12, on Zulip):

But yeah, this example is convincing enough that deny_by_default is not going to happen in the foreseeable future, thanks!

weiznich (Apr 16 2019 at 13:20, on Zulip):

Oh, good to know that use super::* now also imports the privately imported stuff. That wouldn't make it to hard for us to change it back :wink:

Last update: Nov 19 2019 at 17:40UTC