diff options
| author | bors <bors@rust-lang.org> | 2024-10-08 11:27:18 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-10-08 11:27:18 +0000 |
| commit | 84a16c49d4c23a3c2c16d058ce542ca52e07112a (patch) | |
| tree | 9d5b39941405bec4b7c4571606df8b88850325e9 /compiler/rustc_parse/src/parser | |
| parent | 76fc27a178d999358ac2105b8868cc8a45a2513f (diff) | |
| parent | 4316afffd9390bdac1d3bd5e5398c65d6e9bb150 (diff) | |
| download | rust-84a16c49d4c23a3c2c16d058ce542ca52e07112a.tar.gz rust-84a16c49d4c23a3c2c16d058ce542ca52e07112a.zip | |
Auto merge of #18267 - lnicola:sync-from-rust, r=lnicola
minor: Sync from downstream
Diffstat (limited to 'compiler/rustc_parse/src/parser')
| -rw-r--r-- | compiler/rustc_parse/src/parser/attr.rs | 14 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/pat.rs | 54 |
2 files changed, 49 insertions, 19 deletions
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs index c65cf3f40f6..b6fa2099588 100644 --- a/compiler/rustc_parse/src/parser/attr.rs +++ b/compiler/rustc_parse/src/parser/attr.rs @@ -356,8 +356,10 @@ impl<'a> Parser<'a> { } /// Parses `cfg_attr(pred, attr_item_list)` where `attr_item_list` is comma-delimited. - pub fn parse_cfg_attr(&mut self) -> PResult<'a, (ast::MetaItem, Vec<(ast::AttrItem, Span)>)> { - let cfg_predicate = self.parse_meta_item(AllowLeadingUnsafe::No)?; + pub fn parse_cfg_attr( + &mut self, + ) -> PResult<'a, (ast::MetaItemInner, Vec<(ast::AttrItem, Span)>)> { + let cfg_predicate = self.parse_meta_item_inner()?; self.expect(&token::Comma)?; // Presumably, the majority of the time there will only be one attr. @@ -375,7 +377,7 @@ impl<'a> Parser<'a> { } /// Matches `COMMASEP(meta_item_inner)`. - pub(crate) fn parse_meta_seq_top(&mut self) -> PResult<'a, ThinVec<ast::NestedMetaItem>> { + pub(crate) fn parse_meta_seq_top(&mut self) -> PResult<'a, ThinVec<ast::MetaItemInner>> { // Presumably, the majority of the time there will only be one attr. let mut nmis = ThinVec::with_capacity(1); while self.token != token::Eof { @@ -452,14 +454,14 @@ impl<'a> Parser<'a> { /// ```ebnf /// MetaItemInner = UNSUFFIXED_LIT | MetaItem ; /// ``` - fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> { + pub fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::MetaItemInner> { match self.parse_unsuffixed_meta_item_lit() { - Ok(lit) => return Ok(ast::NestedMetaItem::Lit(lit)), + Ok(lit) => return Ok(ast::MetaItemInner::Lit(lit)), Err(err) => err.cancel(), // we provide a better error below } match self.parse_meta_item(AllowLeadingUnsafe::No) { - Ok(mi) => return Ok(ast::NestedMetaItem::MetaItem(mi)), + Ok(mi) => return Ok(ast::MetaItemInner::MetaItem(mi)), Err(err) => err.cancel(), // we provide a better error below } diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index bd2ffaa0a89..7f114013320 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -17,15 +17,16 @@ use thin_vec::{ThinVec, thin_vec}; use super::{ForceCollect, Parser, PathStyle, Restrictions, Trailing, UsePreAttrPos}; use crate::errors::{ - self, AmbiguousRangePattern, DotDotDotForRemainingFields, DotDotDotRangeToPatternNotAllowed, - DotDotDotRestPattern, EnumPatternInsteadOfIdentifier, ExpectedBindingLeftOfAt, - ExpectedCommaAfterPatternField, GenericArgsInPatRequireTurbofishSyntax, - InclusiveRangeExtraEquals, InclusiveRangeMatchArrow, InclusiveRangeNoEnd, InvalidMutInPattern, - ParenRangeSuggestion, PatternOnWrongSideOfAt, RemoveLet, RepeatedMutInPattern, - SwitchRefBoxOrder, TopLevelOrPatternNotAllowed, TopLevelOrPatternNotAllowedSugg, - TrailingVertNotAllowed, UnexpectedExpressionInPattern, UnexpectedExpressionInPatternSugg, - UnexpectedLifetimeInPattern, UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg, - UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern, WrapInParens, + self, AmbiguousRangePattern, AtDotDotInStructPattern, AtInStructPattern, + DotDotDotForRemainingFields, DotDotDotRangeToPatternNotAllowed, DotDotDotRestPattern, + EnumPatternInsteadOfIdentifier, ExpectedBindingLeftOfAt, ExpectedCommaAfterPatternField, + GenericArgsInPatRequireTurbofishSyntax, InclusiveRangeExtraEquals, InclusiveRangeMatchArrow, + InclusiveRangeNoEnd, InvalidMutInPattern, ParenRangeSuggestion, PatternOnWrongSideOfAt, + RemoveLet, RepeatedMutInPattern, SwitchRefBoxOrder, TopLevelOrPatternNotAllowed, + TopLevelOrPatternNotAllowedSugg, TrailingVertNotAllowed, UnexpectedExpressionInPattern, + UnexpectedExpressionInPatternSugg, UnexpectedLifetimeInPattern, UnexpectedParenInRangePat, + UnexpectedParenInRangePatSugg, UnexpectedVertVertBeforeFunctionParam, + UnexpectedVertVertInPattern, WrapInParens, }; use crate::parser::expr::{DestructuredFloat, could_be_unclosed_char_literal}; use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole}; @@ -1433,7 +1434,7 @@ impl<'a> Parser<'a> { /// Parses the fields of a struct-like pattern. fn parse_pat_fields(&mut self) -> PResult<'a, (ThinVec<PatField>, PatFieldsRest)> { - let mut fields = ThinVec::new(); + let mut fields: ThinVec<PatField> = ThinVec::new(); let mut etc = PatFieldsRest::None; let mut ate_comma = true; let mut delayed_err: Option<Diag<'a>> = None; @@ -1454,12 +1455,22 @@ impl<'a> Parser<'a> { // check that a comma comes after every field if !ate_comma { - let mut err = - self.dcx().create_err(ExpectedCommaAfterPatternField { span: self.token.span }); + let err = if self.token == token::At { + let prev_field = fields + .last() + .expect("Unreachable on first iteration, not empty otherwise") + .ident; + self.report_misplaced_at_in_struct_pat(prev_field) + } else { + let mut err = self + .dcx() + .create_err(ExpectedCommaAfterPatternField { span: self.token.span }); + self.recover_misplaced_pattern_modifiers(&fields, &mut err); + err + }; if let Some(delayed) = delayed_err { delayed.emit(); } - self.recover_misplaced_pattern_modifiers(&fields, &mut err); return Err(err); } ate_comma = false; @@ -1594,6 +1605,23 @@ impl<'a> Parser<'a> { Ok((fields, etc)) } + #[deny(rustc::untranslatable_diagnostic)] + fn report_misplaced_at_in_struct_pat(&self, prev_field: Ident) -> Diag<'a> { + debug_assert_eq!(self.token, token::At); + let span = prev_field.span.to(self.token.span); + if let Some(dot_dot_span) = + self.look_ahead(1, |t| if t == &token::DotDot { Some(t.span) } else { None }) + { + self.dcx().create_err(AtDotDotInStructPattern { + span: span.to(dot_dot_span), + remove: span.until(dot_dot_span), + ident: prev_field, + }) + } else { + self.dcx().create_err(AtInStructPattern { span: span }) + } + } + /// If the user writes `S { ref field: name }` instead of `S { field: ref name }`, we suggest /// the correct code. fn recover_misplaced_pattern_modifiers(&self, fields: &ThinVec<PatField>, err: &mut Diag<'a>) { |
