diff options
Diffstat (limited to 'compiler/rustc_parse/src')
| -rw-r--r-- | compiler/rustc_parse/src/errors.rs | 17 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/cfg_select.rs | 30 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/pat.rs | 18 |
3 files changed, 44 insertions, 21 deletions
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index a07d0606fd0..a105dd1909e 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -2661,7 +2661,7 @@ pub(crate) enum TopLevelOrPatternNotAllowedSugg { parse_sugg_remove_leading_vert_in_pattern, code = "", applicability = "machine-applicable", - style = "verbose" + style = "tool-only" )] RemoveLeadingVert { #[primary_span] @@ -2694,12 +2694,25 @@ pub(crate) struct UnexpectedVertVertInPattern { pub start: Option<Span>, } +#[derive(Subdiagnostic)] +#[suggestion( + parse_trailing_vert_not_allowed, + code = "", + applicability = "machine-applicable", + style = "tool-only" +)] +pub(crate) struct TrailingVertSuggestion { + #[primary_span] + pub span: Span, +} + #[derive(Diagnostic)] #[diag(parse_trailing_vert_not_allowed)] pub(crate) struct TrailingVertNotAllowed { #[primary_span] - #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")] pub span: Span, + #[subdiagnostic] + pub suggestion: TrailingVertSuggestion, #[label(parse_label_while_parsing_or_pattern_here)] pub start: Option<Span>, pub token: Token, diff --git a/compiler/rustc_parse/src/parser/cfg_select.rs b/compiler/rustc_parse/src/parser/cfg_select.rs index 2c6fb224d70..08a71db4de8 100644 --- a/compiler/rustc_parse/src/parser/cfg_select.rs +++ b/compiler/rustc_parse/src/parser/cfg_select.rs @@ -1,11 +1,12 @@ use rustc_ast::token::Token; use rustc_ast::tokenstream::{TokenStream, TokenTree}; +use rustc_ast::util::classify; use rustc_ast::{MetaItemInner, token}; use rustc_errors::PResult; use rustc_span::Span; use crate::exp; -use crate::parser::Parser; +use crate::parser::{AttrWrapper, ForceCollect, Parser, Restrictions, Trailing, UsePreAttrPos}; pub enum CfgSelectPredicate { Cfg(MetaItemInner), @@ -23,19 +24,26 @@ pub struct CfgSelectBranches { pub unreachable: Vec<(CfgSelectPredicate, TokenStream, Span)>, } -/// Parses a `TokenTree` that must be of the form `{ /* ... */ }`, and returns a `TokenStream` where -/// the surrounding braces are stripped. +/// Parses a `TokenTree` consisting either of `{ /* ... */ }` (and strip the braces) or an +/// expression followed by a comma (and strip the comma). fn parse_token_tree<'a>(p: &mut Parser<'a>) -> PResult<'a, TokenStream> { - // Generate an error if the `=>` is not followed by `{`. - if p.token != token::OpenBrace { - p.expect(exp!(OpenBrace))?; + if p.token == token::OpenBrace { + // Strip the outer '{' and '}'. + match p.parse_token_tree() { + TokenTree::Token(..) => unreachable!("because of the expect above"), + TokenTree::Delimited(.., tts) => return Ok(tts), + } } - - // Strip the outer '{' and '}'. - match p.parse_token_tree() { - TokenTree::Token(..) => unreachable!("because of the expect above"), - TokenTree::Delimited(.., tts) => Ok(tts), + let expr = p.collect_tokens(None, AttrWrapper::empty(), ForceCollect::Yes, |p, _| { + p.parse_expr_res(Restrictions::STMT_EXPR, AttrWrapper::empty()) + .map(|(expr, _)| (expr, Trailing::No, UsePreAttrPos::No)) + })?; + if !classify::expr_is_complete(&expr) && p.token != token::CloseBrace && p.token != token::Eof { + p.expect(exp!(Comma))?; + } else { + let _ = p.eat(exp!(Comma)); } + Ok(TokenStream::from_ast(&expr)) } pub fn parse_cfg_select<'a>(p: &mut Parser<'a>) -> PResult<'a, CfgSelectBranches> { diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index a415849b915..9754691a0b9 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -24,10 +24,10 @@ use crate::errors::{ GenericArgsInPatRequireTurbofishSyntax, InclusiveRangeExtraEquals, InclusiveRangeMatchArrow, InclusiveRangeNoEnd, InvalidMutInPattern, ParenRangeSuggestion, PatternOnWrongSideOfAt, RemoveLet, RepeatedMutInPattern, SwitchRefBoxOrder, TopLevelOrPatternNotAllowed, - TopLevelOrPatternNotAllowedSugg, TrailingVertNotAllowed, UnexpectedExpressionInPattern, - UnexpectedExpressionInPatternSugg, UnexpectedLifetimeInPattern, UnexpectedParenInRangePat, - UnexpectedParenInRangePatSugg, UnexpectedVertVertBeforeFunctionParam, - UnexpectedVertVertInPattern, WrapInParens, + TopLevelOrPatternNotAllowedSugg, TrailingVertNotAllowed, TrailingVertSuggestion, + UnexpectedExpressionInPattern, UnexpectedExpressionInPatternSugg, UnexpectedLifetimeInPattern, + UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg, + UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern, WrapInParens, }; use crate::parser::expr::{DestructuredFloat, could_be_unclosed_char_literal}; use crate::{exp, maybe_recover_from_interpolated_ty_qpath}; @@ -267,10 +267,9 @@ impl<'a> Parser<'a> { if let PatKind::Or(pats) = &pat.kind { let span = pat.span; - let sub = if pats.len() == 1 { - Some(TopLevelOrPatternNotAllowedSugg::RemoveLeadingVert { - span: span.with_hi(span.lo() + BytePos(1)), - }) + let sub = if let [_] = &pats[..] { + let span = span.with_hi(span.lo() + BytePos(1)); + Some(TopLevelOrPatternNotAllowedSugg::RemoveLeadingVert { span }) } else { Some(TopLevelOrPatternNotAllowedSugg::WrapInParens { span, @@ -362,6 +361,9 @@ impl<'a> Parser<'a> { self.dcx().emit_err(TrailingVertNotAllowed { span: self.token.span, start: lo, + suggestion: TrailingVertSuggestion { + span: self.prev_token.span.shrink_to_hi().with_hi(self.token.span.hi()), + }, token: self.token, note_double_vert: self.token.kind == token::OrOr, }); |
