@@ -204,25 +204,7 @@ impl<'a> Parser<'a> {
204204 let mut def = || mem:: replace ( def, Defaultness :: Final ) ;
205205
206206 let info = if self . eat_keyword ( kw:: Use ) {
207- // USE ITEM
208- let tree = self . parse_use_tree ( ) ?;
209-
210- // If wildcard or glob-like brace syntax doesn't have `;`,
211- // the user may not know `*` or `{}` should be the last.
212- if let Err ( mut e) = self . expect_semi ( ) {
213- match tree. kind {
214- UseTreeKind :: Glob => {
215- e. note ( "the wildcard token must be last on the path" ) ;
216- }
217- UseTreeKind :: Nested ( ..) => {
218- e. note ( "glob-like brace syntax must be last on the path" ) ;
219- }
220- _ => ( ) ,
221- }
222- return Err ( e) ;
223- }
224-
225- ( Ident :: empty ( ) , ItemKind :: Use ( tree) )
207+ self . parse_use_item ( ) ?
226208 } else if self . check_fn_front_matter ( def_final) {
227209 // FUNCTION ITEM
228210 let ( ident, sig, generics, body) = self . parse_fn ( attrs, fn_parse_mode, lo, vis) ?;
@@ -288,7 +270,12 @@ impl<'a> Parser<'a> {
288270 } else if let IsMacroRulesItem :: Yes { has_bang } = self . is_macro_rules_item ( ) {
289271 // MACRO_RULES ITEM
290272 self . parse_item_macro_rules ( vis, has_bang) ?
291- } else if vis. kind . is_pub ( ) && self . isnt_macro_invocation ( ) {
273+ } else if self . isnt_macro_invocation ( )
274+ && ( self . token . is_ident_named ( Symbol :: intern ( "import" ) )
275+ || self . token . is_ident_named ( Symbol :: intern ( "using" ) ) )
276+ {
277+ return self . recover_import_as_use ( ) ;
278+ } else if self . isnt_macro_invocation ( ) && vis. kind . is_pub ( ) {
292279 self . recover_missing_kw_before_item ( ) ?;
293280 return Ok ( None ) ;
294281 } else if macros_allowed && self . check_path ( ) {
@@ -300,6 +287,48 @@ impl<'a> Parser<'a> {
300287 Ok ( Some ( info) )
301288 }
302289
290+ fn recover_import_as_use ( & mut self ) -> PResult < ' a , Option < ( Ident , ItemKind ) > > {
291+ let span = self . token . span ;
292+ let token_name = super :: token_descr ( & self . token ) ;
293+ let snapshot = self . create_snapshot_for_diagnostic ( ) ;
294+ self . bump ( ) ;
295+ match self . parse_use_item ( ) {
296+ Ok ( u) => {
297+ self . struct_span_err ( span, format ! ( "expected item, found {token_name}" ) )
298+ . span_suggestion_short (
299+ span,
300+ "items are imported using the `use` keyword" ,
301+ "use" . to_owned ( ) ,
302+ Applicability :: MachineApplicable ,
303+ )
304+ . emit ( ) ;
305+ Ok ( Some ( u) )
306+ }
307+ Err ( e) => {
308+ e. cancel ( ) ;
309+ self . restore_snapshot ( snapshot) ;
310+ Ok ( None )
311+ }
312+ }
313+ }
314+
315+ fn parse_use_item ( & mut self ) -> PResult < ' a , ( Ident , ItemKind ) > {
316+ let tree = self . parse_use_tree ( ) ?;
317+ if let Err ( mut e) = self . expect_semi ( ) {
318+ match tree. kind {
319+ UseTreeKind :: Glob => {
320+ e. note ( "the wildcard token must be last on the path" ) ;
321+ }
322+ UseTreeKind :: Nested ( ..) => {
323+ e. note ( "glob-like brace syntax must be last on the path" ) ;
324+ }
325+ _ => ( ) ,
326+ }
327+ return Err ( e) ;
328+ }
329+ Ok ( ( Ident :: empty ( ) , ItemKind :: Use ( tree) ) )
330+ }
331+
303332 /// When parsing a statement, would the start of a path be an item?
304333 pub ( super ) fn is_path_start_item ( & mut self ) -> bool {
305334 self . is_kw_followed_by_ident ( kw:: Union ) // no: `union::b`, yes: `union U { .. }`
0 commit comments