Identify missing item category in impl
s
```rust struct S; impl S { pub hello_method(&self) { println!("Hello"); } } fn main() { S.hello_method(); } ``` ```rust error: can't qualify macro invocation with `pub` --> file.rs:3:4 | 3 | pub hello_method(&self) { | ^^^- - expected `!` here for a macro invocation | | | did you mean to write `fn` here for a method declaration? | = help: try adjusting the macro to put `pub` inside the invocation ```
This commit is contained in:
parent
c62e532f3d
commit
57009caabd
3 changed files with 80 additions and 15 deletions
|
@ -4660,25 +4660,30 @@ impl<'a> Parser<'a> {
|
|||
})
|
||||
}
|
||||
|
||||
fn complain_if_pub_macro(&mut self, visa: &Visibility, span: Span) {
|
||||
match *visa {
|
||||
Visibility::Inherited => (),
|
||||
fn complain_if_pub_macro(&mut self, vis: &Visibility, sp: Span) {
|
||||
if let Err(mut err) = self.complain_if_pub_macro_diag(vis, sp) {
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
|
||||
fn complain_if_pub_macro_diag(&mut self, vis: &Visibility, sp: Span) -> PResult<'a, ()> {
|
||||
match *vis {
|
||||
Visibility::Inherited => Ok(()),
|
||||
_ => {
|
||||
let is_macro_rules: bool = match self.token {
|
||||
token::Ident(sid) => sid.name == Symbol::intern("macro_rules"),
|
||||
_ => false,
|
||||
};
|
||||
if is_macro_rules {
|
||||
self.diagnostic().struct_span_err(span, "can't qualify macro_rules \
|
||||
invocation with `pub`")
|
||||
.help("did you mean #[macro_export]?")
|
||||
.emit();
|
||||
let mut err = self.diagnostic()
|
||||
.struct_span_err(sp, "can't qualify macro_rules invocation with `pub`");
|
||||
err.help("did you mean #[macro_export]?");
|
||||
Err(err)
|
||||
} else {
|
||||
self.diagnostic().struct_span_err(span, "can't qualify macro \
|
||||
invocation with `pub`")
|
||||
.help("try adjusting the macro to put `pub` \
|
||||
inside the invocation")
|
||||
.emit();
|
||||
let mut err = self.diagnostic()
|
||||
.struct_span_err(sp, "can't qualify macro invocation with `pub`");
|
||||
err.help("try adjusting the macro to put `pub` inside the invocation");
|
||||
Err(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4689,14 +4694,41 @@ impl<'a> Parser<'a> {
|
|||
-> PResult<'a, (Ident, Vec<ast::Attribute>, ast::ImplItemKind)> {
|
||||
// code copied from parse_macro_use_or_failure... abstraction!
|
||||
if self.token.is_path_start() {
|
||||
// method macro.
|
||||
// Method macro.
|
||||
|
||||
let prev_span = self.prev_span;
|
||||
self.complain_if_pub_macro(&vis, prev_span);
|
||||
// Before complaining about trying to set a macro as `pub`,
|
||||
// check if `!` comes after the path.
|
||||
let err = self.complain_if_pub_macro_diag(&vis, prev_span);
|
||||
|
||||
let lo = self.span.lo;
|
||||
let pth = self.parse_path(PathStyle::Mod)?;
|
||||
self.expect(&token::Not)?;
|
||||
let bang_err = self.expect(&token::Not);
|
||||
if let Err(mut err) = err {
|
||||
if let Err(mut bang_err) = bang_err {
|
||||
// Given this code `pub path(`, it seems like this is not setting the
|
||||
// visibility of a macro invocation, but rather a mistyped method declaration.
|
||||
// Keep the macro diagnostic, but also provide a hint that `fn` might be
|
||||
// missing. Don't complain about the missing `!` as a separate diagnostic, add
|
||||
// label in the appropriate place as part of one unified diagnostic.
|
||||
//
|
||||
// x | pub path(&self) {
|
||||
// | ^^^- - expected `!` here for a macro invocation
|
||||
// | |
|
||||
// | did you mean to write `fn` here for a method declaration?
|
||||
|
||||
bang_err.cancel();
|
||||
err.span_label(self.span, &"expected `!` here for a macro invocation");
|
||||
// pub path(
|
||||
// ^^ `sp` below will point to this
|
||||
let sp = mk_sp(prev_span.hi, self.prev_span.lo);
|
||||
err.span_label(sp,
|
||||
&"did you mean to write `fn` here for a method declaration?");
|
||||
}
|
||||
return Err(err);
|
||||
} else if let Err(bang_err) = bang_err {
|
||||
return Err(bang_err);
|
||||
}
|
||||
|
||||
// eat a matched-delimiter token tree:
|
||||
let (delim, tts) = self.expect_delimited_token_tree()?;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue