@@ -203,101 +203,107 @@ impl<'a> Parser<'a> {
203
203
return Ok ( Some ( macro_def) ) ;
204
204
}
205
205
206
- // Verify whether we have encountered a struct or method definition where the user forgot to
207
- // add the `struct` or `fn` keyword after writing `pub`: `pub S {}`
208
206
if vis. node . is_pub ( ) && self . check_ident ( ) && self . look_ahead ( 1 , |t| * t != token:: Not ) {
209
- // Space between `pub` keyword and the identifier
210
- //
211
- // pub S {}
212
- // ^^^ `sp` points here
213
- let sp = self . prev_span . between ( self . token . span ) ;
214
- let full_sp = self . prev_span . to ( self . token . span ) ;
215
- let ident_sp = self . token . span ;
216
- if self . look_ahead ( 1 , |t| * t == token:: OpenDelim ( token:: Brace ) ) {
217
- // possible public struct definition where `struct` was forgotten
218
- let ident = self . parse_ident ( ) . unwrap ( ) ;
219
- let msg = format ! ( "add `struct` here to parse `{}` as a public struct" , ident) ;
220
- let mut err = self . struct_span_err ( sp, "missing `struct` for struct definition" ) ;
207
+ self . recover_missing_kw_before_item ( ) ?;
208
+ }
209
+ self . parse_macro_use_or_failure ( attrs, macros_allowed, attributes_allowed, lo, vis)
210
+ }
211
+
212
+ /// Recover on encountering a struct or method definition where the user
213
+ /// forgot to add the `struct` or `fn` keyword after writing `pub`: `pub S {}`.
214
+ fn recover_missing_kw_before_item ( & mut self ) -> PResult < ' a , ( ) > {
215
+ // Space between `pub` keyword and the identifier
216
+ //
217
+ // pub S {}
218
+ // ^^^ `sp` points here
219
+ let sp = self . prev_span . between ( self . token . span ) ;
220
+ let full_sp = self . prev_span . to ( self . token . span ) ;
221
+ let ident_sp = self . token . span ;
222
+ if self . look_ahead ( 1 , |t| * t == token:: OpenDelim ( token:: Brace ) ) {
223
+ // possible public struct definition where `struct` was forgotten
224
+ let ident = self . parse_ident ( ) . unwrap ( ) ;
225
+ let msg = format ! ( "add `struct` here to parse `{}` as a public struct" , ident) ;
226
+ let mut err = self . struct_span_err ( sp, "missing `struct` for struct definition" ) ;
227
+ err. span_suggestion_short (
228
+ sp,
229
+ & msg,
230
+ " struct " . into ( ) ,
231
+ Applicability :: MaybeIncorrect , // speculative
232
+ ) ;
233
+ return Err ( err) ;
234
+ } else if self . look_ahead ( 1 , |t| * t == token:: OpenDelim ( token:: Paren ) ) {
235
+ let ident = self . parse_ident ( ) . unwrap ( ) ;
236
+ self . bump ( ) ; // `(`
237
+ let kw_name = self . recover_first_param ( ) ;
238
+ self . consume_block ( token:: Paren , ConsumeClosingDelim :: Yes ) ;
239
+ let ( kw, kw_name, ambiguous) = if self . check ( & token:: RArrow ) {
240
+ self . eat_to_tokens ( & [ & token:: OpenDelim ( token:: Brace ) ] ) ;
241
+ self . bump ( ) ; // `{`
242
+ ( "fn" , kw_name, false )
243
+ } else if self . check ( & token:: OpenDelim ( token:: Brace ) ) {
244
+ self . bump ( ) ; // `{`
245
+ ( "fn" , kw_name, false )
246
+ } else if self . check ( & token:: Colon ) {
247
+ let kw = "struct" ;
248
+ ( kw, kw, false )
249
+ } else {
250
+ ( "fn` or `struct" , "function or struct" , true )
251
+ } ;
252
+
253
+ let msg = format ! ( "missing `{}` for {} definition" , kw, kw_name) ;
254
+ let mut err = self . struct_span_err ( sp, & msg) ;
255
+ if !ambiguous {
256
+ self . consume_block ( token:: Brace , ConsumeClosingDelim :: Yes ) ;
257
+ let suggestion =
258
+ format ! ( "add `{}` here to parse `{}` as a public {}" , kw, ident, kw_name) ;
221
259
err. span_suggestion_short (
222
260
sp,
223
- & msg ,
224
- " struct " . into ( ) ,
225
- Applicability :: MaybeIncorrect , // speculative
261
+ & suggestion ,
262
+ format ! ( " {} " , kw ) ,
263
+ Applicability :: MachineApplicable ,
226
264
) ;
227
- return Err ( err) ;
228
- } else if self . look_ahead ( 1 , |t| * t == token:: OpenDelim ( token:: Paren ) ) {
229
- let ident = self . parse_ident ( ) . unwrap ( ) ;
230
- self . bump ( ) ; // `(`
231
- let kw_name = self . recover_first_param ( ) ;
232
- self . consume_block ( token:: Paren , ConsumeClosingDelim :: Yes ) ;
233
- let ( kw, kw_name, ambiguous) = if self . check ( & token:: RArrow ) {
234
- self . eat_to_tokens ( & [ & token:: OpenDelim ( token:: Brace ) ] ) ;
235
- self . bump ( ) ; // `{`
236
- ( "fn" , kw_name, false )
237
- } else if self . check ( & token:: OpenDelim ( token:: Brace ) ) {
238
- self . bump ( ) ; // `{`
239
- ( "fn" , kw_name, false )
240
- } else if self . check ( & token:: Colon ) {
241
- let kw = "struct" ;
242
- ( kw, kw, false )
243
- } else {
244
- ( "fn` or `struct" , "function or struct" , true )
245
- } ;
246
-
247
- let msg = format ! ( "missing `{}` for {} definition" , kw, kw_name) ;
248
- let mut err = self . struct_span_err ( sp, & msg) ;
249
- if !ambiguous {
250
- self . consume_block ( token:: Brace , ConsumeClosingDelim :: Yes ) ;
251
- let suggestion =
252
- format ! ( "add `{}` here to parse `{}` as a public {}" , kw, ident, kw_name) ;
253
- err. span_suggestion_short (
254
- sp,
255
- & suggestion,
256
- format ! ( " {} " , kw) ,
257
- Applicability :: MachineApplicable ,
265
+ } else {
266
+ if let Ok ( snippet) = self . span_to_snippet ( ident_sp) {
267
+ err. span_suggestion (
268
+ full_sp,
269
+ "if you meant to call a macro, try" ,
270
+ format ! ( "{}!" , snippet) ,
271
+ // this is the `ambiguous` conditional branch
272
+ Applicability :: MaybeIncorrect ,
258
273
) ;
259
274
} else {
260
- if let Ok ( snippet) = self . span_to_snippet ( ident_sp) {
261
- err. span_suggestion (
262
- full_sp,
263
- "if you meant to call a macro, try" ,
264
- format ! ( "{}!" , snippet) ,
265
- // this is the `ambiguous` conditional branch
266
- Applicability :: MaybeIncorrect ,
267
- ) ;
268
- } else {
269
- err. help (
270
- "if you meant to call a macro, remove the `pub` \
275
+ err. help (
276
+ "if you meant to call a macro, remove the `pub` \
271
277
and add a trailing `!` after the identifier",
272
- ) ;
273
- }
274
- }
275
- return Err ( err) ;
276
- } else if self . look_ahead ( 1 , |t| * t == token:: Lt ) {
277
- let ident = self . parse_ident ( ) . unwrap ( ) ;
278
- self . eat_to_tokens ( & [ & token:: Gt ] ) ;
279
- self . bump ( ) ; // `>`
280
- let ( kw, kw_name, ambiguous) = if self . eat ( & token:: OpenDelim ( token:: Paren ) ) {
281
- ( "fn" , self . recover_first_param ( ) , false )
282
- } else if self . check ( & token:: OpenDelim ( token:: Brace ) ) {
283
- ( "struct" , "struct" , false )
284
- } else {
285
- ( "fn` or `struct" , "function or struct" , true )
286
- } ;
287
- let msg = format ! ( "missing `{}` for {} definition" , kw, kw_name) ;
288
- let mut err = self . struct_span_err ( sp, & msg) ;
289
- if !ambiguous {
290
- err. span_suggestion_short (
291
- sp,
292
- & format ! ( "add `{}` here to parse `{}` as a public {}" , kw, ident, kw_name) ,
293
- format ! ( " {} " , kw) ,
294
- Applicability :: MachineApplicable ,
295
278
) ;
296
279
}
297
- return Err ( err) ;
298
280
}
281
+ return Err ( err) ;
282
+ } else if self . look_ahead ( 1 , |t| * t == token:: Lt ) {
283
+ let ident = self . parse_ident ( ) . unwrap ( ) ;
284
+ self . eat_to_tokens ( & [ & token:: Gt ] ) ;
285
+ self . bump ( ) ; // `>`
286
+ let ( kw, kw_name, ambiguous) = if self . eat ( & token:: OpenDelim ( token:: Paren ) ) {
287
+ ( "fn" , self . recover_first_param ( ) , false )
288
+ } else if self . check ( & token:: OpenDelim ( token:: Brace ) ) {
289
+ ( "struct" , "struct" , false )
290
+ } else {
291
+ ( "fn` or `struct" , "function or struct" , true )
292
+ } ;
293
+ let msg = format ! ( "missing `{}` for {} definition" , kw, kw_name) ;
294
+ let mut err = self . struct_span_err ( sp, & msg) ;
295
+ if !ambiguous {
296
+ err. span_suggestion_short (
297
+ sp,
298
+ & format ! ( "add `{}` here to parse `{}` as a public {}" , kw, ident, kw_name) ,
299
+ format ! ( " {} " , kw) ,
300
+ Applicability :: MachineApplicable ,
301
+ ) ;
302
+ }
303
+ return Err ( err) ;
304
+ } else {
305
+ Ok ( ( ) )
299
306
}
300
- self . parse_macro_use_or_failure ( attrs, macros_allowed, attributes_allowed, lo, vis)
301
307
}
302
308
303
309
pub ( super ) fn mk_item_with_info (
0 commit comments