[PATCH] D156993: [clang] Error on substitution failure within lambda body inside a requires-expression

Mariya Podchishchaeva via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 3 05:27:04 PDT 2023


Fznamznon created this revision.
Herald added a project: All.
Fznamznon requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Per CWG 2672 substitution failure within the body of a lambda inside a
requires-expression should be a hard error.

Fixes https://github.com/llvm/llvm-project/issues/64138


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D156993

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/test/SemaCXX/lambda-unevaluated.cpp


Index: clang/test/SemaCXX/lambda-unevaluated.cpp
===================================================================
--- clang/test/SemaCXX/lambda-unevaluated.cpp
+++ clang/test/SemaCXX/lambda-unevaluated.cpp
@@ -155,17 +155,24 @@
 
 template <class T>
 concept lambda_works = requires {
-    []() { T::foo(); };
+    []() { T::foo(); }; // expected-error{{type 'int' cannot be used prior to '::'}}
+                        // expected-note at -1{{while substituting into a lambda expression here}}
+                        // expected-note at -2{{in instantiation of requirement here}}
+                        // expected-note at -4{{while substituting template arguments into constraint expression here}}
 };
 
-static_assert(!lambda_works<int>);
+static_assert(!lambda_works<int>); // expected-note {{while checking the satisfaction of concept 'lambda_works<int>' requested here}}
 static_assert(lambda_works<WithFoo>);
 
 template <class T>
-int* func(T) requires requires { []() { T::foo(); }; };
+int* func(T) requires requires { []() { T::foo(); }; }; // expected-error{{type 'int' cannot be used prior to '::'}}
+                                                        // expected-note at -1{{while substituting into a lambda expression here}}
+                                                        // expected-note at -2{{in instantiation of requirement here}}
+                                                        // expected-note at -3{{while substituting template arguments into constraint expression here}}
 double* func(...);
 
-static_assert(__is_same(decltype(func(0)), double*));
+static_assert(__is_same(decltype(func(0)), double*)); // expected-note {{while checking constraint satisfaction for template 'func<int>' required here}}
+                                                      // expected-note at -1 {{in instantiation of function template specialization 'lambda_in_constraints::func<int>'}}
 static_assert(__is_same(decltype(func(WithFoo())), int*));
 
 template <class T>
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1074,7 +1074,6 @@
   if (InNonInstantiationSFINAEContext)
     return std::optional<TemplateDeductionInfo *>(nullptr);
 
-  bool SawLambdaSubstitution = false;
   for (SmallVectorImpl<CodeSynthesisContext>::const_reverse_iterator
          Active = CodeSynthesisContexts.rbegin(),
          ActiveEnd = CodeSynthesisContexts.rend();
@@ -1101,10 +1100,7 @@
       // A lambda-expression appearing in a function type or a template
       // parameter is not considered part of the immediate context for the
       // purposes of template argument deduction.
-
-      // We need to check parents.
-      SawLambdaSubstitution = true;
-      break;
+      return std::nullopt;
 
     case CodeSynthesisContext::DefaultTemplateArgumentInstantiation:
     case CodeSynthesisContext::PriorTemplateArgumentSubstitution:
@@ -1120,8 +1116,6 @@
       // We're either substituting explicitly-specified template arguments,
       // deduced template arguments. SFINAE applies unless we are in a lambda
       // expression, see [temp.deduct]p9.
-      if (SawLambdaSubstitution)
-        return std::nullopt;
       [[fallthrough]];
     case CodeSynthesisContext::ConstraintSubstitution:
     case CodeSynthesisContext::RequirementInstantiation:
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -132,6 +132,10 @@
   (`#35574 <https://github.com/llvm/llvm-project/issues/35574>_`) and
   (`#27224 <https://github.com/llvm/llvm-project/issues/27224>_`).
 
+- Clang emits an error on substitution failure within lambda body inside a
+  requires-expression. This fixes:
+  (`#64138 <https://github.com/llvm/llvm-project/issues/64138>_`).
+
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
 - Fixed an import failure of recursive friend class template.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D156993.546817.patch
Type: text/x-patch
Size: 4067 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230803/2c8c5d6d/attachment-0001.bin>


More information about the cfe-commits mailing list