about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser/item.rs
diff options
context:
space:
mode:
authorCatherine <catherine.3.flores@gmail.com>2023-07-24 04:55:47 +0000
committerCatherine Flores <catherine.3.flores@gmail.com>2023-07-24 00:25:17 -0500
commit287db04636ffefa3fdaa39fe0fdcc3cf75b60444 (patch)
tree745b89b10863c02ffe96a33220b12aea6fcfcca2 /compiler/rustc_parse/src/parser/item.rs
parent8771282d4e7a5c4569e49d1f878fb3ba90a974d0 (diff)
downloadrust-287db04636ffefa3fdaa39fe0fdcc3cf75b60444.tar.gz
rust-287db04636ffefa3fdaa39fe0fdcc3cf75b60444.zip
Specify macro is invalid in certain contexts
Diffstat (limited to 'compiler/rustc_parse/src/parser/item.rs')
-rw-r--r--compiler/rustc_parse/src/parser/item.rs26
1 files changed, 18 insertions, 8 deletions
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 1470180dea7..6ec3a1ff1a5 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1,8 +1,8 @@
-use crate::errors;
-
 use super::diagnostics::{dummy_arg, ConsumeClosingDelim};
 use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
 use super::{AttrWrapper, FollowedByType, ForceCollect, Parser, PathStyle, TrailingToken};
+use crate::errors::{self, MacroExpandsToAdtField};
+use crate::fluent_generated as fluent;
 use ast::StaticItem;
 use rustc_ast::ast::*;
 use rustc_ast::ptr::P;
@@ -1342,6 +1342,13 @@ impl<'a> Parser<'a> {
                 }
                 let ident = this.parse_field_ident("enum", vlo)?;
 
+                if this.token == token::Not {
+                    return this.unexpected().map_err(|mut err| {
+                        err.note(fluent::parse_macro_expands_to_enum_variant);
+                        err
+                    });
+                }
+
                 let struct_def = if this.check(&token::OpenDelim(Delimiter::Brace)) {
                     // Parse a struct variant.
                     let (fields, recovered) =
@@ -1369,7 +1376,7 @@ impl<'a> Parser<'a> {
 
                 Ok((Some(vr), TrailingToken::MaybeComma))
             },
-        ).map_err(|mut err|{
+        ).map_err(|mut err| {
             err.help("enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`");
             err
         })
@@ -1691,9 +1698,10 @@ impl<'a> Parser<'a> {
         Ok(a_var)
     }
 
-    fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> {
+    fn expect_field_ty_separator(&mut self, adt_ty: &str) -> PResult<'a, ()> {
         if let Err(mut err) = self.expect(&token::Colon) {
             let sm = self.sess.source_map();
+            let mac_invoc = self.token.kind == token::Not;
             let eq_typo = self.token.kind == token::Eq && self.look_ahead(1, |t| t.is_path_start());
             let semi_typo = self.token.kind == token::Semi
                 && self.look_ahead(1, |t| {
@@ -1705,7 +1713,9 @@ impl<'a> Parser<'a> {
                         _ => true,
                     }
                 });
-            if eq_typo || semi_typo {
+            if mac_invoc {
+                err.subdiagnostic(MacroExpandsToAdtField { adt_ty }).emit();
+            } else if eq_typo || semi_typo {
                 self.bump();
                 // Gracefully handle small typos.
                 err.span_suggestion_short(
@@ -1713,8 +1723,8 @@ impl<'a> Parser<'a> {
                     "field names and their types are separated with `:`",
                     ":",
                     Applicability::MachineApplicable,
-                );
-                err.emit();
+                )
+                .emit();
             } else {
                 return Err(err);
             }
@@ -1731,7 +1741,7 @@ impl<'a> Parser<'a> {
         attrs: AttrVec,
     ) -> PResult<'a, FieldDef> {
         let name = self.parse_field_ident(adt_ty, lo)?;
-        self.expect_field_ty_separator()?;
+        self.expect_field_ty_separator(adt_ty)?;
         let ty = self.parse_ty()?;
         if self.token.kind == token::Colon && self.look_ahead(1, |tok| tok.kind != token::Colon) {
             self.sess.emit_err(errors::SingleColonStructType { span: self.token.span });