<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - deleted functions in requires clauses don't SFINAE in concepts"
   href="https://bugs.llvm.org/show_bug.cgi?id=44833">44833</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>deleted functions in requires clauses don't SFINAE in concepts
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Linux
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++2a
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>llvm@marehr.dialup.fu-berlin.de
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>blitzrakete@gmail.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Sorry for this verbose and hard to read code, but I wanted to make this
configurable.

This code basically has multiple code paths. If REQUIRES_BUG is set, the impl
function uses requires to infer if char_is_valid_for is defined or not. If not
impl uses SFINAE.

```c++
#include <utility>

// #define REQUIRES_BUG     1 - enable the requires bug, 0 - disable it
// #define FUNCTION_DEFINED 1 - define function char_is_valid_for, 0 - do not
define char_is_valid_for 

template <int I> struct priority_tag : priority_tag<I - 1> {};
template <> struct priority_tag<0> {};

struct alphabet_base {};

#if FUNCTION_DEFINED
using expect_return_type = bool;
bool char_is_valid_for(char, alphabet_base) { return true; };
#else
using expect_return_type = int;
#endif

namespace seqan3::detail::adl_only {

template <typename...> void char_is_valid_for(...) = delete;

template <typename alph_t>
struct char_is_valid_for_fn
{
    using s_alph_t = alph_t;

#if REQUIRES_BUG
    template <typename t>
    static decltype(auto) impl(priority_tag<1>, t v)
        requires requires { (char_is_valid_for(v, s_alph_t{})); }
    { return (char_is_valid_for(v, s_alph_t{})); }
#else
    template <typename t>
    static auto impl(priority_tag<1>, t v)
        -> std::enable_if_t<true, decltype(char_is_valid_for(v, s_alph_t{}))>
    { return (char_is_valid_for(v, s_alph_t{})); }
#endif

    template <typename t, typename = void>
    static decltype(auto) impl(priority_tag<0>, t v) { return 0; }
};
} // namespace seqan3::detail::adl_only

int main() {
  auto a =
seqan3::detail::adl_only::char_is_valid_for_fn<alphabet_base>::impl(priority_tag<1>{},
char{});
  static_assert(std::is_same_v<decltype(a), expect_return_type>);
}
```

As you can see on <a href="https://godbolt.org/z/tyeiJ2">https://godbolt.org/z/tyeiJ2</a> when defining `clang++
-std=c++2a -DREQUIRES_BUG=1 -DFUNCTION_DEFINED=0` the requires block should
silently see that the requires is not valid (because of a deleted function) and
skip to the next definition.

Error Message:

```
<source>:31:15: error: call to deleted function 'char_is_valid_for'
    { return (char_is_valid_for(v, s_alph_t{})); }
              ^~~~~~~~~~~~~~~~~

<source>:45:75: note: in instantiation of function template specialization
'seqan3::detail::adl_only::char_is_valid_for_fn<alphabet_base>::impl<char>'
requested here

  auto a =
seqan3::detail::adl_only::char_is_valid_for_fn<alphabet_base>::impl(priority_tag<1>{},
char{});
                                                                          ^

<source>:20:29: note: candidate function [with $0 = <>] has been explicitly
deleted
template <typename...> void char_is_valid_for(...) = delete;
                            ^

<source>:45:8: error: variable has incomplete type 'void'
  auto a =
seqan3::detail::adl_only::char_is_valid_for_fn<alphabet_base>::impl(priority_tag<1>{},
char{});
       ^

2 errors generated.
```


Interestingly, if you substitute `s_alph_t` with `alph_t;` everything works as
expected.</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>