Skip to content

[clang-tidy] Add support for lambda-expression in use-trailing-return-type check #135383

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

vbvictor
Copy link
Contributor

@vbvictor vbvictor commented Apr 11, 2025

Add support for lambda-expression in use-trailing-return-type check.

Added two new options:

  1. TransformFunctions will trigger function declarations to use trailing return type. Values can be true or false. Default is true.
  2. TransformLambdas will trigger lambda expression to use trailing return type if it was not stated explicitly. This option can have the following values: All will emit trailing return type for all lambdas, including generic-lambdas that will emit auto type. AllExceptAuto will emit trailing return type for all lambdas excluding those with auto type. None will provide no diagnostics for lambdas. Default is All.

Fixed false positives when lambda was matched as a function in C++11 mode. https://godbolt.org/z/dh6so4Y18

Addresses #95711

@llvmbot
Copy link
Member

llvmbot commented Apr 11, 2025

@llvm/pr-subscribers-clang-tools-extra

@llvm/pr-subscribers-clang-tidy

Author: Baranov Victor (vbvictor)

Changes

Add support for lambda-expression in use-trailing-return-type check.

Added two new options:

  1. TransformFunctions will trigger function declarations to use trailing return type. Values can be true or false. Default is true.
  2. TransformLambdas will trigger lambda expression to use trailing return type if it was not stated explicitly. This option can have the following values: All will emit trailing return type for all lambdas, including generic-lambdas that will emit auto type. AllExceptAuto will emit trailing return type for all lambdas excluding those with auto type. None will provide no diagnostics for lambdas. Default is All.

Addresses #95711


Patch is 23.09 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/135383.diff

8 Files Affected:

  • (modified) clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp (+134-3)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h (+13-2)
  • (modified) clang-tools-extra/docs/ReleaseNotes.rst (+6)
  • (modified) clang-tools-extra/docs/clang-tidy/checks/modernize/use-trailing-return-type.rst (+25-1)
  • (added) clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas-cxx20.cpp (+35)
  • (added) clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas.cpp (+91)
  • (added) clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-wrong-config.cpp (+5)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type.cpp (-2)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp
index 9774e988d71e2..ca0d05a86d453 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp
@@ -17,6 +17,30 @@
 #include <cctype>
 #include <optional>
 
+namespace clang::tidy {
+
+template <>
+struct OptionEnumMapping<
+    modernize::UseTrailingReturnTypeCheck::TransformLambda> {
+  static llvm::ArrayRef<std::pair<
+      modernize::UseTrailingReturnTypeCheck::TransformLambda, StringRef>>
+  getEnumMapping() {
+    static constexpr std::pair<
+        modernize::UseTrailingReturnTypeCheck::TransformLambda, StringRef>
+        Mapping[] = {
+            {modernize::UseTrailingReturnTypeCheck::TransformLambda::All,
+             "All"},
+            {modernize::UseTrailingReturnTypeCheck::TransformLambda::
+                 AllExceptAuto,
+             "AllExceptAuto"},
+            {modernize::UseTrailingReturnTypeCheck::TransformLambda::None,
+             "None"}};
+    return Mapping;
+  }
+};
+
+} // namespace clang::tidy
+
 using namespace clang::ast_matchers;
 
 namespace clang::tidy::modernize {
@@ -111,6 +135,11 @@ struct UnqualNameVisitor : public RecursiveASTVisitor<UnqualNameVisitor> {
 private:
   const FunctionDecl &F;
 };
+
+AST_MATCHER(LambdaExpr, hasExplicitResultType) {
+  return Node.hasExplicitResultType();
+}
+
 } // namespace
 
 constexpr llvm::StringLiteral Message =
@@ -383,14 +412,40 @@ void UseTrailingReturnTypeCheck::keepSpecifiers(
   }
 }
 
+UseTrailingReturnTypeCheck::UseTrailingReturnTypeCheck(
+    StringRef Name, ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      TransformFunctions(Options.get("TransformFunctions", true)),
+      TransformLambdas(Options.get("TransformLambdas", TransformLambda::All)) {
+
+  if (TransformFunctions == false && TransformLambdas == TransformLambda::None)
+    this->configurationDiag(
+        "The check 'modernize-use-trailing-return-type' will not perform any "
+        "analysis because 'TransformFunctions' and 'TransformLambdas' are "
+        "disabled.");
+}
+
+void UseTrailingReturnTypeCheck::storeOptions(
+    ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "TransformFunctions", TransformFunctions);
+  Options.store(Opts, "TransformLambdas", TransformLambdas);
+}
+
 void UseTrailingReturnTypeCheck::registerMatchers(MatchFinder *Finder) {
   auto F = functionDecl(
                unless(anyOf(hasTrailingReturn(), returns(voidType()),
                             cxxConversionDecl(), cxxMethodDecl(isImplicit()))))
                .bind("Func");
 
-  Finder->addMatcher(F, this);
-  Finder->addMatcher(friendDecl(hasDescendant(F)).bind("Friend"), this);
+  if (TransformFunctions) {
+    Finder->addMatcher(F, this);
+    Finder->addMatcher(friendDecl(hasDescendant(F)).bind("Friend"), this);
+  }
+
+  if (TransformLambdas != TransformLambda::None) {
+    Finder->addMatcher(
+        lambdaExpr(unless(hasExplicitResultType())).bind("Lambda"), this);
+  }
 }
 
 void UseTrailingReturnTypeCheck::registerPPCallbacks(
@@ -402,8 +457,13 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) {
   assert(PP && "Expected registerPPCallbacks() to have been called before so "
                "preprocessor is available");
 
-  const auto *F = Result.Nodes.getNodeAs<FunctionDecl>("Func");
+  if (const auto *Lambda = Result.Nodes.getNodeAs<LambdaExpr>("Lambda")) {
+    diagOnLambda(Lambda, Result);
+    return;
+  }
+
   const auto *Fr = Result.Nodes.getNodeAs<FriendDecl>("Friend");
+  const auto *F = Result.Nodes.getNodeAs<FunctionDecl>("Func");
   assert(F && "Matcher is expected to find only FunctionDecls");
 
   // Three-way comparison operator<=> is syntactic sugar and generates implicit
@@ -494,4 +554,75 @@ void UseTrailingReturnTypeCheck::check(const MatchFinder::MatchResult &Result) {
       << FixItHint::CreateInsertion(InsertionLoc, " -> " + ReturnType);
 }
 
+void UseTrailingReturnTypeCheck::diagOnLambda(
+    const LambdaExpr *Lambda,
+    const ast_matchers::MatchFinder::MatchResult &Result) {
+
+  const CXXMethodDecl *Method = Lambda->getCallOperator();
+  if (!Method || Lambda->hasExplicitResultType())
+    return;
+
+  const QualType ReturnType = Method->getReturnType();
+  if (ReturnType->isUndeducedAutoType() &&
+      TransformLambdas == TransformLambda::AllExceptAuto)
+    return;
+
+  const SourceLocation TrailingReturnInsertLoc =
+      findLambdaTrailingReturnInsertLoc(Method, *Result.SourceManager,
+                                        getLangOpts(), *Result.Context);
+
+  if (TrailingReturnInsertLoc.isValid())
+    diag(Lambda->getBeginLoc(), "use a trailing return type for this lambda")
+        << FixItHint::CreateInsertion(
+               TrailingReturnInsertLoc,
+               " -> " +
+                   ReturnType.getAsString(Result.Context->getPrintingPolicy()));
+  else
+    diag(Lambda->getBeginLoc(), "use a trailing return type for this lambda");
+}
+
+SourceLocation UseTrailingReturnTypeCheck::findLambdaTrailingReturnInsertLoc(
+    const CXXMethodDecl *Method, const SourceManager &SM,
+    const LangOptions &LangOpts, const ASTContext &Ctx) {
+  // 'requires' keyword is present in lambda declaration
+  if (Method->getTrailingRequiresClause()) {
+    SourceLocation ParamEndLoc;
+    if (Method->param_empty()) {
+      ParamEndLoc = Method->getBeginLoc();
+    } else {
+      ParamEndLoc = Method->getParametersSourceRange().getEnd();
+    }
+
+    std::pair<FileID, unsigned> ParamEndLocInfo =
+        SM.getDecomposedLoc(ParamEndLoc);
+    StringRef Buffer = SM.getBufferData(ParamEndLocInfo.first);
+
+    Lexer Lexer(SM.getLocForStartOfFile(ParamEndLocInfo.first), LangOpts,
+                Buffer.begin(), Buffer.data() + ParamEndLocInfo.second,
+                Buffer.end());
+
+    Token Token;
+    while (!Lexer.LexFromRawLexer(Token)) {
+      if (Token.is(tok::raw_identifier)) {
+        IdentifierInfo &Info = Ctx.Idents.get(StringRef(
+            SM.getCharacterData(Token.getLocation()), Token.getLength()));
+        Token.setIdentifierInfo(&Info);
+        Token.setKind(Info.getTokenID());
+      }
+
+      if (Token.is(tok::kw_requires)) {
+        return Token.getLocation().getLocWithOffset(-1);
+      }
+    }
+
+    return {};
+  }
+
+  // If no requires clause, insert before the body
+  if (const Stmt *Body = Method->getBody())
+    return Body->getBeginLoc().getLocWithOffset(-1);
+
+  return {};
+}
+
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h
index 5fb6ae945f466..5a340707e8558 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.h
@@ -27,18 +27,22 @@ struct ClassifiedToken {
 /// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-trailing-return-type.html
 class UseTrailingReturnTypeCheck : public ClangTidyCheck {
 public:
-  UseTrailingReturnTypeCheck(StringRef Name, ClangTidyContext *Context)
-      : ClangTidyCheck(Name, Context) {}
+  UseTrailingReturnTypeCheck(StringRef Name, ClangTidyContext *Context);
   bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
     return LangOpts.CPlusPlus11;
   }
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
   void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
                            Preprocessor *ModuleExpanderPP) override;
   void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
 
+  enum TransformLambda { All, AllExceptAuto, None };
+
 private:
   Preprocessor *PP = nullptr;
+  const bool TransformFunctions;
+  const TransformLambda TransformLambdas;
 
   SourceLocation findTrailingReturnTypeSourceLocation(
       const FunctionDecl &F, const FunctionTypeLoc &FTL, const ASTContext &Ctx,
@@ -56,6 +60,13 @@ class UseTrailingReturnTypeCheck : public ClangTidyCheck {
                       SourceRange ReturnTypeCVRange, const FunctionDecl &F,
                       const FriendDecl *Fr, const ASTContext &Ctx,
                       const SourceManager &SM, const LangOptions &LangOpts);
+
+  void diagOnLambda(const LambdaExpr *Lambda,
+                    const ast_matchers::MatchFinder::MatchResult &Result);
+  SourceLocation findLambdaTrailingReturnInsertLoc(const CXXMethodDecl *Method,
+                                                   const SourceManager &SM,
+                                                   const LangOptions &LangOpts,
+                                                   const ASTContext &Ctx);
 };
 
 } // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index fefb085409b44..41dfbd871e023 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -185,6 +185,12 @@ Changes in existing checks
   <clang-tidy/checks/modernize/use-std-numbers>` check to support math
   functions of different precisions.
 
+- Improved :doc:`modernize-use-trailing-return-type
+  <clang-tidy/checks/modernize/use-trailing-return-type>` check by adding
+  support for modifying lambda signatures to use trailing return type and adding
+  two new options: `TransformFunctions` and `TransformLambdas` to control
+  whether function declarations and lambdas should be transformed by the check.
+
 - Improved :doc:`performance-move-const-arg
   <clang-tidy/checks/performance/move-const-arg>` check by fixing false
   negatives on ternary operators calling ``std::move``.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-trailing-return-type.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-trailing-return-type.rst
index 0593a35326aaa..5001859994e1e 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-trailing-return-type.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-trailing-return-type.rst
@@ -3,7 +3,7 @@
 modernize-use-trailing-return-type
 ==================================
 
-Rewrites function signatures to use a trailing return type
+Rewrites function and lambda signatures to use a trailing return type
 (introduced in C++11). This transformation is purely stylistic.
 The return type before the function name is replaced by ``auto``
 and inserted after the function parameter list (and qualifiers).
@@ -16,6 +16,7 @@ Example
   int f1();
   inline int f2(int arg) noexcept;
   virtual float f3() const && = delete;
+  auto lambda = []() {};
 
 transforms to:
 
@@ -24,6 +25,7 @@ transforms to:
   auto f1() -> int;
   inline auto f2(int arg) -> int noexcept;
   virtual auto f3() const && -> float = delete;
+  auto lambda = []() -> void {};
 
 Known Limitations
 -----------------
@@ -66,3 +68,25 @@ a careless rewrite would produce the following output:
 This code fails to compile because the S in the context of f refers to the equally named function parameter.
 Similarly, the S in the context of m refers to the equally named class member.
 The check can currently only detect and avoid a clash with a function parameter name.
+
+Options
+-------
+
+.. option:: TransformFunctions
+
+  When set to `true`, function declarations will be transformed to use trailing
+  return. Default is `true`.
+
+.. option:: TransformLambdas
+
+  Controls how lambda expressions are transformed to use trailing
+  return type. Possible values are:
+
+  * `All` - Transform all lambda expressions without an explicit return type
+    to use trailing return type. If type can not be deduced, ``auto`` will be
+    used.
+  * `AllExceptAuto` - Transform all lambda expressions except those whose return
+    type can not be deduced (``auto`` type).
+  * `None` - Do not transform any lambda expressions.
+
+  Default is `All`.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas-cxx20.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas-cxx20.cpp
new file mode 100644
index 0000000000000..aa56e317bdfce
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas-cxx20.cpp
@@ -0,0 +1,35 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-trailing-return-type %t
+
+namespace std {
+template <typename T, typename U>
+struct is_same { static constexpr auto value = false; };
+
+template <typename T>
+struct is_same<T, T> { static constexpr auto value = true; };
+
+template <typename T>
+concept floating_point = std::is_same<T, float>::value || std::is_same<T, double>::value || std::is_same<T, long double>::value;
+}
+
+void test_lambda_positive() {
+  auto l1 = []<typename T, typename U>(T x, U y) { return x + y; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-FIXES: {{^}}  auto l1 = []<typename T, typename U>(T x, U y) -> auto { return x + y; };{{$}}
+  auto l2 = [](auto x) requires requires { x + x; } { return x; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-FIXES: {{^}}  auto l2 = [](auto x) -> auto requires requires { x + x; } { return x; };{{$}}
+  auto l3 = [](auto x) requires std::floating_point<decltype(x)> { return x; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-FIXES: {{^}}  auto l3 = [](auto x) -> auto requires std::floating_point<decltype(x)> { return x; };{{$}}
+  auto l4 = [](int x) consteval { return x; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-FIXES: {{^}}  auto l4 = [](int x) consteval -> int { return x; };{{$}}
+  // Complete complex example
+  auto l5 = []<typename T, typename U>(T x, U y) constexpr noexcept
+    requires std::floating_point<T> && std::floating_point<U>
+  { return x * y; };
+  // CHECK-MESSAGES: :[[@LINE-3]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-FIXES: {{^}}  auto l5 = []<typename T, typename U>(T x, U y) constexpr noexcept{{$}}
+  // CHECK-FIXES: {{^}}    -> auto requires std::floating_point<T> && std::floating_point<U>{{$}}
+  // CHECK-FIXES: {{^}}  { return x * y; };{{$}}
+}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas.cpp
new file mode 100644
index 0000000000000..4143e9d610c3a
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-trailing-return-type-transform-lambdas.cpp
@@ -0,0 +1,91 @@
+// RUN: %check_clang_tidy -check-suffix=ALL -std=c++14 %s modernize-use-trailing-return-type %t \
+// RUN:   -config="{CheckOptions: {modernize-use-trailing-return-type.TransformLambdas: All, \
+// RUN:                            modernize-use-trailing-return-type.TransformFunctions: false}}"
+// RUN: %check_clang_tidy -check-suffix=NOAUTO -std=c++14 %s modernize-use-trailing-return-type %t \
+// RUN:   -config="{CheckOptions: {modernize-use-trailing-return-type.TransformLambdas: AllExceptAuto, \
+// RUN:                            modernize-use-trailing-return-type.TransformFunctions: false}}"
+// RUN: %check_clang_tidy -check-suffix=NONE -std=c++14 %s modernize-use-trailing-return-type %t \
+// RUN:   -config="{CheckOptions: {modernize-use-trailing-return-type.TransformLambdas: None, \
+// RUN:                            modernize-use-trailing-return-type.TransformFunctions: true}}"
+
+namespace std {
+    template <typename T>
+    class vector {};
+
+    class string {};
+} // namespace std
+
+void test_lambda_positive() {
+  auto l01 = [] {};
+  // CHECK-MESSAGES-ALL: :[[@LINE-1]]:14: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:14: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-FIXES-ALL: {{^}}  auto l01 = [] -> void {};{{$}}
+  auto l1 = []() {};
+  // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-FIXES-ALL: {{^}}  auto l1 = []() -> void {};{{$}}
+  auto l2 = []() { return 42; };
+  // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-FIXES-ALL: {{^}}  auto l2 = []() -> int { return 42; };{{$}}
+  auto l3 = [](int x, double y) { return x * y; };
+  // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-FIXES-ALL: {{^}}  auto l3 = [](int x, double y) -> double { return x * y; };{{$}}
+
+  int capture_int = 10;
+  double capture_double = 3.14;
+  int* capture_ptr = nullptr;
+  
+  auto l4 = [capture_int]() { return capture_int; };
+  // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-FIXES-ALL: {{^}}  auto l4 = [capture_int]() -> int { return capture_int; };{{$}}
+  auto l5 = [capture_int, &capture_double](char c) { return capture_int + capture_double + c; };
+  // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-FIXES-ALL: {{^}}  auto l5 = [capture_int, &capture_double](char c) -> double { return capture_int + capture_double + c; };{{$}}
+  auto l6 = [capture_int]() constexpr mutable noexcept { return ++capture_int; };
+  // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-FIXES-ALL: {{^}}  auto l6 = [capture_int]() constexpr mutable noexcept -> int { return ++capture_int; };{{$}}
+  auto l7 = [&capture_ptr]() { return capture_ptr; };
+  // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-FIXES-ALL: {{^}}  auto l7 = [&capture_ptr]() -> int * { return capture_ptr; };{{$}}
+  auto l8 = [&capture_int]() { return capture_int; };
+  // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-FIXES-ALL: {{^}}  auto l8 = [&capture_int]() -> int { return capture_int; };{{$}}
+  auto l9 = [] { return std::vector<std::vector<int>>{}; };
+  // CHECK-MESSAGES-ALL: :[[@LINE-1]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-MESSAGES-NOAUTO: :[[@LINE-2]]:13: warning: use a trailing return type for this lambda [modernize-use-trailing-return-type]
+  // CHECK-FIXES-ALL: {{^}}  auto l9 = [] -> std::vector<std::vector<int>> { return std::vector<std::vecto...
[truncated]

ParamEndLoc = Method->getParametersSourceRange().getEnd();
}

std::pair<FileID, unsigned> ParamEndLocInfo =
Copy link
Contributor Author

@vbvictor vbvictor Apr 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is very similar to findTrailingReturnTypeSourceLocation function. Here I find the position of requires keyword.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided not to make generic implementation of this piece of code as for now.

@vbvictor vbvictor marked this pull request as draft April 11, 2025 16:13
@vbvictor
Copy link
Contributor Author

vbvictor commented Apr 11, 2025

Converted to draft to fix windows tests

@vbvictor vbvictor force-pushed the add-trailing-for-lambda branch from ae6cedc to 4a7cdb4 Compare April 11, 2025 17:27
@vbvictor vbvictor marked this pull request as ready for review April 11, 2025 17:43
@vbvictor
Copy link
Contributor Author

Ping:)

@vbvictor
Copy link
Contributor Author

Ping

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

Successfully merging this pull request may close these issues.

2 participants