https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122531
--- Comment #3 from Jonathan Wakely <redi at gcc dot gnu.org> ---
I know what you're trying to achieve here, but I think it's misguided. Making
the diagnostics informative but not overwhelming is a much harder problem than
just "don't expand typedefs".
If we take the output of your example and remove the {aka ...} output we get:
aka.cc: In function 'int main()':
aka.cc:5:9: error: no match for 'operator=' (operand types are 'const
std::string' and 'const char [5]')
5 | a = "oops";
| ^~~~~~
* there are 6 candidates
In file included from /home/jwakely/gcc/16/include/c++/16.0.1/string:58,
from aka.cc:1:
* candidate 1: 'constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(const
std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char;
_Traits = std::char_traits<char>; _Alloc = std::allocator<char>]' (near match)
/home/jwakely/gcc/16/include/c++/16.0.1/bits/basic_string.h:929:7:
929 | operator=(const basic_string& __str)
| ^~~~~~~~
* passing 'const std::string*' as 'this' argument discards qualifiers
* candidate 2: 'constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(const
_CharT*) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc =
std::allocator<char>]' (near match)
/home/jwakely/gcc/16/include/c++/16.0.1/bits/basic_string.h:940:7:
940 | operator=(const _CharT* __s)
| ^~~~~~~~
* passing 'const std::string*' as 'this' argument discards qualifiers
* candidate 3: 'constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(_CharT)
[with _CharT = char; _Traits = std::char_traits<char>; _Alloc =
std::allocator<char>]' (near match)
/home/jwakely/gcc/16/include/c++/16.0.1/bits/basic_string.h:952:7:
952 | operator=(_CharT __c)
| ^~~~~~~~
* conversion of argument 1 would be ill-formed:
* error: invalid conversion from 'const char*' to 'char' [-fpermissive]
aka.cc:5:9:
5 | a = "oops";
| ^~~~~~
| |
| const char*
* candidate 4: 'constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>& std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>::operator=(std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&&) [with
_CharT = char; _Traits = std::char_traits<char>; _Alloc =
std::allocator<char>]' (near match)
/home/jwakely/gcc/16/include/c++/16.0.1/bits/basic_string.h:970:7:
970 | operator=(basic_string&& __str)
| ^~~~~~~~
* passing 'const std::string*' as 'this' argument discards qualifiers
* candidate 5: 'template<class _Tp> constexpr
std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_If_sv<_Tp,
std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&>
std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(const _Tp&)
[with _CharT = char; _Traits = std::char_traits<char>; _Alloc =
std::allocator<char>]'
/home/jwakely/gcc/16/include/c++/16.0.1/bits/basic_string.h:1053:8:
1053 | operator=(const _Tp& __svt)
| ^~~~~~~~
* template argument deduction/substitution failed:
In file included from
/home/jwakely/gcc/16/include/c++/16.0.1/bits/char_traits.h:52,
from /home/jwakely/gcc/16/include/c++/16.0.1/string:45:
* /home/jwakely/gcc/16/include/c++/16.0.1/type_traits: In substitution
of 'template<bool _Cond, class _Tp> using std::enable_if_t = typename
std::enable_if::type [with bool _Cond = false; _Tp =
std::__cxx11::basic_string<char>&]':
* required by substitution of 'template<class _CharT, class _Traits,
class _Alloc> template<class _Tp, class _Res> using
std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::_If_sv =
std::enable_if_t<((bool)std::__and_<std::is_convertible<const _Tp&,
std::basic_string_view<_CharT, _Traits> >,
std::__not_<std::is_convertible<const _Tp*, const
std::__cxx11::basic_string<_CharT, _Traits, _Alloc>*> >,
std::__not_<std::is_convertible<const _Tp&, const _CharT*> > >::value), _Res>
[with _Tp = char [5]; _Res = std::__cxx11::basic_string<char>&; _CharT = char;
_Traits = std::char_traits<char>; _Alloc = std::allocator<char>]'
/home/jwakely/gcc/16/include/c++/16.0.1/bits/basic_string.h:160:8:
160 | using _If_sv = enable_if_t<
| ^~~~~~
* required by substitution of 'template<class _Tp> constexpr
std::__cxx11::basic_string<char>::_If_sv<_Tp,
std::__cxx11::basic_string<char>&>
std::__cxx11::basic_string<char>::operator=(const _Tp&) [with _Tp = char [5]]'
/home/jwakely/gcc/16/include/c++/16.0.1/bits/basic_string.h:1053:8:
1053 | operator=(const _Tp& __svt)
| ^~~~~~~~
* required from here
aka.cc:5:9:
5 | a = "oops";
| ^~~~~~
* error: no type named 'type' in 'struct std::enable_if<false,
std::__cxx11::basic_string<char>&>'
/home/jwakely/gcc/16/include/c++/16.0.1/type_traits:2942:11:
2942 | using enable_if_t = typename enable_if<_Cond, _Tp>::type;
| ^~~~~~~~~~~
* candidate 6: 'constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>& std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>::operator=(std::initializer_list<_Tp>) [with _CharT = char; _Traits =
std::char_traits<char>; _Alloc = std::allocator<char>]'
/home/jwakely/gcc/16/include/c++/16.0.1/bits/basic_string.h:1038:7:
1038 | operator=(initializer_list<_CharT> __l)
| ^~~~~~~~
* no known conversion for argument 1 from 'const char [5]' to
'std::initializer_list<char>'
/home/jwakely/gcc/16/include/c++/16.0.1/bits/basic_string.h:1038:42:
1038 | operator=(initializer_list<_CharT> __l)
| ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
Is that actually any better? Clearly not.
There are four occurrences of {aka ...} in the output, for a total of 191
bytes, out of more than 6000 bytes. Removing those 191 bytes does not make any
substantial difference to the verbosity, and it makes it objectively worse
because now there is no obvious connection between the type in the expression:
(operand types are 'const std::string' and 'const char [5]')
and the 6 candidates that are shown:
* candidate 1: 'constexpr std::__cxx11::basic_string<_CharT, _Traits,
_Alloc>& std::__cxx11::basic_string<_CharT, _Traits, _Alloc>::operator=(const
std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char;
_Traits = std::char_traits<char>; _Alloc = std::allocator<char>]' (near match)
Removing the {aka ...} parts does not affect the display of the overload
resolution candidates, all it does is remove the clue that links the types used
in the expression to the candidates. You say you don't want to know about
__cxx11::basic_string but at least in the current diagnostic there is something
telling you that relationship exists. With your proposal, you just have to
*know* a priori that std::string and std::__cxx11::basic_string<char> are the
same thing.
Bug 89370 would be a real improvement, but removing the aka information would
not.