https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/177531

>From 593cb702cd83cb7257f3ce2d3ced658b0ecfb33c Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Fri, 23 Jan 2026 13:51:36 +0800
Subject: [PATCH 1/2] [Clang] Fix the normalization of fold constraints

Fold constraints can contain packs expanded from different locations.
For 'Ps...', where the ellipsis immediately follows the argument, the pack
should be expanded in place regardless of the fold expression. For
'C<Ps> && ...', the fold expression itself is responsible for expanding
Ps.

Previously, both kinds of packs were expanded by the fold expression,
which broke assumptions within concept caching. This patch fixes that by
preserving PackExpansionTypes for the first kind of pack while rewriting
them to non-packs for the second kind.

This patch also removes an unused function and performs some cleanup of
the evaluation contexts. Hopefully it is viable for backporting.

No release note, as this issue was a regression.
---
 clang/include/clang/Sema/Sema.h            |  12 +-
 clang/lib/Sema/SemaConcept.cpp             | 143 +++++++++++++--------
 clang/lib/Sema/SemaTemplateInstantiate.cpp |  42 ++----
 clang/lib/Sema/TreeTransform.h             |   2 +-
 clang/test/SemaCXX/cxx2c-fold-exprs.cpp    |  16 +++
 5 files changed, 120 insertions(+), 95 deletions(-)

diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 23eb954ce774c..4d2eda8c32317 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -13472,7 +13472,7 @@ class Sema final : public SemaBase {
   bool SubstTemplateArgumentsInParameterMapping(
       ArrayRef<TemplateArgumentLoc> Args, SourceLocation BaseLoc,
       const MultiLevelTemplateArgumentList &TemplateArgs,
-      TemplateArgumentListInfo &Out, bool BuildPackExpansionTypes);
+      TemplateArgumentListInfo &Out);
 
   /// Retrieve the template argument list(s) that should be used to
   /// instantiate the definition of the given declaration.
@@ -14888,16 +14888,6 @@ class Sema final : public SemaBase {
       const ConceptReference *TopLevelConceptId = nullptr,
       Expr **ConvertedExpr = nullptr);
 
-  /// \brief Check whether the given non-dependent constraint expression is
-  /// satisfied. Returns false and updates Satisfaction with the satisfaction
-  /// verdict if successful, emits a diagnostic and returns true if an error
-  /// occurred and satisfaction could not be determined.
-  ///
-  /// \returns true if an error occurred, false otherwise.
-  bool
-  CheckConstraintSatisfaction(const ConceptSpecializationExpr *ConstraintExpr,
-                              ConstraintSatisfaction &Satisfaction);
-
   /// Check whether the given function decl's trailing requires clause is
   /// satisfied, if any. Returns false and updates Satisfaction with the
   /// satisfaction verdict if successful, emits a diagnostic and returns true 
if
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 2674f0a7b8749..2e2922f9b438a 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -213,13 +213,41 @@ CalculateTemplateDepthForConstraints(Sema &S, const 
NamedDecl *ND,
 }
 
 namespace {
-class AdjustConstraintDepth : public TreeTransform<AdjustConstraintDepth> {
+class AdjustConstraints : public TreeTransform<AdjustConstraints> {
   unsigned TemplateDepth = 0;
 
+  bool RemoveNonPackExpansionPacks = false;
+
 public:
-  using inherited = TreeTransform<AdjustConstraintDepth>;
-  AdjustConstraintDepth(Sema &SemaRef, unsigned TemplateDepth)
-      : inherited(SemaRef), TemplateDepth(TemplateDepth) {}
+  using inherited = TreeTransform<AdjustConstraints>;
+  AdjustConstraints(Sema &SemaRef, unsigned TemplateDepth,
+                    bool RemoveNonPackExpansionPacks = false)
+      : inherited(SemaRef), TemplateDepth(TemplateDepth),
+        RemoveNonPackExpansionPacks(RemoveNonPackExpansionPacks) {}
+
+  ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
+                                  UnsignedOrNone NumExpansions) {
+    return inherited::RebuildPackExpansion(Pattern, EllipsisLoc, 
NumExpansions);
+  }
+
+  TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
+                                           SourceLocation EllipsisLoc,
+                                           UnsignedOrNone NumExpansions) {
+    if (!RemoveNonPackExpansionPacks)
+      return inherited::RebuildPackExpansion(Pattern, EllipsisLoc,
+                                             NumExpansions);
+    return Pattern;
+  }
+
+  bool PreparePackForExpansion(TemplateArgumentLoc In, bool Uneval,
+                               TemplateArgumentLoc &Out, UnexpandedInfo &Info) 
{
+    if (!RemoveNonPackExpansionPacks)
+      return inherited::PreparePackForExpansion(In, Uneval, Out, Info);
+    assert(In.getArgument().isPackExpansion());
+    Out = In;
+    Info.Expand = false;
+    return false;
+  }
 
   using inherited::TransformTemplateTypeParmType;
   QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
@@ -232,8 +260,8 @@ class AdjustConstraintDepth : public 
TreeTransform<AdjustConstraintDepth> {
           TransformDecl(TL.getNameLoc(), OldTTPDecl));
 
     QualType Result = getSema().Context.getTemplateTypeParmType(
-        T->getDepth() + TemplateDepth, T->getIndex(), T->isParameterPack(),
-        NewTTPDecl);
+        T->getDepth() + TemplateDepth, T->getIndex(),
+        RemoveNonPackExpansionPacks ? false : T->isParameterPack(), 
NewTTPDecl);
     TemplateTypeParmTypeLoc NewTL = TLB.push<TemplateTypeParmTypeLoc>(Result);
     NewTL.setNameLoc(TL.getNameLoc());
     return Result;
@@ -288,7 +316,13 @@ class HashParameterMapping : public 
RecursiveASTVisitor<HashParameterMapping> {
 
     TemplateArgument Arg = TemplateArgs(T->getDepth(), T->getIndex());
 
-    if (T->isParameterPack() && SemaRef.ArgPackSubstIndex) {
+    // In concept parameter mapping for fold expressions, packs that aren't
+    // expanded in place are treated as having non-pack dependency, so that
+    // a PackExpansionType won't prevent expanding the packs outside the
+    // TreeTransform. However we still need to check the pack at this point.
+    if ((T->isParameterPack() ||
+         (T->getDecl() && T->getDecl()->isTemplateParameterPack())) &&
+        SemaRef.ArgPackSubstIndex) {
       assert(Arg.getKind() == TemplateArgument::Pack &&
              "Missing argument pack");
 
@@ -506,10 +540,6 @@ StringRef allocateStringFromConceptDiagnostic(const Sema 
&S,
 
 ExprResult ConstraintSatisfactionChecker::EvaluateAtomicConstraint(
     const Expr *AtomicExpr, const MultiLevelTemplateArgumentList &MLTAL) {
-  EnterExpressionEvaluationContext ConstantEvaluated(
-      S, Sema::ExpressionEvaluationContext::ConstantEvaluated,
-      Sema::ReuseLambdaContextDecl);
-
   llvm::FoldingSetNodeID ID;
   if (Template &&
       DiagRecursiveConstraintEval(S, ID, Template, AtomicExpr, &MLTAL)) {
@@ -617,7 +647,7 @@ 
ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
 
   if (S.SubstTemplateArgumentsInParameterMapping(
           Constraint.getParameterMapping(), Constraint.getBeginLoc(), MLTAL,
-          SubstArgs, /*BuildPackExpansionTypes=*/true)) {
+          SubstArgs)) {
     Satisfaction.IsSatisfied = false;
     return std::nullopt;
   }
@@ -663,6 +693,9 @@ 
ConstraintSatisfactionChecker::SubstitutionInTemplateArguments(
 ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
     const AtomicConstraint &Constraint,
     const MultiLevelTemplateArgumentList &MLTAL) {
+  EnterExpressionEvaluationContext ConstantEvaluated(
+      S, Sema::ExpressionEvaluationContext::ConstantEvaluated,
+      Sema::ReuseLambdaContextDecl);
 
   llvm::SmallVector<TemplateArgument> SubstitutedOutermost;
   std::optional<MultiLevelTemplateArgumentList> SubstitutedArgs =
@@ -706,8 +739,6 @@ ExprResult ConstraintSatisfactionChecker::EvaluateSlow(
     return SubstitutedAtomicExpr;
   }
 
-  EnterExpressionEvaluationContext ConstantEvaluated(
-      S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
   SmallVector<PartialDiagnosticAt, 2> EvaluationDiags;
   Expr::EvalResult EvalResult;
   EvalResult.Diag = &EvaluationDiags;
@@ -1290,28 +1321,6 @@ SubstituteConceptsInConstraintExpression(Sema &S, const 
NamedDecl *D,
                                          MLTAL);
 }
 
-bool Sema::CheckConstraintSatisfaction(
-    const ConceptSpecializationExpr *ConstraintExpr,
-    ConstraintSatisfaction &Satisfaction) {
-
-  ExprResult Res = SubstituteConceptsInConstraintExpression(
-      *this, nullptr, ConstraintExpr, ArgPackSubstIndex);
-  if (!Res.isUsable())
-    return true;
-
-  llvm::SmallVector<AssociatedConstraint, 1> Constraints;
-  Constraints.emplace_back(Res.get());
-
-  MultiLevelTemplateArgumentList MLTAL(ConstraintExpr->getNamedConcept(),
-                                       ConstraintExpr->getTemplateArguments(),
-                                       true);
-
-  return CheckConstraintSatisfaction(
-      ConstraintExpr->getNamedConcept(), Constraints, MLTAL,
-      ConstraintExpr->getSourceRange(), Satisfaction,
-      ConstraintExpr->getConceptReference());
-}
-
 bool Sema::SetupConstraintScope(
     FunctionDecl *FD, std::optional<ArrayRef<TemplateArgument>> TemplateArgs,
     const MultiLevelTemplateArgumentList &MLTAL,
@@ -2000,14 +2009,20 @@ class SubstituteParameterMappings {
   const MultiLevelTemplateArgumentList *MLTAL;
   const ASTTemplateArgumentListInfo *ArgsAsWritten;
 
-  bool InFoldExpr;
+  // When normalizing a fold constraint, e.g.
+  //   C<Pack1, Pack2...> && ...
+  // we want the TreeTransform to expand only Pack2 but not Pack1,
+  // since Pack1 will be expanded during the evaluation of C.
+  // This flag helps rewrite any non-PackExpansion packs into "expanded"
+  // parameters.
+  bool RemovePacksForFoldExpr;
 
   SubstituteParameterMappings(Sema &SemaRef,
                               const MultiLevelTemplateArgumentList *MLTAL,
                               const ASTTemplateArgumentListInfo *ArgsAsWritten,
-                              bool InFoldExpr)
+                              bool RemovePacksForFoldExpr)
       : SemaRef(SemaRef), MLTAL(MLTAL), ArgsAsWritten(ArgsAsWritten),
-        InFoldExpr(InFoldExpr) {}
+        RemovePacksForFoldExpr(RemovePacksForFoldExpr) {}
 
   void buildParameterMapping(NormalizedConstraintWithParamMapping &N);
 
@@ -2016,9 +2031,10 @@ class SubstituteParameterMappings {
   bool substitute(ConceptIdConstraint &CC);
 
 public:
-  SubstituteParameterMappings(Sema &SemaRef, bool InFoldExpr = false)
+  SubstituteParameterMappings(Sema &SemaRef,
+                              bool RemovePacksForFoldExpr = false)
       : SemaRef(SemaRef), MLTAL(nullptr), ArgsAsWritten(nullptr),
-        InFoldExpr(InFoldExpr) {}
+        RemovePacksForFoldExpr(RemovePacksForFoldExpr) {}
 
   bool substitute(NormalizedConstraint &N);
 };
@@ -2121,8 +2137,7 @@ bool SubstituteParameterMappings::substitute(
   // which is wrong.
   TemplateArgumentListInfo SubstArgs;
   if (SemaRef.SubstTemplateArgumentsInParameterMapping(
-          N.getParameterMapping(), N.getBeginLoc(), *MLTAL, SubstArgs,
-          /*BuildPackExpansionTypes=*/!InFoldExpr))
+          N.getParameterMapping(), N.getBeginLoc(), *MLTAL, SubstArgs))
     return true;
   Sema::CheckTemplateArgumentInfo CTAI;
   auto *TD =
@@ -2192,8 +2207,7 @@ bool 
SubstituteParameterMappings::substitute(ConceptIdConstraint &CC) {
   const ASTTemplateArgumentListInfo *ArgsAsWritten =
       CSE->getTemplateArgsAsWritten();
   if (SemaRef.SubstTemplateArgumentsInParameterMapping(
-          ArgsAsWritten->arguments(), CC.getBeginLoc(), *MLTAL, Out,
-          /*BuildPackExpansionTypes=*/!InFoldExpr))
+          ArgsAsWritten->arguments(), CC.getBeginLoc(), *MLTAL, Out))
     return true;
   Sema::CheckTemplateArgumentInfo CTAI;
   if (SemaRef.CheckTemplateArgumentList(CSE->getNamedConcept(),
@@ -2206,7 +2220,7 @@ bool 
SubstituteParameterMappings::substitute(ConceptIdConstraint &CC) {
   TemplateArgs.replaceOutermostTemplateArguments(CSE->getNamedConcept(),
                                                  CTAI.SugaredConverted);
   return SubstituteParameterMappings(SemaRef, &TemplateArgs, ArgsAsWritten,
-                                     InFoldExpr)
+                                     RemovePacksForFoldExpr)
       .substitute(CC.getNormalizedConstraint());
 }
 
@@ -2222,13 +2236,13 @@ bool 
SubstituteParameterMappings::substitute(NormalizedConstraint &N) {
   case NormalizedConstraint::ConstraintKind::FoldExpanded: {
     auto &FE = static_cast<FoldExpandedConstraint &>(N);
     if (!MLTAL) {
-      llvm::SaveAndRestore _1(InFoldExpr, true);
+      llvm::SaveAndRestore _1(RemovePacksForFoldExpr, true);
       assert(!ArgsAsWritten);
       return substitute(FE.getNormalizedPattern());
     }
     Sema::ArgPackSubstIndexRAII _(SemaRef, std::nullopt);
     substitute(static_cast<NormalizedConstraintWithParamMapping &>(FE));
-    return SubstituteParameterMappings(SemaRef, /*InFoldExpr=*/true)
+    return SubstituteParameterMappings(SemaRef, 
/*RemovePacksForFoldExpr=*/true)
         .substitute(FE.getNormalizedPattern());
   }
   case NormalizedConstraint::ConstraintKind::ConceptId: {
@@ -2239,16 +2253,39 @@ bool 
SubstituteParameterMappings::substitute(NormalizedConstraint &N) {
     }
     assert(!ArgsAsWritten);
     const ConceptSpecializationExpr *CSE = CC.getConceptSpecializationExpr();
+    SmallVector<TemplateArgument> InnerArgs(CSE->getTemplateArguments());
     ConceptDecl *Concept = CSE->getNamedConcept();
+    if (RemovePacksForFoldExpr) {
+      TemplateArgumentListInfo OutArgs;
+      ArrayRef<TemplateArgumentLoc> InputArgLoc =
+          CSE->getConceptReference()->getTemplateArgsAsWritten()->arguments();
+      if (AdjustConstraints(SemaRef, /*TemplateDepth=*/0,
+                            /*RemoveNonPackExpansionPacks=*/true)
+              .TransformTemplateArguments(InputArgLoc.begin(),
+                                          InputArgLoc.end(), OutArgs))
+        return true;
+      Sema::CheckTemplateArgumentInfo CTAI;
+      // Repack the packs.
+      if (SemaRef.CheckTemplateArgumentList(
+              Concept, Concept->getTemplateParameters(), 
Concept->getBeginLoc(),
+              OutArgs,
+              /*DefaultArguments=*/{},
+              /*PartialTemplateArgs=*/false, CTAI))
+        return true;
+      InnerArgs = std::move(CTAI.SugaredConverted);
+      RemovePacksForFoldExpr = false;
+    }
+
     MultiLevelTemplateArgumentList MLTAL = 
SemaRef.getTemplateInstantiationArgs(
         Concept, Concept->getLexicalDeclContext(),
-        /*Final=*/true, CSE->getTemplateArguments(),
+        /*Final=*/true, InnerArgs,
         /*RelativeToPrimary=*/true,
         /*Pattern=*/nullptr,
         /*ForConstraintInstantiation=*/true);
 
-    return SubstituteParameterMappings(
-               SemaRef, &MLTAL, CSE->getTemplateArgsAsWritten(), InFoldExpr)
+    return SubstituteParameterMappings(SemaRef, &MLTAL,
+                                       CSE->getTemplateArgsAsWritten(),
+                                       RemovePacksForFoldExpr)
         .substitute(CC.getNormalizedConstraint());
   }
   case NormalizedConstraint::ConstraintKind::Compound: {
@@ -2496,12 +2533,12 @@ bool Sema::IsAtLeastAsConstrained(const NamedDecl *D1,
   for (size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) {
     if (Depth2 > Depth1) {
       AC1[I].ConstraintExpr =
-          AdjustConstraintDepth(*this, Depth2 - Depth1)
+          AdjustConstraints(*this, Depth2 - Depth1)
               .TransformExpr(const_cast<Expr *>(AC1[I].ConstraintExpr))
               .get();
     } else if (Depth1 > Depth2) {
       AC2[I].ConstraintExpr =
-          AdjustConstraintDepth(*this, Depth1 - Depth2)
+          AdjustConstraints(*this, Depth1 - Depth2)
               .TransformExpr(const_cast<Expr *>(AC2[I].ConstraintExpr))
               .get();
     }
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp 
b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 35205f40cbcef..50def4e181ab8 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1281,11 +1281,6 @@ namespace {
     // Whether an incomplete substituion should be treated as an error.
     bool BailOutOnIncomplete;
 
-    // Whether to rebuild pack expansion types; We don't do that when
-    // rebuilding the parameter mapping of a fold expression appearing
-    // in a constraint expression.
-    bool BuildPackExpansionTypes = true;
-
     // CWG2770: Function parameters should be instantiated when they are
     // needed by a satisfaction check of an atomic constraint or
     // (recursively) by another function parameter.
@@ -1313,11 +1308,9 @@ namespace {
 
     TemplateInstantiator(ForParameterMappingSubstitution_t, Sema &SemaRef,
                          SourceLocation Loc,
-                         const MultiLevelTemplateArgumentList &TemplateArgs,
-                         bool BuildPackExpansionTypes)
+                         const MultiLevelTemplateArgumentList &TemplateArgs)
         : inherited(SemaRef), TemplateArgs(TemplateArgs), Loc(Loc),
-          BailOutOnIncomplete(false),
-          BuildPackExpansionTypes(BuildPackExpansionTypes) {}
+          BailOutOnIncomplete(false) {}
 
     /// Determine whether the given type \p T has already been
     /// transformed.
@@ -1601,24 +1594,6 @@ namespace {
       return inherited::TransformTemplateArgument(Input, Output, Uneval);
     }
 
-    // This has to be here to allow its overload.
-    ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
-                                    UnsignedOrNone NumExpansions) {
-      return inherited::RebuildPackExpansion(Pattern, EllipsisLoc,
-                                             NumExpansions);
-    }
-
-    TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
-                                             SourceLocation EllipsisLoc,
-                                             UnsignedOrNone NumExpansions) {
-      // We don't rewrite a PackExpansion type when we want to normalize a
-      // CXXFoldExpr constraint. We'll expand it when evaluating the 
constraint.
-      if (BuildPackExpansionTypes)
-        return inherited::RebuildPackExpansion(Pattern, EllipsisLoc,
-                                               NumExpansions);
-      return Pattern;
-    }
-
     using TreeTransform::TransformTemplateSpecializationType;
     QualType
     TransformTemplateSpecializationType(TypeLocBuilder &TLB,
@@ -2446,7 +2421,14 @@ 
TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
     auto [AssociatedDecl, Final] =
         TemplateArgs.getAssociatedDecl(T->getDepth());
     UnsignedOrNone PackIndex = std::nullopt;
-    if (T->isParameterPack()) {
+    if (T->isParameterPack() ||
+        // In concept parameter mapping for fold expressions, packs that aren't
+        // expanded in place are treated as having non-pack dependency, so that
+        // a PackExpansionType won't prevent expanding the packs outside the
+        // TreeTransform. However, we still need to unpack the arguments during
+        // any template argument substitution, so we check the associated
+        // declaration instead.
+        (T->getDecl() && T->getDecl()->isTemplateParameterPack())) {
       assert(Arg.getKind() == TemplateArgument::Pack &&
              "Missing argument pack");
 
@@ -4340,10 +4322,10 @@ bool Sema::SubstTemplateArguments(
 bool Sema::SubstTemplateArgumentsInParameterMapping(
     ArrayRef<TemplateArgumentLoc> Args, SourceLocation BaseLoc,
     const MultiLevelTemplateArgumentList &TemplateArgs,
-    TemplateArgumentListInfo &Out, bool BuildPackExpansionTypes) {
+    TemplateArgumentListInfo &Out) {
   TemplateInstantiator Instantiator(
       TemplateInstantiator::ForParameterMappingSubstitution, *this, BaseLoc,
-      TemplateArgs, BuildPackExpansionTypes);
+      TemplateArgs);
   return Instantiator.TransformTemplateArguments(Args.begin(), Args.end(), 
Out);
 }
 
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index a53d578fc35ac..9057cf2482551 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -5179,7 +5179,7 @@ bool TreeTransform<Derived>::TransformTemplateArguments(
     if (In.getArgument().isPackExpansion()) {
       UnexpandedInfo Info;
       TemplateArgumentLoc Prepared;
-      if (PreparePackForExpansion(In, Uneval, Prepared, Info))
+      if (getDerived().PreparePackForExpansion(In, Uneval, Prepared, Info))
         return true;
       if (!Info.Expand) {
         Outputs.addArgument(Prepared);
diff --git a/clang/test/SemaCXX/cxx2c-fold-exprs.cpp 
b/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
index 289059ea86eb9..89ddcbaf11583 100644
--- a/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
+++ b/clang/test/SemaCXX/cxx2c-fold-exprs.cpp
@@ -491,4 +491,20 @@ void test() {
 
 }
 
+namespace GH177245 {
+
+template <class _Fun, class... _As>
+concept __callable = requires (_Fun __fun, _As...) { __fun(); };
+
+template <class... _Args>
+struct __mdispatch {
+  template <class... _Ts>
+    requires (__callable<_Args, _Ts...> && ...)
+  void operator()();
+};
+
+static_assert(!__callable<__mdispatch<int>>);
+
+}
+
 }

>From 5058aa9fe6f2b9d9294c1e3e53ea1fcf77ca4817 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Fri, 23 Jan 2026 15:33:24 +0800
Subject: [PATCH 2/2] Address feedback

---
 clang/lib/Sema/SemaConcept.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 2e2922f9b438a..f55f3a9a61ab8 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -2012,7 +2012,7 @@ class SubstituteParameterMappings {
   // When normalizing a fold constraint, e.g.
   //   C<Pack1, Pack2...> && ...
   // we want the TreeTransform to expand only Pack2 but not Pack1,
-  // since Pack1 will be expanded during the evaluation of C.
+  // since Pack1 will be expanded during the evaluation of the fold expression.
   // This flag helps rewrite any non-PackExpansion packs into "expanded"
   // parameters.
   bool RemovePacksForFoldExpr;
@@ -2273,7 +2273,6 @@ bool 
SubstituteParameterMappings::substitute(NormalizedConstraint &N) {
               /*PartialTemplateArgs=*/false, CTAI))
         return true;
       InnerArgs = std::move(CTAI.SugaredConverted);
-      RemovePacksForFoldExpr = false;
     }
 
     MultiLevelTemplateArgumentList MLTAL = 
SemaRef.getTemplateInstantiationArgs(

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to