================
@@ -313,9 +313,75 @@ Response HandleRecordDecl(const CXXRecordDecl *Rec,
 
   // This is to make sure we pick up the VarTemplateSpecializationDecl that 
this
   // lambda is defined inside of.
-  if (Rec->isLambda())
+  if (Rec->isLambda()) {
     if (const Decl *LCD = Rec->getLambdaContextDecl())
       return Response::ChangeDecl(LCD);
+    // Attempt to retrieve the template arguments for a using alias 
declaration.
+    // This is necessary for constraint checking, since we always keep
+    // constraints relative to the primary template.
+    if (ForConstraintInstantiation && !SemaRef.CodeSynthesisContexts.empty()) {
+      for (auto &CSC : llvm::reverse(SemaRef.CodeSynthesisContexts)) {
+        if (CSC.Kind != Sema::CodeSynthesisContext::SynthesisKind::
+                            TypeAliasTemplateInstantiation)
+          continue;
+        auto *TATD = cast<TypeAliasTemplateDecl>(CSC.Entity),
+             *CurrentTATD = TATD;
+        FunctionDecl *LambdaCallOperator = Rec->getLambdaCallOperator();
+        // Retrieve the 'primary' template for a lambda call operator. It's
+        // unfortunate that we only have the mappings of call operators rather
+        // than lambda classes.
+        while (true) {
+          auto *FTD = dyn_cast_if_present<FunctionTemplateDecl>(
+              LambdaCallOperator->getDescribedTemplate());
+          if (FTD && FTD->getInstantiatedFromMemberTemplate()) {
+            LambdaCallOperator =
+                FTD->getInstantiatedFromMemberTemplate()->getTemplatedDecl();
+          } else if (auto *Prev = cast<CXXMethodDecl>(LambdaCallOperator)
+                                      ->getInstantiatedFromMemberFunction())
+            LambdaCallOperator = Prev;
+          else
+            break;
+        }
+        // Same applies for type alias Decl. We perform this to obtain the
+        // "canonical" template parameter depths.
+        while (TATD->getInstantiatedFromMemberTemplate())
+          TATD = TATD->getInstantiatedFromMemberTemplate();
+        // Tell if we're currently inside of a lambda expression that is
+        // surrounded by a using alias declaration. e.g.
+        //   template <class> using type = decltype([](auto) { ^ }());
+        // By checking if:
+        //  1. The lambda expression and the using alias declaration share the
+        //  same declaration context.
+        //  2. They have the same template depth.
+        // Then we assume the template arguments from the using alias
+        // declaration are essential for constraint instantiation. We have to 
do
----------------
cor3ntin wrote:

```suggestion
        // Then we assume the template arguments of the using alias
        // declaration are necessary for constraint instantiation. We have to do
```

https://github.com/llvm/llvm-project/pull/82310
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to