rust-lang / chalk

An implementation and definition of the Rust trait system using a PROLOG-like logic solver
https://rust-lang.github.io/chalk/book/
Other
1.81k stars 180 forks source link

identifying which method will run for a trait #716

Open nikomatsakis opened 3 years ago

nikomatsakis commented 3 years ago

As part of rust-analyzer/rust-analyzer#4558, we would like to extend chalk so that it can identify the fn that will run. The basic idea is to model this in a similar fashion to how associated type normalization works.

Summary of the idea

Given:

impl<A> Foo for Bar<A> {
    fn method(&self) { }
}

where method has the type FnDef(X, [_]) we will generate a program clause like

forall<A> {
    NormalizeFn(<Foo as Bar<A>>::method => FnDef(X, [A]))
}

Rust-analyzer can then do a query like NormalizeFn(<Foo as Bar<u32>>::method => ?X) to find the FnDef type for the method that will run (which includes its unique id and the values of all its relevant type parameters).

nikomatsakis commented 3 years ago

Implementation steps:

Extend the chalk-ir

Extend the database types

Actually, I think we have function signature and other information already accessible for FnDef, so we should leverage that.

Extend the program clause generation

The program_clauses_that_could_match function needs to be extended so that when we try to prove a NormalizeFn goal, we go to the relevant impls, and we generate NormalizeFn rules.

Extend the parser and unit testing

We ought to be able to write unit tests that include fn foo<A>() { } in them. We may want to include ABI and argument types -- I think we already have some of that logic in order to generate the impls of the Fn traits, so we just want to extend it to be included within traits and impls.

nikomatsakis commented 3 years ago

@rustbot assign @lf-

lf- commented 3 years ago

I am working on this on https://github.com/lf-/chalk/tree/source-impl (obviously it will be rebased and commits cleaned up when it's ready for proper review; I'm posting this for reference)

So far done:

To do as I keep going:

Confused about:

What to generate for program clauses for NormalizeFn(FnDefTy, Ty). I would really like an example of something reasonable for this from the stdlib for instance. I'm currently unsure what exact info this goal needs to encode and what program clauses to make.

lf- commented 3 years ago

So that was a lie. It turns out the lowering and parsing contains way more lowering and parsing than I thought 😭. Moving slowly but getting places. Total diff has already crossed 1000 lines :V

jackh726 commented 2 years ago

@rustbot release-assignment

compiler-errors commented 2 years ago

@jackh726, is this up for grabs? i would be interested in continuing the work in the linked PR. been looking for some chalk work.

jackh726 commented 2 years ago

I think in theory yes. But this is more of a question for Niko. He said he has thoughts for a different approach :)

nikomatsakis commented 2 years ago

@compiler-errors I'd be very psyched to see you continue with this work!

I did have thoughts for another approach, but essentially what I wanted to do was to make "methods" kind of a special sort of associated type, I believe. We could schedule some time to talk about it at https://calendly.com/nikomatsakis/, @compiler-errors.

jackh726 commented 2 years ago

I think it would be cool to treat associated types, consts, and methods similarly in how we resolve them (thinking with #745 in mind)