Stream: t-compiler/wg-rls-2.0/chalk

Topic: planning / status


nikomatsakis (Apr 29 2019 at 17:01, on Zulip):

Hey @Florian Diebold, @matklad -- have either of you got a minute?

nikomatsakis (Apr 29 2019 at 17:03, on Zulip):

I'm thinking about the next steps for chalk integration, and wanted to talk more about rust-analyzer and how it should fit together

matklad (Apr 29 2019 at 17:04, on Zulip):

I am around

matklad (Apr 29 2019 at 17:04, on Zulip):

and @Florian Diebold actually added chalk to ra: https://github.com/rust-analyzer/rust-analyzer/pull/1216 :D

nikomatsakis (Apr 29 2019 at 17:08, on Zulip):

Ah, cool

nikomatsakis (Apr 29 2019 at 17:08, on Zulip):

So

nikomatsakis (Apr 29 2019 at 17:08, on Zulip):

Well, let me skim that PR I guess

nikomatsakis (Apr 29 2019 at 17:14, on Zulip):

ok, that's a bit much to skim :)

Florian Diebold (May 07 2019 at 11:31, on Zulip):

By the way, I've now implemented support for where clauses, but have huge performance problems, as in some queries seem to basically never finish. As far as I can tell, one of the reasons seems to be that in a case like where T: Foo, T: Bar, Chalk will request all impls for Foo and then for each of those impls request all impls for Bar. So I'm now looking into implementing a 'type fingerprint' thing so that we (hopefully) don't get this multiplicative behavior.

nikomatsakis (May 07 2019 at 13:39, on Zulip):

Yeah, the current code for requesting impls is super naive in this way

Florian Diebold (May 07 2019 at 17:15, on Zulip):

Hmm I think what I'm actually running into is https://github.com/rust-lang/chalk/issues/217, just with Send instead of Sized

nikomatsakis (May 07 2019 at 17:29, on Zulip):

Sounds plausible. I was thinking about that last night and feeling doubts about the best solution :/

Florian Diebold (May 07 2019 at 19:30, on Zulip):

I've managed a small reproduction:

//- /main.rs
trait Send {}

struct S1; impl Send for S1;
struct S2; impl Send for S2;
struct U1;

trait Trait { fn method(self); }

struct X1<A, B> {}
impl<A, B> Send for X1<A, B> where A: Send, B: Send {}

struct S<B, C> {}

trait Fn {}

impl<B, C> Trait for S<B, C> where C: Fn, B: Send {}

fn test() { (S {}).method(); }

Type inference on test takes over 3 minutes; if I remove S2, it goes down to 20 seconds; switching the order of the where clauses in the last impl makes it work instantly. It seems to enumerate a huge number of possibilities for ?0: Send. (Note that Send isn't even an auto trait in the test.)

nikomatsakis (May 07 2019 at 21:01, on Zulip):

Yeah, the engine can definitely do that sometimes. This is exactly the sort of feedback I was interested in exploring

matklad (May 07 2019 at 21:03, on Zulip):

@nikomatsakis does chalk has "fuel" thing? I think we should add it: it seems for IDE stuff you want to add fuel basically everywhere

matklad (May 07 2019 at 21:03, on Zulip):

As in, to be responsive, IDE should be a primitive recursive function :D

matklad (May 07 2019 at 21:05, on Zulip):

That is, we certainly need to fix this bug, but I expect that fixing all of the bugs will be really hard, and just adding a "fuel" safeguard on top can help to contain the bug's effects

nikomatsakis (May 07 2019 at 21:06, on Zulip):

it doesn't, but it's plausible we could add it

nikomatsakis (May 07 2019 at 21:06, on Zulip):

it's made to be "resumable" in this way

matklad (May 07 2019 at 21:08, on Zulip):

My gut feeling is that fuel will be very welcome. And an interesting question here is how do we integrate fuel with salsa: if you just make "fuel tank" a query parameter, you lose incremental efficency (nothing is cached due to fuel fluctuation). If you use some kind of interior mutability, you lose incremental soundness.

nikomatsakis (May 07 2019 at 21:29, on Zulip):

well, trait solving is already a "volatile" activity

nikomatsakis (May 07 2019 at 21:29, on Zulip):

(but I haven't looked closely at how you integrated it into the RLS queries)

nikomatsakis (May 07 2019 at 21:29, on Zulip):

that said, there is also some existing set of "limits"

nikomatsakis (May 07 2019 at 21:29, on Zulip):

e.g., a max_size which limits how deeply the size of types that we will construct

nikomatsakis (May 07 2019 at 21:29, on Zulip):

for the time being, dialing that down may help

nikomatsakis (May 07 2019 at 21:31, on Zulip):

(this is in the SolverConfig)

Florian Diebold (May 11 2019 at 12:52, on Zulip):

Setting max_size to 6 from 10 makes the test complete instantly again. What exactly does this control, would A<B<C<D>>> have size 4? If so, I assume we can set it to e.g. 4 and still have very little impact on most uses, right?

Florian Diebold (May 11 2019 at 13:54, on Zulip):

Hm, actually even with 4 it takes too long in some functions in RA :/

Florian Diebold (May 11 2019 at 14:00, on Zulip):

With 2, it doesn't run into any slow cases on RA, but I don't know if that's still a reasonable value...

matklad (May 11 2019 at 14:01, on Zulip):

Make it 2.42? :)

Florian Diebold (May 11 2019 at 14:09, on Zulip):

by the way, https://github.com/rust-lang/chalk/pull/226 is exciting, it'll probably give us impl Trait support for very little work :)

Florian Diebold (May 11 2019 at 19:44, on Zulip):

I've tried implementing fuel in Chalk, and it doesn't seem very hard: https://github.com/rust-lang/chalk/pull/227 Of course this might mean we sometimes get different answers depending on how much the Solver had already cached; can this be a problem?

Last update: Nov 15 2019 at 10:30UTC