diff options
| author | Pavel Grigorenko <GrigorenkoPV@ya.ru> | 2024-09-21 20:07:52 +0300 |
|---|---|---|
| committer | Pavel Grigorenko <GrigorenkoPV@ya.ru> | 2024-09-21 20:07:52 +0300 |
| commit | e90e2593ea9c29ff6be20ec38b314fb2d6d927a4 (patch) | |
| tree | 58e3df5eeb0ac828eb74bc4bb19ec9e58f3ba27a /compiler/rustc_parse/src/parser/path.rs | |
| parent | 74fd001cdae0321144a20133f2216ea8a97da476 (diff) | |
| download | rust-e90e2593ea9c29ff6be20ec38b314fb2d6d927a4.tar.gz rust-e90e2593ea9c29ff6be20ec38b314fb2d6d927a4.zip | |
Parser: recover from `:::` to `::`
Diffstat (limited to 'compiler/rustc_parse/src/parser/path.rs')
| -rw-r--r-- | compiler/rustc_parse/src/parser/path.rs | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs index 42039c621d6..961679b1f56 100644 --- a/compiler/rustc_parse/src/parser/path.rs +++ b/compiler/rustc_parse/src/parser/path.rs @@ -16,7 +16,7 @@ use tracing::debug; use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; use super::{Parser, Restrictions, TokenType}; -use crate::errors::PathSingleColon; +use crate::errors::{PathSingleColon, PathTripleColon}; use crate::parser::{CommaRecoveryMode, RecoverColon, RecoverComma}; use crate::{errors, maybe_whole}; @@ -210,7 +210,7 @@ impl<'a> Parser<'a> { let lo = self.token.span; let mut segments = ThinVec::new(); let mod_sep_ctxt = self.token.span.ctxt(); - if self.eat(&token::PathSep) { + if self.eat_path_sep() { segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt))); } self.parse_path_segments(&mut segments, style, ty_generics)?; @@ -246,7 +246,7 @@ impl<'a> Parser<'a> { } segments.push(segment); - if self.is_import_coupler() || !self.eat(&token::PathSep) { + if self.is_import_coupler() || !self.eat_path_sep() { if style == PathStyle::Expr && self.may_recover() && self.token == token::Colon @@ -272,6 +272,18 @@ impl<'a> Parser<'a> { } } + /// Eat `::` or, potentially, `:::`. + #[must_use] + pub(super) fn eat_path_sep(&mut self) -> bool { + let result = self.eat(&token::PathSep); + if result && self.may_recover() { + if self.eat_noexpect(&token::Colon) { + self.dcx().emit_err(PathTripleColon { span: self.prev_token.span }); + } + } + result + } + pub(super) fn parse_path_segment( &mut self, style: PathStyle, @@ -297,9 +309,7 @@ impl<'a> Parser<'a> { Ok( if style == PathStyle::Type && check_args_start(self) - || style != PathStyle::Mod - && self.check(&token::PathSep) - && self.look_ahead(1, |t| is_args_start(t)) + || style != PathStyle::Mod && self.check_path_sep_and_look_ahead(is_args_start) { // We use `style == PathStyle::Expr` to check if this is in a recursion or not. If // it isn't, then we reset the unmatched angle bracket count as we're about to start @@ -310,7 +320,8 @@ impl<'a> Parser<'a> { // Generic arguments are found - `<`, `(`, `::<` or `::(`. // First, eat `::` if it exists. - let _ = self.eat(&token::PathSep); + let _ = self.eat_path_sep(); + let lo = self.token.span; let args = if self.eat_lt() { // `<'a, T, A = U>` |
