diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index 1271bce799d5c..ee0abba1c1753 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -260,7 +260,7 @@ impl<'a> Parser<'a> { item } else { let do_parse = |this: &mut Self| { - let path = this.parse_path(PathStyle::Mod, None)?; + let path = this.parse_path(PathStyle::Mod)?; let args = this.parse_attr_args()?; Ok(ast::AttrItem { path, args, tokens: None }) }; @@ -387,7 +387,7 @@ impl<'a> Parser<'a> { } let lo = self.token.span; - let path = self.parse_path(PathStyle::Mod, None)?; + let path = self.parse_path(PathStyle::Mod)?; let kind = self.parse_meta_item_kind()?; let span = lo.to(self.prev_token.span); Ok(ast::MetaItem { path, kind, span }) diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 8bc4433a9653a..5fa4f7902d624 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1579,7 +1579,7 @@ impl<'a> Parser<'a> { self.expect(&token::ModSep)?; let mut path = ast::Path { segments: ThinVec::new(), span: DUMMY_SP, tokens: None }; - self.parse_path_segments(&mut path.segments, T::PATH_STYLE, None, None)?; + self.parse_path_segments(&mut path.segments, T::PATH_STYLE, None)?; path.span = ty_span.to(self.prev_token.span); let ty_str = self.span_to_snippet(ty_span).unwrap_or_else(|_| pprust::ty_to_string(&ty)); diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 6dafb8b999b2f..0e19a67a8413a 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -775,7 +775,7 @@ impl<'a> Parser<'a> { _ => {} } - match self.parse_path(PathStyle::Expr, None) { + match self.parse_path(PathStyle::Expr) { Ok(path) => { let span_after_type = parser_snapshot_after_type.token.span; let expr = mk_expr( @@ -1314,7 +1314,7 @@ impl<'a> Parser<'a> { } let fn_span_lo = self.token.span; - let mut seg = self.parse_path_segment(PathStyle::Expr, None, None)?; + let mut seg = self.parse_path_segment(PathStyle::Expr, None)?; self.check_trailing_angle_brackets(&seg, &[&token::OpenDelim(Delimiter::Parenthesis)]); self.check_turbofish_missing_angle_brackets(&mut seg); @@ -1544,7 +1544,7 @@ impl<'a> Parser<'a> { })?; (Some(qself), path) } else { - (None, self.parse_path(PathStyle::Expr, None)?) + (None, self.parse_path(PathStyle::Expr)?) }; // `!`, as an operator, is prefix, so we know this isn't that. diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index d3f756139def3..1301ed3e3882e 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -452,7 +452,7 @@ impl<'a> Parser<'a> { /// Parses an item macro, e.g., `item!();`. fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> { - let path = self.parse_path(PathStyle::Mod, None)?; // `foo::bar` + let path = self.parse_path(PathStyle::Mod)?; // `foo::bar` self.expect(&token::Not)?; // `!` match self.parse_delim_args() { // `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`. @@ -976,7 +976,7 @@ impl<'a> Parser<'a> { self.parse_use_tree_glob_or_nested()? } else { // `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;` - prefix = self.parse_path(PathStyle::Mod, None)?; + prefix = self.parse_path(PathStyle::Mod)?; if self.eat(&token::ModSep) { self.parse_use_tree_glob_or_nested()? @@ -987,7 +987,7 @@ impl<'a> Parser<'a> { .emit_err(errors::SingleColonImportPath { span: self.prev_token.span }); // We parse the rest of the path and append it to the original prefix. - self.parse_path_segments(&mut prefix.segments, PathStyle::Mod, None, None)?; + self.parse_path_segments(&mut prefix.segments, PathStyle::Mod, None)?; prefix.span = lo.to(self.prev_token.span); } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 2af0caa1bdaf7..37b4c371c94b4 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -1413,7 +1413,7 @@ impl<'a> Parser<'a> { // Parse `pub(in path)`. self.bump(); // `(` self.bump(); // `in` - let path = self.parse_path(PathStyle::Mod, None)?; // `path` + let path = self.parse_path(PathStyle::Mod)?; // `path` self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)` let vis = VisibilityKind::Restricted { path: P(path), @@ -1430,7 +1430,7 @@ impl<'a> Parser<'a> { { // Parse `pub(crate)`, `pub(self)`, or `pub(super)`. self.bump(); // `(` - let path = self.parse_path(PathStyle::Mod, None)?; // `crate`/`super`/`self` + let path = self.parse_path(PathStyle::Mod)?; // `crate`/`super`/`self` self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)` let vis = VisibilityKind::Restricted { path: P(path), @@ -1456,7 +1456,7 @@ impl<'a> Parser<'a> { /// Recovery for e.g. `pub(something) fn ...` or `struct X { pub(something) y: Z }` fn recover_incorrect_vis_restriction(&mut self) -> PResult<'a, ()> { self.bump(); // `(` - let path = self.parse_path(PathStyle::Mod, None)?; + let path = self.parse_path(PathStyle::Mod)?; self.expect(&token::CloseDelim(Delimiter::Parenthesis))?; // `)` let path_str = pprust::path_to_string(&path); diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs index a09c1e4d7fde2..f5681532b3af7 100644 --- a/compiler/rustc_parse/src/parser/nonterminal.rs +++ b/compiler/rustc_parse/src/parser/nonterminal.rs @@ -168,7 +168,7 @@ impl<'a> Parser<'a> { }.into_diagnostic(&self.sess.span_diagnostic)); } NonterminalKind::Path => token::NtPath( - P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type, None))?), + P(self.collect_tokens_no_attrs(|this| this.parse_path(PathStyle::Type))?), ), NonterminalKind::Meta => token::NtMeta(P(self.parse_attr_item(true)?)), NonterminalKind::Vis => token::NtVis( diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 5803d0c1c0524..8d68a3a50acae 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -2,10 +2,11 @@ use super::{ForceCollect, Parser, PathStyle, TrailingToken}; use crate::errors::{ self, AmbiguousRangePattern, DotDotDotForRemainingFields, DotDotDotRangeToPatternNotAllowed, DotDotDotRestPattern, EnumPatternInsteadOfIdentifier, ExpectedBindingLeftOfAt, - ExpectedCommaAfterPatternField, InclusiveRangeExtraEquals, InclusiveRangeMatchArrow, - InclusiveRangeNoEnd, InvalidMutInPattern, PatternOnWrongSideOfAt, RefMutOrderIncorrect, - RemoveLet, RepeatedMutInPattern, TopLevelOrPatternNotAllowed, TopLevelOrPatternNotAllowedSugg, - TrailingVertNotAllowed, UnexpectedLifetimeInPattern, UnexpectedVertVertBeforeFunctionParam, + ExpectedCommaAfterPatternField, GenericArgsInPatRequireTurbofishSyntax, + InclusiveRangeExtraEquals, InclusiveRangeMatchArrow, InclusiveRangeNoEnd, InvalidMutInPattern, + PatternOnWrongSideOfAt, RefMutOrderIncorrect, RemoveLet, RepeatedMutInPattern, + TopLevelOrPatternNotAllowed, TopLevelOrPatternNotAllowedSugg, TrailingVertNotAllowed, + UnexpectedLifetimeInPattern, UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern, }; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; @@ -366,11 +367,11 @@ impl<'a> Parser<'a> { // Parse _ PatKind::Wild } else if self.eat_keyword(kw::Mut) { - self.parse_pat_ident_mut()? + self.parse_pat_ident_mut(syntax_loc)? } else if self.eat_keyword(kw::Ref) { // Parse ref ident @ pat / ref mut ident @ pat let mutbl = self.parse_mutability(); - self.parse_pat_ident(BindingAnnotation(ByRef::Yes, mutbl))? + self.parse_pat_ident(BindingAnnotation(ByRef::Yes, mutbl), syntax_loc)? } else if self.eat_keyword(kw::Box) { self.parse_pat_box()? } else if self.check_inline_const(0) { @@ -392,7 +393,7 @@ impl<'a> Parser<'a> { // Parse `ident @ pat` // This can give false positives and parse nullary enums, // they are dealt with later in resolve. - self.parse_pat_ident(BindingAnnotation::NONE)? + self.parse_pat_ident(BindingAnnotation::NONE, syntax_loc)? } else if self.is_start_of_pat_with_path() { // Parse pattern starting with a path let (qself, path) = if self.eat_lt() { @@ -401,7 +402,7 @@ impl<'a> Parser<'a> { (Some(qself), path) } else { // Parse an unqualified path - (None, self.parse_path(PathStyle::Pat, syntax_loc)?) + (None, self.parse_path(PathStyle::Pat)?) }; let span = lo.to(self.prev_token.span); @@ -574,12 +575,12 @@ impl<'a> Parser<'a> { } /// Parse a mutable binding with the `mut` token already eaten. - fn parse_pat_ident_mut(&mut self) -> PResult<'a, PatKind> { + fn parse_pat_ident_mut(&mut self, syntax_loc: Option) -> PResult<'a, PatKind> { let mut_span = self.prev_token.span; if self.eat_keyword(kw::Ref) { self.sess.emit_err(RefMutOrderIncorrect { span: mut_span.to(self.prev_token.span) }); - return self.parse_pat_ident(BindingAnnotation::REF_MUT); + return self.parse_pat_ident(BindingAnnotation::REF_MUT, syntax_loc); } self.recover_additional_muts(); @@ -784,7 +785,7 @@ impl<'a> Parser<'a> { (Some(qself), path) } else { // Parse an unqualified path - (None, self.parse_path(PathStyle::Pat, None)?) + (None, self.parse_path(PathStyle::Pat)?) }; let hi = self.prev_token.span; Ok(self.mk_expr(lo.to(hi), ExprKind::Path(qself, path))) @@ -813,16 +814,28 @@ impl<'a> Parser<'a> { | token::DotDotDot | token::DotDotEq | token::DotDot // A range pattern. | token::ModSep // A tuple / struct variant pattern. | token::Not)) // A macro expanding to a pattern. - // May suggest the turbofish syntax for generics, only valid for recoveries. - && !(self.look_ahead(1, |t| t.kind == token::Lt) - && self.look_ahead(2, |t| t.can_begin_type())) } /// Parses `ident` or `ident @ pat`. /// Used by the copy foo and ref foo patterns to give a good /// error message when parsing mistakes like `ref foo(a, b)`. - fn parse_pat_ident(&mut self, binding_annotation: BindingAnnotation) -> PResult<'a, PatKind> { + fn parse_pat_ident( + &mut self, + binding_annotation: BindingAnnotation, + syntax_loc: Option, + ) -> PResult<'a, PatKind> { let ident = self.parse_ident()?; + + if !matches!(syntax_loc, Some(PatternLocation::FunctionParameter)) + && self.check_noexpect(&token::Lt) + && self.look_ahead(1, |t| t.can_begin_type()) + { + return Err(self.sess.create_err(GenericArgsInPatRequireTurbofishSyntax { + span: self.token.span, + suggest_turbofish: self.token.span.shrink_to_lo(), + })); + } + let sub = if self.eat(&token::At) { Some(self.parse_pat_no_top_alt(Some(Expected::BindingPattern), None)?) } else { diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 0d5f48e424e2c..feb7e829caf68 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -1,7 +1,6 @@ -use super::pat::PatternLocation; use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{Parser, Restrictions, TokenType}; -use crate::errors::{GenericArgsInPatRequireTurbofishSyntax, PathSingleColon}; +use crate::errors::PathSingleColon; use crate::{errors, maybe_whole}; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; @@ -80,7 +79,7 @@ impl<'a> Parser<'a> { let (mut path, path_span); if self.eat_keyword(kw::As) { let path_lo = self.token.span; - path = self.parse_path(PathStyle::Type, None)?; + path = self.parse_path(PathStyle::Type)?; path_span = path_lo.to(self.prev_token.span); } else { path_span = self.token.span.to(self.token.span); @@ -99,7 +98,7 @@ impl<'a> Parser<'a> { } let qself = P(QSelf { ty, path_span, position: path.segments.len() }); - self.parse_path_segments(&mut path.segments, style, None, None)?; + self.parse_path_segments(&mut path.segments, style, None)?; Ok(( qself, @@ -140,12 +139,8 @@ impl<'a> Parser<'a> { true } - pub(super) fn parse_path( - &mut self, - style: PathStyle, - syntax_loc: Option, - ) -> PResult<'a, Path> { - self.parse_path_inner(style, None, syntax_loc) + pub(super) fn parse_path(&mut self, style: PathStyle) -> PResult<'a, Path> { + self.parse_path_inner(style, None) } /// Parses simple paths. @@ -162,7 +157,6 @@ impl<'a> Parser<'a> { &mut self, style: PathStyle, ty_generics: Option<&Generics>, - syntax_loc: Option, ) -> PResult<'a, Path> { let reject_generics_if_mod_style = |parser: &Parser<'_>, path: &Path| { // Ensure generic arguments don't end up in attribute paths, such as: @@ -207,7 +201,7 @@ impl<'a> Parser<'a> { if self.eat(&token::ModSep) { segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))); } - self.parse_path_segments(&mut segments, style, ty_generics, syntax_loc)?; + self.parse_path_segments(&mut segments, style, ty_generics)?; Ok(Path { segments, span: lo.to(self.prev_token.span), tokens: None }) } @@ -216,10 +210,9 @@ impl<'a> Parser<'a> { segments: &mut ThinVec, style: PathStyle, ty_generics: Option<&Generics>, - syntax_loc: Option, ) -> PResult<'a, ()> { loop { - let segment = self.parse_path_segment(style, ty_generics, syntax_loc)?; + let segment = self.parse_path_segment(style, ty_generics)?; if style.has_generic_ambiguity() { // In order to check for trailing angle brackets, we must have finished // recursing (`parse_path_segment` can indirectly call this function), @@ -274,7 +267,6 @@ impl<'a> Parser<'a> { &mut self, style: PathStyle, ty_generics: Option<&Generics>, - syntax_loc: Option, ) -> PResult<'a, PathSegment> { let ident = self.parse_path_segment_ident()?; let is_args_start = |token: &Token| { @@ -294,17 +286,6 @@ impl<'a> Parser<'a> { is_args_start(&this.token) }; - if let Some(PatternLocation::FunctionParameter) = syntax_loc { - } else if style == PathStyle::Pat - && self.check_noexpect(&token::Lt) - && self.look_ahead(1, |t| t.can_begin_type()) - { - return Err(self.sess.create_err(GenericArgsInPatRequireTurbofishSyntax { - span: self.token.span, - suggest_turbofish: self.token.span.shrink_to_lo(), - })); - } - Ok( if style == PathStyle::Type && check_args_start(self) || style != PathStyle::Mod diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 2c08e984be578..9fcf51a04ec05 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -149,7 +149,7 @@ impl<'a> Parser<'a> { fn parse_stmt_path_start(&mut self, lo: Span, attrs: AttrWrapper) -> PResult<'a, Stmt> { let stmt = self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { - let path = this.parse_path(PathStyle::Expr, None)?; + let path = this.parse_path(PathStyle::Expr)?; if this.eat(&token::Not) { let stmt_mac = this.parse_stmt_mac(lo, attrs, path)?; diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs index 8be84c7d46224..3bb50b05aa346 100644 --- a/compiler/rustc_parse/src/parser/ty.rs +++ b/compiler/rustc_parse/src/parser/ty.rs @@ -289,7 +289,7 @@ impl<'a> Parser<'a> { recover_return_sign, )? } else { - let path = self.parse_path(PathStyle::Type, None)?; + let path = self.parse_path(PathStyle::Type)?; let parse_plus = allow_plus == AllowPlus::Yes && self.check_plus(); self.parse_remaining_bounds_path(lifetime_defs, path, lo, parse_plus)? } @@ -649,7 +649,7 @@ impl<'a> Parser<'a> { ty_generics: Option<&Generics>, ) -> PResult<'a, TyKind> { // Simple path - let path = self.parse_path_inner(PathStyle::Type, ty_generics, None)?; + let path = self.parse_path_inner(PathStyle::Type, ty_generics)?; if self.eat(&token::Not) { // Macro invocation in type position Ok(TyKind::MacCall(P(MacCall { path, args: self.parse_delim_args()? }))) @@ -865,7 +865,7 @@ impl<'a> Parser<'a> { path } else { - self.parse_path(PathStyle::Type, None)? + self.parse_path(PathStyle::Type)? }; if self.may_recover() && self.token == TokenKind::OpenDelim(Delimiter::Parenthesis) { diff --git a/tests/ui/span/issue-34264.stderr b/tests/ui/span/issue-34264.stderr index 8c639d5513b53..f0dea66f6128d 100644 --- a/tests/ui/span/issue-34264.stderr +++ b/tests/ui/span/issue-34264.stderr @@ -1,8 +1,8 @@ -error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `<` +error: expected one of `:`, `@`, or `|`, found `<` --> $DIR/issue-34264.rs:1:14 | LL | fn foo(Option, String) {} - | ^ expected one of 9 possible tokens + | ^ expected one of `:`, `@`, or `|` | = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) help: if this is a `self` type, give it a parameter name diff --git a/tests/ui/suggestions/issue-64252-self-type.stderr b/tests/ui/suggestions/issue-64252-self-type.stderr index dd83d6a1cb291..dbef39faeadf6 100644 --- a/tests/ui/suggestions/issue-64252-self-type.stderr +++ b/tests/ui/suggestions/issue-64252-self-type.stderr @@ -1,8 +1,8 @@ -error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `<` +error: expected one of `:`, `@`, or `|`, found `<` --> $DIR/issue-64252-self-type.rs:4:15 | LL | pub fn foo(Box) { } - | ^ expected one of 9 possible tokens + | ^ expected one of `:`, `@`, or `|` | = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) help: if this is a `self` type, give it a parameter name @@ -14,11 +14,11 @@ help: if this is a type, explicitly ignore the parameter name LL | pub fn foo(_: Box) { } | ++ -error: expected one of `!`, `(`, `...`, `..=`, `..`, `::`, `:`, `{`, or `|`, found `<` +error: expected one of `:`, `@`, or `|`, found `<` --> $DIR/issue-64252-self-type.rs:8:15 | LL | fn bar(Box) { } - | ^ expected one of 9 possible tokens + | ^ expected one of `:`, `@`, or `|` | = note: anonymous parameters are removed in the 2018 edition (see RFC 1685) help: if this is a `self` type, give it a parameter name