@@ -4657,25 +4657,30 @@ impl<'a> Parser<'a> {
4657
4657
} )
4658
4658
}
4659
4659
4660
- fn complain_if_pub_macro ( & mut self , visa : & Visibility , span : Span ) {
4661
- match * visa {
4662
- Visibility :: Inherited => ( ) ,
4660
+ fn complain_if_pub_macro ( & mut self , vis : & Visibility , sp : Span ) {
4661
+ if let Err ( mut err) = self . complain_if_pub_macro_diag ( vis, sp) {
4662
+ err. emit ( ) ;
4663
+ }
4664
+ }
4665
+
4666
+ fn complain_if_pub_macro_diag ( & mut self , vis : & Visibility , sp : Span ) -> PResult < ' a , ( ) > {
4667
+ match * vis {
4668
+ Visibility :: Inherited => Ok ( ( ) ) ,
4663
4669
_ => {
4664
4670
let is_macro_rules: bool = match self . token {
4665
4671
token:: Ident ( sid) => sid. name == Symbol :: intern ( "macro_rules" ) ,
4666
4672
_ => false ,
4667
4673
} ;
4668
4674
if is_macro_rules {
4669
- self . diagnostic ( ) . struct_span_err ( span , "can't qualify macro_rules \
4670
- invocation with `pub`")
4671
- . help ( "did you mean #[macro_export]?" )
4672
- . emit ( ) ;
4675
+ let mut err = self . diagnostic ( )
4676
+ . struct_span_err ( sp , "can't qualify macro_rules invocation with `pub`") ;
4677
+ err . help ( "did you mean #[macro_export]?" ) ;
4678
+ Err ( err )
4673
4679
} else {
4674
- self . diagnostic ( ) . struct_span_err ( span, "can't qualify macro \
4675
- invocation with `pub`")
4676
- . help ( "try adjusting the macro to put `pub` \
4677
- inside the invocation")
4678
- . emit ( ) ;
4680
+ let mut err = self . diagnostic ( )
4681
+ . struct_span_err ( sp, "can't qualify macro invocation with `pub`" ) ;
4682
+ err. help ( "try adjusting the macro to put `pub` inside the invocation" ) ;
4683
+ Err ( err)
4679
4684
}
4680
4685
}
4681
4686
}
@@ -4686,14 +4691,36 @@ impl<'a> Parser<'a> {
4686
4691
-> PResult < ' a , ( Ident , Vec < ast:: Attribute > , ast:: ImplItemKind ) > {
4687
4692
// code copied from parse_macro_use_or_failure... abstraction!
4688
4693
if self . token . is_path_start ( ) {
4689
- // method macro.
4694
+ // Method macro.
4690
4695
4691
4696
let prev_span = self . prev_span ;
4692
- self . complain_if_pub_macro ( & vis, prev_span) ;
4697
+ // Before complaining about trying to set a macro as `pub`,
4698
+ // check if `!` comes after the path.
4699
+ let err = self . complain_if_pub_macro_diag ( & vis, prev_span) ;
4693
4700
4694
4701
let lo = self . span ;
4695
4702
let pth = self . parse_path ( PathStyle :: Mod ) ?;
4696
- self . expect ( & token:: Not ) ?;
4703
+ let bang_err = self . expect ( & token:: Not ) ;
4704
+ if let Err ( mut err) = err {
4705
+ if let Err ( mut bang_err) = bang_err {
4706
+ // Given this code `pub path(`, it seems like this is not setting the
4707
+ // visibility of a macro invocation, but rather a mistyped method declaration.
4708
+ // Create a diagnostic pointing out that `fn` is missing.
4709
+ //
4710
+ // x | pub path(&self) {
4711
+ // | ^ missing `fn` for method declaration
4712
+
4713
+ err. cancel ( ) ;
4714
+ bang_err. cancel ( ) ;
4715
+ // pub path(
4716
+ // ^^ `sp` below will point to this
4717
+ let sp = prev_span. between ( self . prev_span ) ;
4718
+ err = self . diagnostic ( )
4719
+ . struct_span_err ( sp, "missing `fn` for method declaration" ) ;
4720
+ err. span_label ( sp, & "missing `fn`" ) ;
4721
+ }
4722
+ return Err ( err) ;
4723
+ }
4697
4724
4698
4725
// eat a matched-delimiter token tree:
4699
4726
let ( delim, tts) = self . expect_delimited_token_tree ( ) ?;
0 commit comments