Issue |
123306
|
Summary |
Compiler error for requires _expression_ inside templated lambda due to missing delayed template specialization?
|
Labels |
new issue
|
Assignees |
|
Reporter |
rath3t
|
Hello everyone,
tl;dr:
https://godbolt.org/z/Wca74vn1e delayed template specialization might not work for lambda4Templated and lambda6Templated.
Long version:
I witnessed the following problem with templated lambdas and requires expressions:
I have the following class definition
```cpp
template <bool v>
struct A {
static auto foo() requires v;
};
```
and the following function
```cpp
template <bool v>
void bar(A<v> a4) {
if constexpr (v) return A<v>::foo(); // does compile with clang,gcc,msvc
if constexpr (v)
return A<false>::foo(); // does NOT compile with clang,gcc, (as it
// should?)
auto lambda = []() {
if constexpr (v)
return A<v>::foo(); // does compile with clang,gcc,msvc
};
auto lambda2 = []() {
if constexpr (v)
return A<false>::foo(); // does NOT compile with clang,gcc (as it should?)
};
A<false> a; // explicit false as template
auto lambda3 = [a]() {
if constexpr (v)
return a.foo(); // does NOT compile with clang (as it should?)
};
auto lambda3T = [a]<bool vL>() {
if constexpr (vL)
return a.foo(); // does NOT compile with clang (as it should?)
};
A<v> a2;
auto lambda4 = [a2]() {
if constexpr (v) return a2.foo(); // does compile with clang,gcc,msvc
};
auto lambda4Templated = [a2]<bool vL>() {
if constexpr (vL) return a2.foo(); // does NOT compile with clang
};
auto lambda5 = []() {
A<v> a3;
if constexpr (v) return a3.foo(); // does compile with clang,gcc,msvc
};
auto lambda5Templated = []<bool vL>() {
A<vL> a3;
if constexpr (vL) return a3.foo(); // does compile with clang,gcc,msvc
};
auto lambda6 = [a4]() {
if constexpr (v) return a4.foo(); // does compile with clang,gcc,msvc
};
auto lambda6Templated = [a4]<bool vL>() {
if constexpr (vL) return a4.foo(); // does NOT compile with clang
};
auto lambda7 = []<bool vL>() {
if constexpr (vL)
return A<vL>::foo(); // does compile with clang,gcc,msvc
};
}
int main() { bar(A<false>{}); }
```
I tried several versions of the lambdas and I think the behavior is as expected _except_ for the `lambda4/lambda4Templated` and the `lambda6/lambda6Templated` pairs. It all depends I think on the delayed or not delayed instantiation of the `A<...>::foo()` in the other cases, but for the lambda4/6 cases I would expect that both or neither of them work.
In particular I think `lambda4Templated/lambda6Templated` should compile.
If I look into https://eel.is/c++draft/temp.point#1 and if I understand the following correctly
> [...] if the specialization is implicitly instantiated because it is referenced from within another template specialization and the context from which it is referenced depends on a template parameter, the point of instantiation of the specialization **is the point of instantiation of the enclosing specialization**[.](https://eel.is/c++draft/temp.point#1.sentence-1)
Then the instantiation of the .foo() called should be delayed until I instantiation the `lambda4Template` and `lambda6Template`, like `lambda4Template.template operator()<false>()`.
Thanks for your help! I have no idea how I can contribute but if this is actually a bug, I would be willing to do so, if someone is giving me some pointers.
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs