Skip to content
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

Use C++20 concepts to inform code completion in templates #261

Closed
HighCommander4 opened this issue Jan 21, 2020 · 5 comments
Closed

Use C++20 concepts to inform code completion in templates #261

HighCommander4 opened this issue Jan 21, 2020 · 5 comments

Comments

@HighCommander4
Copy link

HighCommander4 commented Jan 21, 2020

In the following code example:

template <typename T>
concept Fooable = requires (T t) { t.foo(); };

class Waldo {};

template <typename T> requires Fooable<T>
void bar(T t) {
  t.^
}

it would make sense to offer foo as a completion proposal.

@sam-mccall
Copy link
Member

Indeed. It looks like core concepts stuff (constraints and such) is still landing in clang, e.g. recent https://reviews.llvm.org/D50360. The implementation of this is going to depend on what the AST looks like.

If you're able to follow that closely enough, have a sense of how the AST could be structured to help enable such code completion, it might be worth prototyping and talking to the authors (looks like Saar Raz is implementing most with Richard Smith reviewing) while things are still in flux.

Otherwise it might be worth holding off on this for a bit until it's more stable, and working out how to produce sensible suggestions on top of it. My read is an AST walk and a few heuristics will give us method names with argument counts (and maybe types), nested types, and that might be about as much as we get.

@sam-mccall
Copy link
Member

sam-mccall commented Jan 29, 2020

What the heck, here's a rough prototype (no tests, and some cases not covered: completion after :: doesn't work, and completion of nested templates doesn't work)

https://reviews.llvm.org/D73596

Have been trying it out with this snippet:

template <typename T> concept X = requires(T t) { t.xxx(); typename T::x_t; };
template <typename T> concept Y = requires(T t) { t.yyy(); };
template <typename A, typename B> concept W = requires(A a, B b) { { b.www() } noexcept; };
template <typename T> concept Z = requires(T t) { t.zzz(); requires W<int, T>; };
template <X T> requires Y<T> &&requires(T *t) { t->aaa(); }
void foo(T t) requires Z<T> || requires(T &t) { t.bbb(); t->bb(); } {
  t.
}

@HighCommander4
Copy link
Author

What the heck, here's a rough prototype (no tests, and some cases not covered: completion after :: doesn't work, and completion of nested templates doesn't work)

https://reviews.llvm.org/D73596

I remember reviewing this code, but I guess it was in a re-upload as a new review request. Did it end up landing?

@HighCommander4
Copy link
Author

Here's the newer review request: https://reviews.llvm.org/D73649, and it did in fact land.

Perhaps we should close this issue, and file follow-ups for additional cases we'd like to support?

@sam-mccall
Copy link
Member

Agree, we have some basic support. I'm sure there's things to be improved but let's close this until we have a better idea what's high priority.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants