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

Reply via email to