about summary refs log tree commit diff
path: root/compiler/rustc_parse/src
diff options
context:
space:
mode:
authorLaurențiu Nicola <lnicola@dend.ro>2024-10-08 14:25:39 +0300
committerLaurențiu Nicola <lnicola@dend.ro>2024-10-08 14:25:39 +0300
commit4316afffd9390bdac1d3bd5e5398c65d6e9bb150 (patch)
tree9d5b39941405bec4b7c4571606df8b88850325e9 /compiler/rustc_parse/src
parent537fb8d1bb2405b118898c663bc076815a1762c7 (diff)
parentcf24c73141a77db730f4b7fda69dcd7e8b113b51 (diff)
downloadrust-4316afffd9390bdac1d3bd5e5398c65d6e9bb150.tar.gz
rust-4316afffd9390bdac1d3bd5e5398c65d6e9bb150.zip
Merge from rust-lang/rust
Diffstat (limited to 'compiler/rustc_parse/src')
-rw-r--r--compiler/rustc_parse/src/errors.rs20
-rw-r--r--compiler/rustc_parse/src/lib.rs4
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs14
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs54
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs6
5 files changed, 74 insertions, 24 deletions
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 20bcefd4fe1..dade3912751 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -2572,6 +2572,25 @@ pub(crate) struct EnumPatternInsteadOfIdentifier {
 }
 
 #[derive(Diagnostic)]
+#[diag(parse_at_dot_dot_in_struct_pattern)]
+pub(crate) struct AtDotDotInStructPattern {
+    #[primary_span]
+    pub span: Span,
+    #[suggestion(code = "", style = "verbose", applicability = "machine-applicable")]
+    pub remove: Span,
+    pub ident: Ident,
+}
+
+#[derive(Diagnostic)]
+#[diag(parse_at_in_struct_pattern)]
+#[note]
+#[help]
+pub(crate) struct AtInStructPattern {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(parse_dot_dot_dot_for_remaining_fields)]
 pub(crate) struct DotDotDotForRemainingFields {
     #[primary_span]
@@ -2589,6 +2608,7 @@ pub(crate) struct ExpectedCommaAfterPatternField {
 
 #[derive(Diagnostic)]
 #[diag(parse_unexpected_expr_in_pat)]
+#[note]
 pub(crate) struct UnexpectedExpressionInPattern {
     /// The unexpected expr's span.
     #[primary_span]
diff --git a/compiler/rustc_parse/src/lib.rs b/compiler/rustc_parse/src/lib.rs
index f7a8b8780ed..2792050a0b3 100644
--- a/compiler/rustc_parse/src/lib.rs
+++ b/compiler/rustc_parse/src/lib.rs
@@ -18,7 +18,7 @@ use std::path::Path;
 
 use rustc_ast as ast;
 use rustc_ast::tokenstream::TokenStream;
-use rustc_ast::{AttrItem, Attribute, MetaItem, token};
+use rustc_ast::{AttrItem, Attribute, MetaItemInner, token};
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::sync::Lrc;
 use rustc_errors::{Diag, FatalError, PResult};
@@ -160,7 +160,7 @@ pub fn fake_token_stream_for_crate(psess: &ParseSess, krate: &ast::Crate) -> Tok
 pub fn parse_cfg_attr(
     cfg_attr: &Attribute,
     psess: &ParseSess,
-) -> Option<(MetaItem, Vec<(AttrItem, Span)>)> {
+) -> Option<(MetaItemInner, Vec<(AttrItem, Span)>)> {
     const CFG_ATTR_GRAMMAR_HELP: &str = "#[cfg_attr(condition, attribute, other_attribute, ...)]";
     const CFG_ATTR_NOTE_REF: &str = "for more information, visit \
         <https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>";
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>) {
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index b15d1edf79c..f3174e7dea2 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -3,8 +3,8 @@
 use rustc_ast::token::Delimiter;
 use rustc_ast::tokenstream::DelimSpan;
 use rustc_ast::{
-    self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, MetaItemKind,
-    NestedMetaItem, Safety,
+    self as ast, AttrArgs, AttrArgsEq, Attribute, DelimArgs, MetaItem, MetaItemInner, MetaItemKind,
+    Safety,
 };
 use rustc_errors::{Applicability, FatalError, PResult};
 use rustc_feature::{AttributeSafety, AttributeTemplate, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
@@ -143,7 +143,7 @@ pub(super) fn check_cfg_attr_bad_delim(psess: &ParseSess, span: DelimSpan, delim
 
 /// Checks that the given meta-item is compatible with this `AttributeTemplate`.
 fn is_attr_template_compatible(template: &AttributeTemplate, meta: &ast::MetaItemKind) -> bool {
-    let is_one_allowed_subword = |items: &[NestedMetaItem]| match items {
+    let is_one_allowed_subword = |items: &[MetaItemInner]| match items {
         [item] => item.is_word() && template.one_of.iter().any(|&word| item.has_name(word)),
         _ => false,
     };