Rollup merge of #113999 - Centri3:macro-arm-expand, r=wesleywiser
Specify macro is invalid in certain contexts Adds a note when a macro is used where it really shouldn't be. Closes #113766
This commit is contained in:
commit
1f076fe1d8
9 changed files with 246 additions and 24 deletions
|
@ -1815,6 +1815,12 @@ pub struct UnknownPrefix<'a> {
|
|||
pub sugg: Option<UnknownPrefixSugg>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[note(parse_macro_expands_to_adt_field)]
|
||||
pub struct MacroExpandsToAdtField<'a> {
|
||||
pub adt_ty: &'a str,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum UnknownPrefixSugg {
|
||||
#[suggestion(
|
||||
|
|
|
@ -2641,6 +2641,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 {
|
||||
|
@ -2661,24 +2662,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)
|
||||
|
|
|
@ -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;
|
||||
|
@ -1450,6 +1450,17 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
let ident = this.parse_field_ident("enum", vlo)?;
|
||||
|
||||
if this.token == token::Not {
|
||||
if let Err(mut err) = this.unexpected::<()>() {
|
||||
err.note(fluent::parse_macro_expands_to_enum_variant).emit();
|
||||
}
|
||||
|
||||
this.bump();
|
||||
this.parse_delim_args()?;
|
||||
|
||||
return Ok((None, TrailingToken::MaybeComma));
|
||||
}
|
||||
|
||||
let struct_def = if this.check(&token::OpenDelim(Delimiter::Brace)) {
|
||||
// Parse a struct variant.
|
||||
let (fields, recovered) =
|
||||
|
@ -1477,7 +1488,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
|
||||
})
|
||||
|
@ -1687,7 +1698,8 @@ impl<'a> Parser<'a> {
|
|||
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
|
||||
let lo = this.token.span;
|
||||
let vis = this.parse_visibility(FollowedByType::No)?;
|
||||
Ok((this.parse_single_struct_field(adt_ty, lo, vis, attrs)?, TrailingToken::None))
|
||||
this.parse_single_struct_field(adt_ty, lo, vis, attrs)
|
||||
.map(|field| (field, TrailingToken::None))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1821,8 +1833,8 @@ impl<'a> Parser<'a> {
|
|||
"field names and their types are separated with `:`",
|
||||
":",
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.emit();
|
||||
)
|
||||
.emit();
|
||||
} else {
|
||||
return Err(err);
|
||||
}
|
||||
|
@ -1839,6 +1851,23 @@ impl<'a> Parser<'a> {
|
|||
attrs: AttrVec,
|
||||
) -> PResult<'a, FieldDef> {
|
||||
let name = self.parse_field_ident(adt_ty, lo)?;
|
||||
// Parse the macro invocation and recover
|
||||
if self.token.kind == token::Not {
|
||||
if let Err(mut err) = self.unexpected::<FieldDef>() {
|
||||
err.subdiagnostic(MacroExpandsToAdtField { adt_ty }).emit();
|
||||
self.bump();
|
||||
self.parse_delim_args()?;
|
||||
return Ok(FieldDef {
|
||||
span: DUMMY_SP,
|
||||
ident: None,
|
||||
vis,
|
||||
id: DUMMY_NODE_ID,
|
||||
ty: self.mk_ty(DUMMY_SP, TyKind::Err),
|
||||
attrs,
|
||||
is_placeholder: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
self.expect_field_ty_separator()?;
|
||||
let ty = self.parse_ty()?;
|
||||
if self.token.kind == token::Colon && self.look_ahead(1, |tok| tok.kind != token::Colon) {
|
||||
|
|
|
@ -142,7 +142,11 @@ impl<'a> Parser<'a> {
|
|||
// Parse the first pattern (`p_0`).
|
||||
let mut first_pat = self.parse_pat_no_top_alt(expected, syntax_loc)?;
|
||||
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 `|`,
|
||||
|
@ -184,7 +188,7 @@ impl<'a> Parser<'a> {
|
|||
err
|
||||
})?;
|
||||
if rc == RecoverComma::Yes {
|
||||
self.maybe_recover_unexpected_comma(pat.span, rt)?;
|
||||
self.maybe_recover_unexpected_comma(pat.span, false, rt)?;
|
||||
}
|
||||
pats.push(pat);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue