[PATCH] D120416: [clangd] Function return type hints: support lambdas, don't duplicate "->"

Sam McCall via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 23 07:59:37 PST 2022


sammccall created this revision.
sammccall added a reviewer: nridge.
Herald added subscribers: usaxena95, kadircet, arphaman, kristof.beyls.
sammccall requested review of this revision.
Herald added subscribers: cfe-commits, MaskRay, ilya-biryukov.
Herald added a project: clang-tools-extra.

While here, fix an ugliness:

  auto foo()->auto { return 42; }

This (silly) code gains a "-> int" hint. While correct and useful, it renders as

  auto foo()->int->auto { return 42; }

which is confusing enough to do more harm than good I think.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D120416

Files:
  clang-tools-extra/clangd/InlayHints.cpp
  clang-tools-extra/clangd/unittests/InlayHintTests.cpp


Index: clang-tools-extra/clangd/unittests/InlayHintTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -527,13 +527,18 @@
   assertTypeHints(R"cpp(
     void f() {
       int cap = 42;
-      auto $L[[L]] = [cap, $init[[init]] = 1 + 1](int a) { 
+      auto $L[[L]] = [cap, $init[[init]] = 1 + 1](int a$ret[[)]] { 
         return a + cap + init; 
       };
     }
   )cpp",
                   ExpectedHint{": (lambda)", "L"},
-                  ExpectedHint{": int", "init"});
+                  ExpectedHint{": int", "init"}, ExpectedHint{"-> int", "ret"});
+
+  // Lambda return hint shown even if no param list.
+  assertTypeHints("auto $L[[x]] = <:$ret[[:>]]{return 42;};",
+                  ExpectedHint{": (lambda)", "L"},
+                  ExpectedHint{"-> int", "ret"});
 }
 
 // Structured bindings tests.
@@ -616,6 +621,9 @@
     // Do not hint `auto` for trailing return type.
     auto f3() -> int;
 
+    // Do not hint when a trailing return type is specified.
+    auto f4() -> auto* { return "foo"; }
+
     // `auto` conversion operator
     struct A {
       operator auto($retConv[[)]] { return 42; }
Index: clang-tools-extra/clangd/InlayHints.cpp
===================================================================
--- clang-tools-extra/clangd/InlayHints.cpp
+++ clang-tools-extra/clangd/InlayHints.cpp
@@ -254,17 +254,30 @@
   }
 
   bool VisitFunctionDecl(FunctionDecl *D) {
-    if (auto *AT = D->getReturnType()->getContainedAutoType()) {
-      QualType Deduced = AT->getDeducedType();
-      if (!Deduced.isNull()) {
-        addTypeHint(D->getFunctionTypeLoc().getRParenLoc(), D->getReturnType(),
-                    /*Prefix=*/"-> ");
-      }
+    if (auto *FPT =
+            llvm::dyn_cast<FunctionProtoType>(D->getType().getTypePtr())) {
+      if (!FPT->hasTrailingReturn())
+        addReturnTypeHint(D, D->getFunctionTypeLoc().getRParenLoc());
     }
+    return true;
+  }
 
+  bool VisitLambdaExpr(LambdaExpr *E) {
+    FunctionDecl *D = E->getCallOperator();
+    if (!E->hasExplicitResultType())
+      addReturnTypeHint(D, E->hasExplicitParameters()
+                               ? D->getFunctionTypeLoc().getRParenLoc()
+                               : E->getIntroducerRange().getEnd());
     return true;
   }
 
+  void addReturnTypeHint(FunctionDecl *D, SourceLocation Loc) {
+    auto *AT = D->getReturnType()->getContainedAutoType();
+    if (!AT || AT->getDeducedType().isNull())
+      return;
+    addTypeHint(Loc, D->getReturnType(), /*Prefix=*/"-> ");
+  }
+
   bool VisitVarDecl(VarDecl *D) {
     // Do not show hints for the aggregate in a structured binding,
     // but show hints for the individual bindings.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D120416.410831.patch
Type: text/x-patch
Size: 2817 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220223/3c4a095c/attachment.bin>


More information about the cfe-commits mailing list