<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/54678>54678</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Diagnostic for constraint satisfication failure can provide irrelevant information
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
brevzin
</td>
</tr>
</table>
<pre>
Here's an example:
```cpp
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.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzNV0tvozoU_jVkYzUiBkKyYNGmM7ojzTLSXRtjgivHztgmvZ1ff88xoaGdMCEjVVNEiLF9Xt95mdJUL8U_woqI5o4wTcR_bH9QIkruo_gxivvnMu5ufjh0M17ANuZh44Yr5lyUfOkWuNFcHDzZ2laQKHkkHgZR8jBkd5X4K1Ouo65xdCv5N2uFEkem_WQeZAtcyNHIitTGRHS1JT6ia2LFj1Za4QhOBUs2YWeUb-AeSDotIE1El3B3Rpz3P8Dv8arwktnLwn-R1Ksw0GqS8O4pAZs9kxo4B6r8hA6BqwMgpbDwihrOd7ql9Ptw4cy3j5GhmG0jCGdKOeINgbUh62UMAVfh7BvGMO0a06oKrcYNlUENayZVRDekFJy1EBxaSN8Ii-RgC1JpE96U0bvAhHnp6hec6sBYxnMy1A2g1zvCWwBWe_VCxF560LORjghrgVndMXyr88W0OL0mG2daywW6IrlfpPDI4Nexw4E2ALrnjQTBdau5l0YHMYhRgIjmQVx-3RtR9iXKw31ReAwPmnZCMdLuQYauZAVhR_r4I3IHoIkqrBrtvIWIAAyA4gSfFOCG7OEZsCbbkEwIdnY9jj8-icjlC2EZBSSnQ0D6UAK40SqaQ6iJofUvuNRp0HvkM5p86zUGEcbqIh9BqD7BQEBr1QICFcZrNzupdo9rcalw_NtI3hBIxZ0x1Xy48tB6Iv1otr6rJWON7HKMZH-UsUFkfqVOTkjZxQelbKiIE3L243vPrTmLiKTJSEQGs0aSdqDxhMz9a4bfgMUKg2OsfE1Ozt-ejG73zdt6Grr57_0yuZh-Jpf8kb8-UzHdYpVENRwpDZQF3zA_PCr96qnzmYmUUG9hbCZRDbyDxy2s1e9nsajLcxjedXwPzHpiangRpJLuqS-1jVFV8Psreu9PeBLjYhkH94PZUHLhlNir29kduFrBHDAMHQMPk25Ovvnw2fPUOo_fPgOtKsmgzjovOToGyUG2JXd35Dk0pu7sCGpxA0Qcjo8Yc4gInKhzMMeao6ygWutAfDpFgs6cOTGfVUVSrZM1m3nplSgez9JCa3mt672JnHV9B9RuLZ6o9VnCWWmpgXofts5aq4rG-4PDBki_wr2DhtCWc2728KLUsf-7A05PYAK8Suda4WCQpct8NWsKKlarNasXS5rUlPGsjrOE5rCYLeoyZ-VMsVIoV0C_iSjV4pkEFjCGfjOTBY0pjZNkAQziZDnP1qKul2kZp2KVpExEaSzgI0TNUY-5sbuZLYJKZbtzsKik8-68CBUCup8QQRzwZ61vjC1KK44_pZ4F0UVQ_X_NjD5b">