From 292aa8704957f0c0a94cc0cb01c74267d2bdfe27 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Tue, 11 Feb 2025 11:13:33 -0300 Subject: [PATCH] Fix use closure parsing error message --- compiler/rustc_parse/src/parser/item.rs | 19 ++++++++++++++++--- tests/ui/ergonomic-clones/closure/parse.rs | 4 +--- .../ui/ergonomic-clones/closure/parse.stderr | 12 +++--------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 961e81989d6..678376aee4f 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -209,9 +209,7 @@ impl<'a> Parser<'a> { let check_pub = def == &Defaultness::Final; let mut def_ = || mem::replace(def, Defaultness::Final); - let info = if !self.look_ahead(1, |t| [token::OrOr, token::Or].contains(&t.kind)) - && self.eat_keyword_case(exp!(Use), case) - { + let info = if !self.is_use_closure() && self.eat_keyword_case(exp!(Use), case) { self.parse_use_item()? } else if self.check_fn_front_matter(check_pub, case) { // FUNCTION ITEM @@ -1279,6 +1277,21 @@ impl<'a> Parser<'a> { None } + fn is_use_closure(&self) -> bool { + if self.token.is_keyword(kw::Use) { + // Check if this could be a closure. + self.look_ahead(1, |token| { + // Move or Async here would be an error but still we're parsing a closure + let dist = + if token.is_keyword(kw::Move) || token.is_keyword(kw::Async) { 2 } else { 1 }; + + self.look_ahead(dist, |token| matches!(token.kind, token::Or | token::OrOr)) + }) + } else { + false + } + } + fn is_unsafe_foreign_mod(&self) -> bool { self.token.is_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Extern]) diff --git a/tests/ui/ergonomic-clones/closure/parse.rs b/tests/ui/ergonomic-clones/closure/parse.rs index d4523de57ff..23fce20e370 100644 --- a/tests/ui/ergonomic-clones/closure/parse.rs +++ b/tests/ui/ergonomic-clones/closure/parse.rs @@ -14,9 +14,7 @@ fn parse2() { fn parse3() { use move || { - //~^ ERROR expected identifier, found keyword `move` - //~| ERROR expected one of `::`, `;`, or `as`, found `||` - // FIXME ideally we should error like in the previous example + //~^ ERROR expected one of `async`, `|`, or `||`, found keyword `move` }; } diff --git a/tests/ui/ergonomic-clones/closure/parse.stderr b/tests/ui/ergonomic-clones/closure/parse.stderr index ac86a041929..c45c46eefa5 100644 --- a/tests/ui/ergonomic-clones/closure/parse.stderr +++ b/tests/ui/ergonomic-clones/closure/parse.stderr @@ -18,17 +18,11 @@ error: expected one of `async`, `|`, or `||`, found keyword `use` LL | move use || { | ^^^ expected one of `async`, `|`, or `||` -error: expected identifier, found keyword `move` +error: expected one of `async`, `|`, or `||`, found keyword `move` --> $DIR/parse.rs:16:9 | LL | use move || { - | ^^^^ expected identifier, found keyword + | ^^^^ expected one of `async`, `|`, or `||` -error: expected one of `::`, `;`, or `as`, found `||` - --> $DIR/parse.rs:16:14 - | -LL | use move || { - | ^^ expected one of `::`, `;`, or `as` - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors