public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: David Malcolm <dmalcolm@redhat.com>
To: Martin Sebor <msebor@gmail.com>, gcc-patches@gcc.gnu.org
Cc: Jason Merrill <jason@redhat.com>
Subject: Re: [PATCH] v2: C++: suggestions for misspelled private members (PR c++/84993)
Date: Tue, 09 Oct 2018 15:09:00 -0000	[thread overview]
Message-ID: <1539094923.14521.134.camel@redhat.com> (raw)
In-Reply-To: <36d5eaee-2c66-715f-ce4b-d243d711a744@gmail.com>

On Mon, 2018-09-24 at 10:56 -0600, Martin Sebor wrote:
> On 09/21/2018 04:09 PM, David Malcolm wrote:
> > This is v2 of the patch; I managed to bit-rot my own patch due to
> > my
> > fix for r264335, which tightened up the "is this meaningful"
> > threshold
> > on edit distances when finding spelling correction candidates.
> > 
> > The only change in this version is to rename various things in
> > the testcase so that they continue to be suggested
> > ("colour" vs "m_color" are no longer near enough, so I renamed
> > "colour" to "m_colour").
> > 
> > Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
> > 
> > OK for trunk?
> > 
> > Blurb from v1:
> > 
> > PR c++/84993 identifies a problem with our suggestions for
> > misspelled member names in the C++ FE for the case where the
> > member is private.
> > 
> > For example, given:
> > 
> > class foo
> > {
> > public:
> >   double get_ratio() const { return m_ratio; }
> > 
> > private:
> >   double m_ratio;
> > };
> > 
> > void test(foo *ptr)
> > {
> >   if (ptr->ratio >= 0.5)
> >     ;// etc
> > }
> > 
> > ...we currently emit this suggestion:
> > 
> > <source>: In function 'void test(foo*)':
> > <source>:12:12: error: 'class foo' has no member named 'ratio'; did
> > you mean 'm_ratio'?
> >    if (ptr->ratio >= 0.5)
> >             ^~~~~
> >             m_ratio
> > 
> > ...but if the user follows this suggestion, they get:
> > 
> > <source>: In function 'void test(foo*)':
> > <source>:12:12: error: 'double foo::m_ratio' is private within this
> > context
> >    if (ptr->m_ratio >= 0.5)
> >             ^~~~~~~
> > <source>:7:10: note: declared private here
> >    double m_ratio;
> >           ^~~~~~~
> > <source>:12:12: note: field 'double foo::m_ratio' can be accessed
> > via 'double foo::get_ratio() const'
> >    if (ptr->m_ratio >= 0.5)
> >             ^~~~~~~
> >             get_ratio()
> > 
> > It feels wrong to be emitting a fix-it hint that doesn't compile,
> > so this
> > patch adds the accessor fix-it hint logic to this case, so that we
> > directly
> > offer a valid suggestion:
> > 
> > <source>: In function 'void test(foo*)':
> > <source>:12:12: error: 'class foo' has no member named 'ratio'; did
> > you mean
> > 'double foo::m_ratio'? (accessible via 'double foo::get_ratio()
> > const')
> >    if (ptr->ratio >= 0.5)
> >             ^~~~~
> >             get_ratio()
> 
> I wonder if suggesting the inaccessible member is at all helpful
> if it cannot be used.  

Of the two members "m_ratio" and "get_ratio", the winning candidate
based on edit-distance lookup was the inaccessible member; the accessor
is "further away" in terms of edit distance.  I think it's useful to
the user to identify both, as this patch does.

> Would mentioning only the accessor be
> a better approach?

I think it's more helpful to the user to be explicit about what the
compiler is "thinking", and mention both.  Consider the case where the
accessor has a wildy different name to the misspelled member:

class foo {
public:
  int get_pertinent_data () { return m_val; }

private:
  int m_val;
};

int test (foo *f)
{
   return f->val;
}

The patch emits:

t.c: In function ‘int test(foo*)’:
t.c:11:14: error: ‘class foo’ has no member named ‘val’; did you mean
‘int foo::m_val’? (accessible via ‘int foo::get_pertinent_data()’)
11 |    return f->val;
   |              ^~~
   |              get_pertinent_data()

which I think is clear and helpful.

> Also, to echo a comment made by someone else in a bug I don't
> remember, rather than phrasing the error in the form of
> a question ("did you mean x?") it might be better to either
> state what we know:
> 
>    error: 'class foo' has no member named 'ratio'; the nearest
>      match is 'double foo::m_ratio' (accessible via 'double
>      foo::get_ratio() const')
> 
> or offer a suggestion:
> 
>    error: 'class foo' has no member named 'ratio'; suggest
>      using 'double foo::get_ratio() const' instead

I think you're referring to PR 84890, though that bug was about this
kind of message:
  note: ‘INT_MAX’ is defined in header ‘<limits.h>’; did you forget to
‘#include <limits.h>’?

PR 84890 combines several concerns:
(a) is the message too verbose? (initial comment)
(b) is the message potentially annoying to the user? (comment 5)
(c) is it better to phrase the message as a suggestion, rather than as
a question? (comment 8)

Taking these in turn:

(a) may apply to the missing include message, but I think the "did you
mean 'foo'" is short and clear

(b) both styles of message refer to the user as "you", which has a risk
of making things personal.  I think it's fine for the "did you mean"
case.  I think there's an argument that the "did you forget" could be
annoying - but that's not a concern for this patch.

(c) of the various wordings:
  (c.1) "did you mean 'foo'?" (as in the patch, and the status quo for
the rest of the C and C++ FE)
  (c.2) "suggest using 'foo' instead" doesn't seem grammatically
correct to me, in that it sounds like the user is being asked to
suggest something, rather than to change their code.  I think there's
an implicit "I" in there - "I suggest" - but after abbreviation it
seems clunky to me.
  (c.3) "suggestion: use 'foo'" might work, but (c.1) seems much
simpler to me

So I prefer the wording in the patch.  If we're going to change the
wording across the compiler, I'd prefer to do that in a separate patch.

> A different approach altogether to these spelling messages that
> occurs to me but that you may have already considered and rejected
> would be to do what GCC does for errors due to ambiguous overloads:
> i.e., enumerate the available candidates.  This would work well in
> cases when multiple members are a close match.  It would also make
> it possible to explain, for each candidate member, whether it's
> accessible.

I hadn't thought of that approach, but my hunch is that there's likely
to only be one good suggestion: this use-case is trying to handle the
case where the user is trying to access a field of a class, and can't
quite remember the spelling, or what the accessor is.

FWIW I actually have another patch I'm about to post which updates
those available candidates suggestions (it special-cases the common
case where there's just one candidate: it uses the "did you mean %qs?"
wording, and the user gets a fix-it hint inline, and two less "note"
diagnostics)

Dave

  reply	other threads:[~2018-10-09 14:22 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-07-12  1:58 [PATCH] " David Malcolm
2018-07-27 15:00 ` [PING] " David Malcolm
2018-09-21 21:38   ` [PATCH] v2: " David Malcolm
2018-09-24 17:11     ` Martin Sebor
2018-10-09 15:09       ` David Malcolm [this message]
2018-10-11 18:36     ` Jason Merrill

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1539094923.14521.134.camel@redhat.com \
    --to=dmalcolm@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jason@redhat.com \
    --cc=msebor@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).