[PATCH] D154368: [Clang] Fix constraint checking of non-generic lambdas.

2023-07-21 Thread Corentin Jabot via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGf9caa12328b2: [Clang] Fix constraint checking of non-generic 
lambdas. (authored by cor3ntin).

Changed prior to commit:
  https://reviews.llvm.org/D154368?vs=541858=542806#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154368/new/

https://reviews.llvm.org/D154368

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/SemaTemplate/concepts.cpp

Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -410,8 +410,8 @@
 
 template 
 void SingleDepthReferencesTopLambda(U &) {
-  []()
-requires IsInt
+  []() // #SDRTL_OP
+requires IsInt // #SDRTL_REQ
   {}();
 }
 
@@ -434,8 +434,8 @@
 
 template 
 void DoubleDepthReferencesTopLambda(U &) {
-  []() { []()
-   requires IsInt
+  []() { []() // #DDRTL_OP
+   requires IsInt // #DDRTL_REQ
  {}(); }();
 }
 
@@ -459,10 +459,11 @@
 
 template 
 void DoubleDepthReferencesAllLambda(U &) {
-  [](U &) {
-[](U && u3)
-  requires IsInt &&
-   IsInt && IsInt
+  [](U &) { // #DDRAL_OP1
+[](U && u3) // #DDRAL_OP2
+  requires IsInt // #DDRAL_REQ
+&& IsInt
+&& IsInt
 {}(u2);
   }(u);
 }
@@ -484,8 +485,8 @@
 template 
 void ChecksLocalVar(T x) {
   T Local;
-  []()
-requires(IsInt)
+  []() // #CLV_OP
+requires(IsInt) // #CLV_REQ
   {}();
 }
 
@@ -527,8 +528,12 @@
   SingleDepthReferencesTopNotCalled(will_fail);
   SingleDepthReferencesTopCalled(v); // #SDRTC
   SingleDepthReferencesTopLambda(v);
-  // FIXME: This should error on constraint failure! (Lambda!)
   SingleDepthReferencesTopLambda(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-error@#SDRTL_OP{{no matching function for call to object of type}}
+  // expected-note@#SDRTL_OP{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#SDRTL_REQ{{because 'IsInt' evaluated to false}}
+
   DoubleDepthReferencesTop(v);
   DoubleDepthReferencesTop(will_fail);
   // expected-error@#DDRT_CALL{{no matching function for call to object of type 'lc2'}}
@@ -538,8 +543,12 @@
   // expected-note@#DDRT_REQ{{'IsInt' evaluated to false}}
 
   DoubleDepthReferencesTopLambda(v);
-  // FIXME: This should error on constraint failure! (Lambda!)
   DoubleDepthReferencesTopLambda(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-error@#DDRTL_OP{{no matching function for call to object of type}}
+  // expected-note@#DDRTL_OP{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#DDRTL_OP{{while substituting into a lambda expression here}}
+  // expected-note@#DDRTL_REQ{{because 'IsInt' evaluated to false}}
   DoubleDepthReferencesAll(v);
   DoubleDepthReferencesAll(will_fail);
   // expected-error@#DDRA_CALL{{no matching function for call to object of type 'lc2'}}
@@ -549,8 +558,12 @@
   // expected-note@#DDRA_REQ{{'IsInt' evaluated to false}}
 
   DoubleDepthReferencesAllLambda(v);
-  // FIXME: This should error on constraint failure! (Lambda!)
   DoubleDepthReferencesAllLambda(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-note@#DDRAL_OP1{{while substituting into a lambda expression here}}
+  // expected-error@#DDRAL_OP2{{no matching function for call to object of type}}
+  // expected-note@#DDRAL_OP2{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#DDRAL_REQ{{because 'IsInt' evaluated to false}}
 
   CausesFriendConstraint CFC;
   FriendFunc(CFC, 1);
@@ -563,8 +576,13 @@
   // ChecksCapture(v);
 
   ChecksLocalVar(v);
-  // FIXME: This should error on constraint failure! (Lambda!)
   ChecksLocalVar(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-error@#CLV_OP{{no matching function for call to object of type}}
+  // expected-note@#CLV_OP{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#CLV_REQ{{because 'IsInt' evaluated to false}}
+
+
 
   LocalStructMemberVar(v);
   LocalStructMemberVar(will_fail);
@@ -701,6 +719,18 @@
 } // namespace SelfFriend
 
 
+namespace Surrogates {
+int f1(int);
+template 
+struct A {
+using F = int(int);
+operator F*() requires N { return f1; } // expected-note{{conversion candidate 'operator int (*)(int)' not viable: constraints not satisfied}}
+};
+int i = A{}(0);
+int j = A{}(0); // expected-error{{no matching function for call to object of type 'A'}}
+}
+
+
 namespace ConstrainedMemberVarTemplate {
 template  struct Container {
   static constexpr long 

[PATCH] D154368: [Clang] Fix constraint checking of non-generic lambdas.

2023-07-20 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM aside from some questions about comments in the test.




Comment at: clang/test/SemaTemplate/concepts.cpp:531
   SingleDepthReferencesTopLambda(v);
   // FIXME: This should error on constraint failure! (Lambda!)
   SingleDepthReferencesTopLambda(will_fail);

Comment is now stale and can be removed?



Comment at: clang/test/SemaTemplate/concepts.cpp:580
   ChecksLocalVar(v);
   // FIXME: This should error on constraint failure! (Lambda!)
   ChecksLocalVar(will_fail);

This one can also be removed?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154368/new/

https://reviews.llvm.org/D154368

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D154368: [Clang] Fix constraint checking of non-generic lambdas.

2023-07-19 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 541858.
cor3ntin marked 3 inline comments as done.
cor3ntin added a comment.

Address Aaron's feedback


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154368/new/

https://reviews.llvm.org/D154368

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/SemaTemplate/concepts.cpp

Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -410,8 +410,8 @@
 
 template 
 void SingleDepthReferencesTopLambda(U &) {
-  []()
-requires IsInt
+  []() // #SDRTL_OP
+requires IsInt // #SDRTL_REQ
   {}();
 }
 
@@ -434,8 +434,8 @@
 
 template 
 void DoubleDepthReferencesTopLambda(U &) {
-  []() { []()
-   requires IsInt
+  []() { []() // #DDRTL_OP
+   requires IsInt // #DDRTL_REQ
  {}(); }();
 }
 
@@ -459,10 +459,11 @@
 
 template 
 void DoubleDepthReferencesAllLambda(U &) {
-  [](U &) {
-[](U && u3)
-  requires IsInt &&
-   IsInt && IsInt
+  [](U &) { // #DDRAL_OP1
+[](U && u3) // #DDRAL_OP2
+  requires IsInt // #DDRAL_REQ
+&& IsInt
+&& IsInt
 {}(u2);
   }(u);
 }
@@ -484,8 +485,8 @@
 template 
 void ChecksLocalVar(T x) {
   T Local;
-  []()
-requires(IsInt)
+  []() // #CLV_OP
+requires(IsInt) // #CLV_REQ
   {}();
 }
 
@@ -529,6 +530,11 @@
   SingleDepthReferencesTopLambda(v);
   // FIXME: This should error on constraint failure! (Lambda!)
   SingleDepthReferencesTopLambda(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-error@#SDRTL_OP{{no matching function for call to object of type}}
+  // expected-note@#SDRTL_OP{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#SDRTL_REQ{{because 'IsInt' evaluated to false}}
+
   DoubleDepthReferencesTop(v);
   DoubleDepthReferencesTop(will_fail);
   // expected-error@#DDRT_CALL{{no matching function for call to object of type 'lc2'}}
@@ -538,8 +544,12 @@
   // expected-note@#DDRT_REQ{{'IsInt' evaluated to false}}
 
   DoubleDepthReferencesTopLambda(v);
-  // FIXME: This should error on constraint failure! (Lambda!)
   DoubleDepthReferencesTopLambda(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-error@#DDRTL_OP{{no matching function for call to object of type}}
+  // expected-note@#DDRTL_OP{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#DDRTL_OP{{while substituting into a lambda expression here}}
+  // expected-note@#DDRTL_REQ{{because 'IsInt' evaluated to false}}
   DoubleDepthReferencesAll(v);
   DoubleDepthReferencesAll(will_fail);
   // expected-error@#DDRA_CALL{{no matching function for call to object of type 'lc2'}}
@@ -549,8 +559,12 @@
   // expected-note@#DDRA_REQ{{'IsInt' evaluated to false}}
 
   DoubleDepthReferencesAllLambda(v);
-  // FIXME: This should error on constraint failure! (Lambda!)
   DoubleDepthReferencesAllLambda(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-note@#DDRAL_OP1{{while substituting into a lambda expression here}}
+  // expected-error@#DDRAL_OP2{{no matching function for call to object of type}}
+  // expected-note@#DDRAL_OP2{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#DDRAL_REQ{{because 'IsInt' evaluated to false}}
 
   CausesFriendConstraint CFC;
   FriendFunc(CFC, 1);
@@ -565,6 +579,12 @@
   ChecksLocalVar(v);
   // FIXME: This should error on constraint failure! (Lambda!)
   ChecksLocalVar(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-error@#CLV_OP{{no matching function for call to object of type}}
+  // expected-note@#CLV_OP{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#CLV_REQ{{because 'IsInt' evaluated to false}}
+
+
 
   LocalStructMemberVar(v);
   LocalStructMemberVar(will_fail);
@@ -701,6 +721,18 @@
 } // namespace SelfFriend
 
 
+namespace Surrogates {
+int f1(int);
+template 
+struct A {
+using F = int(int);
+operator F*() requires N { return f1; } // expected-note{{conversion candidate 'operator int (*)(int)' not viable: constraints not satisfied}}
+};
+int i = A{}(0);
+int j = A{}(0); // expected-error{{no matching function for call to object of type 'A'}}
+}
+
+
 namespace ConstrainedMemberVarTemplate {
 template  struct Container {
   static constexpr long arity = Size;
@@ -914,3 +946,53 @@
 
 static_assert(W0<0>::W1<1>::F::value == 1);
 } // TemplateInsideTemplateInsideTemplate
+
+
+namespace GH63181 {
+
+template void f() {
+auto l = []() requires N { }; // expected-note 2{{candidate function not 

[PATCH] D154368: [Clang] Fix constraint checking of non-generic lambdas.

2023-07-18 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang/include/clang/Basic/DiagnosticSemaKinds.td:4718-4719
+def note_ovl_surrogate_constraints_not_satisfied : Note<
+"candidate surrogate function %0 not viable: constraints "
+"not satisfied">;
 def note_implicit_member_target_infer_collision : Note<

I think "candidate surrogate function" is a bit... technical for a user-facing 
diagnostic (we don't seem to use it any other diagnostics). Perhaps we should 
go with `conversion candidate function` instead as we did for 
`note_ovl_surrogate_cand`?



Comment at: clang/lib/Sema/SemaConcept.cpp:685
+  // (and may refer to its parameters), so check the call operator instead.
+  if (const CXXConversionDecl *MD = dyn_cast(FD);
+  MD && isLambdaConversionOperator(const_cast(MD)))





Comment at: clang/lib/Sema/SemaLambda.cpp:1636-1638
+  // A non-generic lambda may still be a templated entity
+  // We need to preserve constraints when converting the
+  // lambda to a function pointer. See GH63181.





Comment at: clang/lib/Sema/SemaOverload.cpp:14973
+  // conversion operator as the constraints are always the same.
+  // As the user probably do not intend to perform a surrogate call,
+  // we filter them out to produce better error diagnostics, ie to avoid




Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154368/new/

https://reviews.llvm.org/D154368

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D154368: [Clang] Fix constraint checking of non-generic lambdas.

2023-07-04 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin updated this revision to Diff 536976.
cor3ntin added a comment.

- Move the check for lambda conversion operator in CheckFunmctionConstraints so 
that it is always performed.

- Add tests of constraints referring to parameters of the lambda


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D154368/new/

https://reviews.llvm.org/D154368

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/SemaTemplate/concepts.cpp

Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -410,8 +410,8 @@
 
 template 
 void SingleDepthReferencesTopLambda(U &) {
-  []()
-requires IsInt
+  []() // #SDRTL_OP
+requires IsInt // #SDRTL_REQ
   {}();
 }
 
@@ -434,8 +434,8 @@
 
 template 
 void DoubleDepthReferencesTopLambda(U &) {
-  []() { []()
-   requires IsInt
+  []() { []() // #DDRTL_OP
+   requires IsInt // #DDRTL_REQ
  {}(); }();
 }
 
@@ -459,10 +459,11 @@
 
 template 
 void DoubleDepthReferencesAllLambda(U &) {
-  [](U &) {
-[](U && u3)
-  requires IsInt &&
-   IsInt && IsInt
+  [](U &) { // #DDRAL_OP1
+[](U && u3) // #DDRAL_OP2
+  requires IsInt // #DDRAL_REQ
+&& IsInt
+&& IsInt
 {}(u2);
   }(u);
 }
@@ -484,8 +485,8 @@
 template 
 void ChecksLocalVar(T x) {
   T Local;
-  []()
-requires(IsInt)
+  []() // #CLV_OP
+requires(IsInt) // #CLV_REQ
   {}();
 }
 
@@ -529,6 +530,11 @@
   SingleDepthReferencesTopLambda(v);
   // FIXME: This should error on constraint failure! (Lambda!)
   SingleDepthReferencesTopLambda(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-error@#SDRTL_OP{{no matching function for call to object of type}}
+  // expected-note@#SDRTL_OP{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#SDRTL_REQ{{because 'IsInt' evaluated to false}}
+
   DoubleDepthReferencesTop(v);
   DoubleDepthReferencesTop(will_fail);
   // expected-error@#DDRT_CALL{{no matching function for call to object of type 'lc2'}}
@@ -538,8 +544,12 @@
   // expected-note@#DDRT_REQ{{'IsInt' evaluated to false}}
 
   DoubleDepthReferencesTopLambda(v);
-  // FIXME: This should error on constraint failure! (Lambda!)
   DoubleDepthReferencesTopLambda(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-error@#DDRTL_OP{{no matching function for call to object of type}}
+  // expected-note@#DDRTL_OP{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#DDRTL_OP{{while substituting into a lambda expression here}}
+  // expected-note@#DDRTL_REQ{{because 'IsInt' evaluated to false}}
   DoubleDepthReferencesAll(v);
   DoubleDepthReferencesAll(will_fail);
   // expected-error@#DDRA_CALL{{no matching function for call to object of type 'lc2'}}
@@ -549,8 +559,12 @@
   // expected-note@#DDRA_REQ{{'IsInt' evaluated to false}}
 
   DoubleDepthReferencesAllLambda(v);
-  // FIXME: This should error on constraint failure! (Lambda!)
   DoubleDepthReferencesAllLambda(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-note@#DDRAL_OP1{{while substituting into a lambda expression here}}
+  // expected-error@#DDRAL_OP2{{no matching function for call to object of type}}
+  // expected-note@#DDRAL_OP2{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#DDRAL_REQ{{because 'IsInt' evaluated to false}}
 
   CausesFriendConstraint CFC;
   FriendFunc(CFC, 1);
@@ -565,6 +579,12 @@
   ChecksLocalVar(v);
   // FIXME: This should error on constraint failure! (Lambda!)
   ChecksLocalVar(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-error@#CLV_OP{{no matching function for call to object of type}}
+  // expected-note@#CLV_OP{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#CLV_REQ{{because 'IsInt' evaluated to false}}
+
+
 
   LocalStructMemberVar(v);
   LocalStructMemberVar(will_fail);
@@ -701,6 +721,18 @@
 } // namespace SelfFriend
 
 
+namespace Surrogates {
+int f1(int);
+template 
+struct A {
+using F = int(int);
+operator F*() requires N { return f1; } // expected-note{{candidate surrogate function 'operator int (*)(int)' not viable: constraints not satisfied}}
+};
+int i = A{}(0);
+int j = A{}(0); // expected-error{{no matching function for call to object of type 'A'}}
+}
+
+
 namespace ConstrainedMemberVarTemplate {
 template  struct Container {
   static constexpr long arity = Size;
@@ -914,3 +946,53 @@
 
 static_assert(W0<0>::W1<1>::F::value == 1);
 } // TemplateInsideTemplateInsideTemplate
+
+

[PATCH] D154368: [Clang] Fix constraint checking of non-generic lambdas.

2023-07-03 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin created this revision.
Herald added a project: All.
cor3ntin requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

A lambda call operator can be a templated entity -
and therefore have constraints while not being a function template

  template void f() {
[]() requires false { }();
  }

In that case, we would check the constraints of the call operator
which is non-viable. However, we would find a viable candidate:
the conversion operator to function pointer, and use it to
perform a surrogate call.
These constraints were not checked because:

- We never check the constraints of surrogate functions
- The lambda conversion operator has non constraints.

>From the wording, it is not clear what the intent is but
it seems reasonable to expect the constraints of the lambda conversion
operator to be checked and it is consistent with GCC and MSVC.

This patch also improve the diagnostics for constraint failure
on surrogate calls.

Fixes #63181


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D154368

Files:
  clang/docs/ReleaseNotes.rst
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/SemaTemplate/concepts.cpp

Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -410,8 +410,8 @@
 
 template 
 void SingleDepthReferencesTopLambda(U &) {
-  []()
-requires IsInt
+  []() // #SDRTL_OP
+requires IsInt // #SDRTL_REQ
   {}();
 }
 
@@ -434,8 +434,8 @@
 
 template 
 void DoubleDepthReferencesTopLambda(U &) {
-  []() { []()
-   requires IsInt
+  []() { []() // #DDRTL_OP
+   requires IsInt // #DDRTL_REQ
  {}(); }();
 }
 
@@ -459,10 +459,11 @@
 
 template 
 void DoubleDepthReferencesAllLambda(U &) {
-  [](U &) {
-[](U && u3)
-  requires IsInt &&
-   IsInt && IsInt
+  [](U &) { // #DDRAL_OP1
+[](U && u3) // #DDRAL_OP2
+  requires IsInt // #DDRAL_REQ
+&& IsInt
+&& IsInt
 {}(u2);
   }(u);
 }
@@ -484,8 +485,8 @@
 template 
 void ChecksLocalVar(T x) {
   T Local;
-  []()
-requires(IsInt)
+  []() // #CLV_OP
+requires(IsInt) // #CLV_REQ
   {}();
 }
 
@@ -529,6 +530,11 @@
   SingleDepthReferencesTopLambda(v);
   // FIXME: This should error on constraint failure! (Lambda!)
   SingleDepthReferencesTopLambda(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-error@#SDRTL_OP{{no matching function for call to object of type}}
+  // expected-note@#SDRTL_OP{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#SDRTL_REQ{{because 'IsInt' evaluated to false}}
+
   DoubleDepthReferencesTop(v);
   DoubleDepthReferencesTop(will_fail);
   // expected-error@#DDRT_CALL{{no matching function for call to object of type 'lc2'}}
@@ -538,8 +544,12 @@
   // expected-note@#DDRT_REQ{{'IsInt' evaluated to false}}
 
   DoubleDepthReferencesTopLambda(v);
-  // FIXME: This should error on constraint failure! (Lambda!)
   DoubleDepthReferencesTopLambda(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-error@#DDRTL_OP{{no matching function for call to object of type}}
+  // expected-note@#DDRTL_OP{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#DDRTL_OP{{while substituting into a lambda expression here}}
+  // expected-note@#DDRTL_REQ{{because 'IsInt' evaluated to false}}
   DoubleDepthReferencesAll(v);
   DoubleDepthReferencesAll(will_fail);
   // expected-error@#DDRA_CALL{{no matching function for call to object of type 'lc2'}}
@@ -549,8 +559,12 @@
   // expected-note@#DDRA_REQ{{'IsInt' evaluated to false}}
 
   DoubleDepthReferencesAllLambda(v);
-  // FIXME: This should error on constraint failure! (Lambda!)
   DoubleDepthReferencesAllLambda(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-note@#DDRAL_OP1{{while substituting into a lambda expression here}}
+  // expected-error@#DDRAL_OP2{{no matching function for call to object of type}}
+  // expected-note@#DDRAL_OP2{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#DDRAL_REQ{{because 'IsInt' evaluated to false}}
 
   CausesFriendConstraint CFC;
   FriendFunc(CFC, 1);
@@ -565,6 +579,12 @@
   ChecksLocalVar(v);
   // FIXME: This should error on constraint failure! (Lambda!)
   ChecksLocalVar(will_fail);
+  // expected-note@-1{{in instantiation of function template specialization}}
+  // expected-error@#CLV_OP{{no matching function for call to object of type}}
+  // expected-note@#CLV_OP{{candidate function not viable: constraints not satisfied}}
+  // expected-note@#CLV_REQ{{because 'IsInt' evaluated to false}}
+
+
 
   LocalStructMemberVar(v);