Closed
Description
Here's an example:
template<class>
concept True = true;
template<class>
concept False = false;
template<class>
concept Irrelevant = false;
template<class T> void foo(T t) requires (True<T> || Irrelevant<T>) && False<T> { }
template<class T> void bar(T t) requires (Irrelevant<T> || True<T>) && False<T> { }
int main() {
foo(42);
bar(42L);
}
The calls to foo(42)
and bar(42L)
should (and do) fail, because neither int
nor long
satisfy False
.
clang currently emits this error for foo(42)
<source>:14:5: error: no matching function for call to 'foo'
foo(42);
^~~
<source>:10:24: note: candidate template ignored: constraints not satisfied [with T = int]
template<class T> void foo(T t) requires (True<T> || Irrelevant<T>) && False<T> { }
^
<source>:10:72: note: because 'int' does not satisfy 'False'
template<class T> void foo(T t) requires (True<T> || Irrelevant<T>) && False<T> { }
^
<source>:5:17: note: because 'false' evaluated to false
concept False = false;
^
Which is good.
But it emits this error for bar(42L)
:
<source>:15:5: error: no matching function for call to 'bar'
bar(42L);
^~~
<source>:11:24: note: candidate template ignored: constraints not satisfied [with T = long]
template<class T> void bar(T t) requires (Irrelevant<T> || True<T>) && False<T> { }
^
<source>:11:43: note: because 'long' does not satisfy 'Irrelevant'
template<class T> void bar(T t) requires (Irrelevant<T> || True<T>) && False<T> { }
^
<source>:8:22: note: because 'false' evaluated to false
concept Irrelevant = false;
^
<source>:11:72: note: and 'long' does not satisfy 'False'
template<class T> void bar(T t) requires (Irrelevant<T> || True<T>) && False<T> { }
^
<source>:5:17: note: because 'false' evaluated to false
concept False = false;
^
This notes both that long
does not satisfy False
but also that long
does not satisfy Irrelevant
. But Irrelevant
is irrelevant - that part of the disjunction holds (because long
satisfies True
), so that is not the reason this fails. It's just an irrelevant diagnostic to the user -- which clang (correctly) doesn't provide in the foo
case.