[PATCH] D73649: [CodeComplete] Member completion for concept-constrained types.
Nathan Ridge via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 3 12:37:16 PST 2020
nridge marked 3 inline comments as done.
nridge added inline comments.
================
Comment at: clang/lib/Sema/SemaCodeComplete.cpp:4856
+private:
+ // Infer members of T, given that the expression E (dependent on T) is true.
+ void believe(const Expr *E, const TemplateTypeParmType *T) {
----------------
sammccall wrote:
> nridge wrote:
> > "given that the expression E is valid"?
> E comes from concept constraints, we actually know that E is not only valid but its value is exactly `true`.
>
> In particular, knowing that E is *valid* doesn't tell us anything at all about T if E is a ConceptSpecializationExpr like `Integral<T>`, as we'd get from a `requires Integral<T>` clause or an `Integral auto foo` parameter. (Note that `Integral<std::string>` is a valid expression with the value `false`)
You're totally right on this one, my bad! (When I wrote this, I imagined `believe()` being called on the expression inside an `ExprRequirement`, but that's not the case.)
================
Comment at: clang/lib/Sema/SemaCodeComplete.cpp:4901
+ if (!Req->isDependent())
+ continue; // Can't tell us anything about T.
+ if (auto *TR = llvm::dyn_cast<concepts::TypeRequirement>(Req)) {
----------------
sammccall wrote:
> nridge wrote:
> > Are we sure a dependent requirement can't tell us anything about `T`?
> >
> > For example, a constraint with a dependent return type requirement might still give us a useful member name and arguments. Even a call expression with dependent arguments could give us a useful member name.
> >
> > Or am I misunderstanding what `Requirement::isDependent()` signifies?
> I think you're reading this backwards, a *non-dependent* requirement can't tell us anything about T, because it doesn't depend on T!
>
> This isn't terribly important except that it takes care of a few cases at once (e.g. all requirements below must have an expr rather than an error, because constraints with an error aren't dependent)
Indeed, I was reading this backwards. Makes sense now!
================
Comment at: clang/lib/Sema/SemaCodeComplete.cpp:4972
+
+ // In T::foo::bar, `foo` must be a type.
+ bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS) {
----------------
sammccall wrote:
> nridge wrote:
> > It would be nice if the test exercised this case.
> Oops, this was actually broken because VisitNestedNameSpecifier doesn't seem to be a thing :-(
> Fixed to use TraverseNestedNameSpecifierLoc and added a test.
> Oops, this was actually broken because VisitNestedNameSpecifier doesn't seem to be a thing :-(
(I suspected this, but the heavy macro usage in `RecursiveASTVisitor.h` made me second-guess myself and think I was just overlooking a place that defines `VisitNestedNameSpecifier`. I figured adding a test wouldn't hurt even if I'm mistaken and the code works. :-))
================
Comment at: clang/lib/Sema/SemaCodeComplete.cpp:5006
+ if (/*Inserted*/ R.second ||
+ std::make_tuple(M.Operator, M.ArgTypes.hasValue(),
+ M.ResultType != nullptr) >
----------------
So `Colons` is more info than `Arrow` which is more info than `Dot`? Is there some intuition behind that?
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D73649/new/
https://reviews.llvm.org/D73649
More information about the cfe-commits
mailing list