Skip to content

Support built-in derives #1427

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
flodiebold opened this issue Jun 22, 2019 · 7 comments
Closed

Support built-in derives #1427

flodiebold opened this issue Jun 22, 2019 · 7 comments
Labels
E-has-instructions Issue has some instructions and pointers to code to get started E-medium

Comments

@flodiebold
Copy link
Member

We should support the built-in derives, e.g. with

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
struct SomeStruct { ... }

we should know that the type implements those traits and pass corresponding impls to Chalk when doing trait solving. The most noticeable case where this currently matters is Clone since that gets called directly all the time; the other ones are more likely to be used in bounds, so we're probably missing some trait implementations because of this.

Here are some general notes about this (I haven't thought about / investigated this in detail yet):

  • we don't need to generate code for the impls, so just producing a 'fake' impl without any actual method implementations should be enough
  • We could generate actual ra_hir::ImplBlocks for this, or we could collect the derives in some separate data structure and just generate fake impls for Chalk (i.e. in impls_for_trait). I'm not sure which would be the better/nicer approach.
  • as far as I know / think, the derived impls just have a bound for each type parameter of the struct (e.g. #[derive(Clone)] struct S<T> would result in impl<T: Clone> Clone for S<T>), but I haven't checked this.
@flodiebold flodiebold added E-medium E-has-instructions Issue has some instructions and pointers to code to get started labels Jun 22, 2019
@lnicola
Copy link
Member

lnicola commented Jun 22, 2019

We could generate actual ra_hir::ImplBlocks for this, or we could collect the derives in some separate data structure and just generate fake impls for Chalk (i.e. in impls_for_trait). I'm not sure which would be the better/nicer approach.

It would be nice if "go to definition" (or "implementation"; "definition" is what I'm used to from VS) on a method of a derived trait would work and point to the attribute.

as far as I know / think, the derived impls just have a bound for each type parameter of the struct

Yes, see rust-lang/rust#41481 and rust-lang/rust#26925.

@flodiebold
Copy link
Member Author

flodiebold commented Jun 22, 2019

It would be nice if "go to definition" on a method of a derived trait would work and point to the attribute.

Currently "go to definition" will go to the definition of the method in the trait. I don't know if we should go to the impl if possible, or if we should have a separate command that does that... In many cases it's not possible anyway 🤔
In any case, I think neither approach precludes that, though the approach with actual ImplBlocks may make it a bit simpler (at the cost of needing to refactor a lot of the source handling for ImplBlock at the outset).

Edit: Ah right, there's a 'go to implementation' in the LSP. So that should probably go to the impl. We'd first have to get Chalk to tell us which impl applied though...

@matklad
Copy link
Member

matklad commented Jun 22, 2019

I think the more future proof version (supporing custom derives) would be to generate actual source code when we do macro expansion.

@eupn
Copy link
Contributor

eupn commented Aug 2, 2019

I think the more future proof version (supporting custom derives) would be to generate actual source code when we do macro expansion.

@matklad hey, where the implementation of #[derive(...)] attribute expansion should go in that case?

@lnicola
Copy link
Member

lnicola commented Nov 9, 2019

A hacky and maybe easy way to get this (and also custom derives) would be to assert that types with #[derive(Trait)] on them implement Trait.

@flodiebold
Copy link
Member Author

Yes, as a midterm solution, we could basically provide synthetic impls for derives. Nowadays, I think we have all of the necessary infrastructure for that. It'd involve adding a variant to the Impl enum here, adding code here to return those impls when there's a derive, and providing the right data to Chalk here. It's not quite simply asserting the type implements the trait though; if the type has parameters, the impl needs to have variables for those and bound each of them with the trait.

This won't work for custom derives though, since they can do basically anything, not just implementing a trait, and even for the ones that do, I don't think we have a good way of knowing what the trait being implemented is. Still, I think this could be worth it for the built-in derives, since proper support for custom derives may still take quite some time.

@flodiebold
Copy link
Member Author

This is actually fixed 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
E-has-instructions Issue has some instructions and pointers to code to get started E-medium
Projects
None yet
Development

No branches or pull requests

4 participants