[Bug c++/71125] [concepts] Spurious 'invalid reference to function concept error' issued when overloads are not all declared with the concept specifier
redi at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Mon Oct 14 22:39:00 GMT 2019
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71125
Jonathan Wakely <redi at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Keywords| |diagnostic
Status|WAITING |NEW
Severity|normal |enhancement
--- Comment #4 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Casey Carter from comment #2)
> (In reply to Jonathan Wakely from comment #1)
> > Is this valid in C++20?
>
> Definitely not: there are no concept functions in C++20.
Right, sorry I was unclear ... I modernised Tom's original code to use C++20
syntax, which still fails to compile, and was asking about that version ...
which I didn't actually post and somehow expected everybody to know what I
meant. Oops.
The code I tested was:
template<typename T>
constexpr bool C1() { return true; }
template<typename T, typename U>
concept C1 = true;
template<typename T>
requires C1<T>
void f1() {}
// Removing the unused overload avoids the error:
template<typename T>
constexpr bool C2() { return true; }
template<typename T>
requires C2<T> // Ok.
void f2() {}
// Swapping the order of the declarations avoids the error:
template<typename T, typename U>
concept C3 = true;
template<typename T>
constexpr bool C3() { return true; }
template<typename T>
requires C3<T> // Ok.
void f3() {}
// Swapping the overload that is resolved avoids the error:
template<typename T>
constexpr bool C4() { return true; }
template<typename T, typename U>
concept C4 = true;
template<typename T>
requires C4<T,int> // Ok.
void f4() {}
// Swapping which overload is declared with the concept specifier avoids the
error:
template<typename T>
concept C5 = true;
template<typename T, typename U>
constexpr bool C5() { return true; }
template<typename T>
requires C5<T> // Ok.
void f5() {}
And the diagnostics from trunk are:
71125.cc:4:18: error: 'template<class T, class U> concept C1' conflicts with a
previous declaration
4 | concept C1 = true;
| ^
71125.cc:2:16: note: previous declaration 'constexpr bool C1()'
2 | constexpr bool C1() { return true; }
| ^~
71125.cc:6:12: error: constraint expression does not have type 'bool'
6 | requires C1<T>
| ^~~~~
71125.cc:13:12: error: constraint expression does not have type 'bool'
13 | requires C2<T> // Ok.
| ^~~~~
71125.cc:20:19: error: 'template<class T> constexpr bool C3()' conflicts with a
previous declaration
20 | constexpr bool C3() { return true; }
| ^
71125.cc:18:9: note: previous declaration 'template<class T, class U> concept
C3'
18 | concept C3 = true;
| ^~
71125.cc:22:12: error: wrong number of template arguments (1, should be 2)
22 | requires C3<T> // Ok.
| ^~~~~
71125.cc:18:9: note: provided for 'template<class T, class U> concept C3'
18 | concept C3 = true;
| ^~
71125.cc:29:18: error: 'template<class T, class U> concept C4' conflicts with a
previous declaration
29 | concept C4 = true;
| ^
71125.cc:27:16: note: previous declaration 'constexpr bool C4()'
27 | constexpr bool C4() { return true; }
| ^~
71125.cc:31:12: error: constraint expression does not have type 'bool'
31 | requires C4<T,int> // Ok.
| ^~~~~~~~~
71125.cc:38:19: error: 'template<class T, class U> constexpr bool C5()'
conflicts with a previous declaration
38 | constexpr bool C5() { return true; }
| ^
71125.cc:36:9: note: previous declaration 'template<class T> concept C5'
36 | concept C5 = true;
| ^~
I think the "conflicts with a previous declaration" diagnostic is reasonable.
Maybe "redeclared as a different kind of symbol" would also work.
I'll recategorise it as a diagnostic enhancement and confirm it, but I think
closing it would also be fine.
More information about the Gcc-bugs
mailing list