Recover from some macros

This commit is contained in:
Catherine Flores 2023-07-24 17:05:10 +00:00
parent 287db04636
commit dece622ee4
9 changed files with 127 additions and 105 deletions

View file

@ -1343,10 +1343,14 @@ impl<'a> Parser<'a> {
let ident = this.parse_field_ident("enum", vlo)?; let ident = this.parse_field_ident("enum", vlo)?;
if this.token == token::Not { if this.token == token::Not {
return this.unexpected().map_err(|mut err| { if let Err(mut err) = this.unexpected::<()>() {
err.note(fluent::parse_macro_expands_to_enum_variant); err.note(fluent::parse_macro_expands_to_enum_variant).emit();
err }
});
this.bump();
this.parse_delim_args()?;
return Ok((None, TrailingToken::MaybeComma));
} }
let struct_def = if this.check(&token::OpenDelim(Delimiter::Brace)) { let struct_def = if this.check(&token::OpenDelim(Delimiter::Brace)) {
@ -1586,7 +1590,8 @@ impl<'a> Parser<'a> {
self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| { self.collect_tokens_trailing_token(attrs, ForceCollect::No, |this, attrs| {
let lo = this.token.span; let lo = this.token.span;
let vis = this.parse_visibility(FollowedByType::No)?; 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))
}) })
} }
@ -1698,10 +1703,9 @@ impl<'a> Parser<'a> {
Ok(a_var) Ok(a_var)
} }
fn expect_field_ty_separator(&mut self, adt_ty: &str) -> PResult<'a, ()> { fn expect_field_ty_separator(&mut self) -> PResult<'a, ()> {
if let Err(mut err) = self.expect(&token::Colon) { if let Err(mut err) = self.expect(&token::Colon) {
let sm = self.sess.source_map(); 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 eq_typo = self.token.kind == token::Eq && self.look_ahead(1, |t| t.is_path_start());
let semi_typo = self.token.kind == token::Semi let semi_typo = self.token.kind == token::Semi
&& self.look_ahead(1, |t| { && self.look_ahead(1, |t| {
@ -1713,9 +1717,7 @@ impl<'a> Parser<'a> {
_ => true, _ => true,
} }
}); });
if mac_invoc { if eq_typo || semi_typo {
err.subdiagnostic(MacroExpandsToAdtField { adt_ty }).emit();
} else if eq_typo || semi_typo {
self.bump(); self.bump();
// Gracefully handle small typos. // Gracefully handle small typos.
err.span_suggestion_short( err.span_suggestion_short(
@ -1741,7 +1743,29 @@ impl<'a> Parser<'a> {
attrs: AttrVec, attrs: AttrVec,
) -> PResult<'a, FieldDef> { ) -> PResult<'a, FieldDef> {
let name = self.parse_field_ident(adt_ty, lo)?; let name = self.parse_field_ident(adt_ty, lo)?;
self.expect_field_ty_separator(adt_ty)?; // 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: P(Ty {
id: DUMMY_NODE_ID,
kind: TyKind::Err,
span: DUMMY_SP,
tokens: None,
}),
attrs,
is_placeholder: false,
});
}
}
self.expect_field_ty_separator()?;
let ty = self.parse_ty()?; let ty = self.parse_ty()?;
if self.token.kind == token::Colon && self.look_ahead(1, |tok| tok.kind != token::Colon) { 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 }); self.sess.emit_err(errors::SingleColonStructType { span: self.token.span });

View file

@ -181,11 +181,7 @@ impl<'a> Parser<'a> {
err err
})?; })?;
if rc == RecoverComma::Yes { if rc == RecoverComma::Yes {
self.maybe_recover_unexpected_comma( self.maybe_recover_unexpected_comma(pat.span, false, rt)?;
pat.span,
matches!(pat.kind, PatKind::MacCall(_)),
rt,
)?;
} }
pats.push(pat); pats.push(pat);
} }

View file

@ -1,16 +0,0 @@
#![no_main]
macro_rules! field {
($name:ident:$type:ty) => {
$name:$type
};
}
enum EnumVariantField {
Named { //~ NOTE while parsing this struct
field!(oopsies:()), //~ NOTE macros cannot expand to struct fields
//~^ ERROR expected `:`, found `!`
//~^^ ERROR expected `,`, or `}`, found `(`
//~^^^ NOTE expected `:`
},
}

View file

@ -1,18 +0,0 @@
error: expected `:`, found `!`
--> $DIR/macro-expand-to-field-2.rs:11:14
|
LL | field!(oopsies:()),
| ^ expected `:`
|
= note: macros cannot expand to struct fields
error: expected `,`, or `}`, found `(`
--> $DIR/macro-expand-to-field-2.rs:11:15
|
LL | Named {
| ----- while parsing this struct
LL | field!(oopsies:()),
| ^
error: aborting due to 2 previous errors

View file

@ -1,15 +0,0 @@
#![no_main]
macro_rules! field {
($name:ident:$type:ty) => {
$name:$type
};
}
union EnumVariantField { //~ NOTE while parsing this union
A: u32,
field!(oopsies:()), //~ NOTE macros cannot expand to union fields
//~^ ERROR expected `:`, found `!`
//~^^ ERROR expected `,`, or `}`, found `(`
//~^^^ NOTE expected `:`
}

View file

@ -1,19 +0,0 @@
error: expected `:`, found `!`
--> $DIR/macro-expand-to-field-3.rs:11:10
|
LL | field!(oopsies:()),
| ^ expected `:`
|
= note: macros cannot expand to union fields
error: expected `,`, or `}`, found `(`
--> $DIR/macro-expand-to-field-3.rs:11:11
|
LL | union EnumVariantField {
| ---------------- while parsing this union
LL | A: u32,
LL | field!(oopsies:()),
| ^
error: aborting due to 2 previous errors

View file

@ -12,15 +12,46 @@ macro_rules! variant {
} }
} }
struct Struct { //~ NOTE while parsing this struct struct Struct {
field!(bar:u128), //~ NOTE macros cannot expand to struct fields field!(bar:u128), //~ NOTE macros cannot expand to struct fields
//~^ ERROR expected `:`, found `!` //~^ ERROR unexpected token: `!`
//~^^ NOTE expected `:` //~^^ NOTE unexpected token after this
//~^^^ ERROR expected `,`, or `}`, found `(` a: u32,
} b: u32,
field!(recovers:()), //~ NOTE macros cannot expand to struct fields
enum EnumVariant { //~ NOTE while parsing this enum
variant!(whoops), //~ NOTE macros cannot expand to enum variants
//~^ ERROR unexpected token: `!` //~^ ERROR unexpected token: `!`
//~^^ NOTE unexpected token after this //~^^ NOTE unexpected token after this
} }
enum EnumVariant {
variant!(whoops), //~ NOTE macros cannot expand to enum variants
//~^ ERROR unexpected token: `!`
//~^^ NOTE unexpected token after this
U32,
F64,
variant!(recovers), //~ NOTE macros cannot expand to enum variants
//~^ ERROR unexpected token: `!`
//~^^ NOTE unexpected token after this
}
enum EnumVariantField {
Named {
field!(oopsies:()), //~ NOTE macros cannot expand to struct fields
//~^ ERROR unexpected token: `!`
//~^^ unexpected token after this
field!(oopsies2:()), //~ NOTE macros cannot expand to struct fields
//~^ ERROR unexpected token: `!`
//~^^ unexpected token after this
},
}
union Union {
A: u32,
field!(oopsies:()), //~ NOTE macros cannot expand to union fields
//~^ ERROR unexpected token: `!`
//~^^ unexpected token after this
B: u32,
field!(recovers:()), //~ NOTE macros cannot expand to union fields
//~^ ERROR unexpected token: `!`
//~^^ unexpected token after this
}

View file

@ -1,29 +1,66 @@
error: expected `:`, found `!` error: unexpected token: `!`
--> $DIR/macro-expand-to-field.rs:16:10 --> $DIR/macro-expand-to-field.rs:16:10
| |
LL | field!(bar:u128), LL | field!(bar:u128),
| ^ expected `:` | ^ unexpected token after this
| |
= note: macros cannot expand to struct fields = note: macros cannot expand to struct fields
error: expected `,`, or `}`, found `(` error: unexpected token: `!`
--> $DIR/macro-expand-to-field.rs:16:11 --> $DIR/macro-expand-to-field.rs:21:10
| |
LL | struct Struct { LL | field!(recovers:()),
| ------ while parsing this struct | ^ unexpected token after this
LL | field!(bar:u128), |
| ^ = note: macros cannot expand to struct fields
error: unexpected token: `!` error: unexpected token: `!`
--> $DIR/macro-expand-to-field.rs:23:12 --> $DIR/macro-expand-to-field.rs:27:12
| |
LL | enum EnumVariant {
| ----------- while parsing this enum
LL | variant!(whoops), LL | variant!(whoops),
| ^ unexpected token after this | ^ unexpected token after this
| |
= note: macros cannot expand to enum variants = note: macros cannot expand to enum variants
= help: enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`
error: aborting due to 3 previous errors error: unexpected token: `!`
--> $DIR/macro-expand-to-field.rs:32:12
|
LL | variant!(recovers),
| ^ unexpected token after this
|
= note: macros cannot expand to enum variants
error: unexpected token: `!`
--> $DIR/macro-expand-to-field.rs:39:14
|
LL | field!(oopsies:()),
| ^ unexpected token after this
|
= note: macros cannot expand to struct fields
error: unexpected token: `!`
--> $DIR/macro-expand-to-field.rs:42:14
|
LL | field!(oopsies2:()),
| ^ unexpected token after this
|
= note: macros cannot expand to struct fields
error: unexpected token: `!`
--> $DIR/macro-expand-to-field.rs:50:10
|
LL | field!(oopsies:()),
| ^ unexpected token after this
|
= note: macros cannot expand to union fields
error: unexpected token: `!`
--> $DIR/macro-expand-to-field.rs:54:10
|
LL | field!(recovers:()),
| ^ unexpected token after this
|
= note: macros cannot expand to union fields
error: aborting due to 8 previous errors

View file

@ -10,6 +10,8 @@ fn main() {
Some(1) => {}, Some(1) => {},
arm!(None => {}), //~ NOTE macros cannot expand to match arms arm!(None => {}), //~ NOTE macros cannot expand to match arms
//~^ ERROR unexpected `,` in pattern //~^ ERROR unexpected `,` in pattern
// doesn't recover
Some(2) => {},
_ => {}, _ => {},
}; };
} }