https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102775

--- Comment #2 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Here's another example:

#include <limits>
int i = numeric_limits<double>::digits10;

lim.cc:2:9: error: 'numeric_limits' was not declared in this scope; did you
mean 'std::numeric_limits'?
    2 | int i = numeric_limits<double>::digits10;
      |         ^~~~~~~~~~~~~~
      |         std::numeric_limits
In file included from lim.cc:1:
/home/jwakely/gcc/14/include/c++/14.0.0/limits:312:12: note:
'std::numeric_limits' declared here
  312 |     struct numeric_limits : public __numeric_limits_base
      |            ^~~~~~~~~~~~~~
lim.cc:2:24: error: expected primary-expression before 'double'
    2 | int i = numeric_limits<double>::digits10;
      |                        ^~~~~~

The "expected primary-expression before 'double'" part is just noise. There's
only one problem in the code, and if you add the suggested "std::"
qualification then the code is valid.

If we treated "numeric_limits" as an alias for "std::numeric_limits" after the
first error, then the rest of the file would compile successfully. We'd still
give an error and the code would be ill-formed, but we'd only complain about
the one location that actually has a bug.

Presumably to make this work we would need to make the result of the "did you
mean" lookup available to the compiler (not just to the diagnostic machinery).
If there's a match, like std::numeric_limits in this case, then do name lookup
for that and if it's found and is a type then act as though we'd seen a
using-declaration/typedef for that name to make it available as just
"numeric_limits".

For a name where the match is the same name but with a namespace qualification,
a using-declaration would suffice to make it available with the unqualified
name. For a misspelled name where the match is spelled differently, we could
introduce a typedef (for types) or reference (for objects and functions) to
make the name usable with the misspelled name.

Sometimes doing this might make the code even more invalid and produce
additional diagnostics that wouldn't be present today. I think it would need to
be tried and tested on a variety of code to see whether it's usually an
improvement or makes things worse. I suspect that for the majority of code with
a single mistake (like using a name unqualified) it would help.

Introducing these aliases for unqualified/misspelled names could potentially
also change the meaning of the following code to make it something different
from what was really intended, e.g. a fix-it for "foo()" suggests "Foo()" but
the user actually meant to call "food()". The code has already hit an error and
so we'll never generate wrong code, so this can only result in additional
spurious diagnostics that wouldn't be emitted today.

Reply via email to