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
next prev parent 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).