diff options
| author | Catherine <catherine.3.flores@gmail.com> | 2023-07-24 04:55:47 +0000 |
|---|---|---|
| committer | Catherine Flores <catherine.3.flores@gmail.com> | 2023-07-24 00:25:17 -0500 |
| commit | 287db04636ffefa3fdaa39fe0fdcc3cf75b60444 (patch) | |
| tree | 745b89b10863c02ffe96a33220b12aea6fcfcca2 /compiler/rustc_parse/src | |
| parent | 8771282d4e7a5c4569e49d1f878fb3ba90a974d0 (diff) | |
| download | rust-287db04636ffefa3fdaa39fe0fdcc3cf75b60444.tar.gz rust-287db04636ffefa3fdaa39fe0fdcc3cf75b60444.zip | |
Specify macro is invalid in certain contexts
Diffstat (limited to 'compiler/rustc_parse/src')
| -rw-r--r-- | compiler/rustc_parse/src/errors.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/diagnostics.rs | 37 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/item.rs | 26 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/parser/pat.rs | 12 |
4 files changed, 55 insertions, 26 deletions
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 96e1c0e3c6d..7f209c63f42 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -1801,6 +1801,12 @@ pub struct UnknownPrefix<'a> { } #[derive(Subdiagnostic)] +#[note(parse_macro_expands_to_adt_field)] +pub struct MacroExpandsToAdtField<'a> { + pub adt_ty: &'a str, +} + +#[derive(Subdiagnostic)] pub enum UnknownPrefixSugg { #[suggestion( parse_suggestion_br, diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index c3cf6437afa..3eed3ed9e1b 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -2591,6 +2591,7 @@ impl<'a> Parser<'a> { pub(crate) fn maybe_recover_unexpected_comma( &mut self, lo: Span, + is_mac_invoc: bool, rt: CommaRecoveryMode, ) -> PResult<'a, ()> { if self.token != token::Comma { @@ -2611,24 +2612,28 @@ impl<'a> Parser<'a> { let seq_span = lo.to(self.prev_token.span); let mut err = self.struct_span_err(comma_span, "unexpected `,` in pattern"); if let Ok(seq_snippet) = self.span_to_snippet(seq_span) { - err.multipart_suggestion( - format!( - "try adding parentheses to match on a tuple{}", - if let CommaRecoveryMode::LikelyTuple = rt { "" } else { "..." }, - ), - vec![ - (seq_span.shrink_to_lo(), "(".to_string()), - (seq_span.shrink_to_hi(), ")".to_string()), - ], - Applicability::MachineApplicable, - ); - if let CommaRecoveryMode::EitherTupleOrPipe = rt { - err.span_suggestion( - seq_span, - "...or a vertical bar to match on multiple alternatives", - seq_snippet.replace(',', " |"), + if is_mac_invoc { + err.note(fluent::parse_macro_expands_to_match_arm); + } else { + err.multipart_suggestion( + format!( + "try adding parentheses to match on a tuple{}", + if let CommaRecoveryMode::LikelyTuple = rt { "" } else { "..." }, + ), + vec![ + (seq_span.shrink_to_lo(), "(".to_string()), + (seq_span.shrink_to_hi(), ")".to_string()), + ], Applicability::MachineApplicable, ); + if let CommaRecoveryMode::EitherTupleOrPipe = rt { + err.span_suggestion( + seq_span, + "...or a vertical bar to match on multiple alternatives", + seq_snippet.replace(',', " |"), + Applicability::MachineApplicable, + ); + } } } Err(err) 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 }); diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs index 14891c45d81..b477453615d 100644 --- a/compiler/rustc_parse/src/parser/pat.rs +++ b/compiler/rustc_parse/src/parser/pat.rs @@ -135,7 +135,11 @@ impl<'a> Parser<'a> { // Parse the first pattern (`p_0`). let mut first_pat = self.parse_pat_no_top_alt(expected)?; if rc == RecoverComma::Yes { - self.maybe_recover_unexpected_comma(first_pat.span, rt)?; + self.maybe_recover_unexpected_comma( + first_pat.span, + matches!(first_pat.kind, PatKind::MacCall(_)), + rt, + )?; } // If the next token is not a `|`, @@ -177,7 +181,11 @@ impl<'a> Parser<'a> { err })?; if rc == RecoverComma::Yes { - self.maybe_recover_unexpected_comma(pat.span, rt)?; + self.maybe_recover_unexpected_comma( + pat.span, + matches!(pat.kind, PatKind::MacCall(_)), + rt, + )?; } pats.push(pat); } |
