Recover from some macros
This commit is contained in:
parent
287db04636
commit
dece622ee4
9 changed files with 127 additions and 105 deletions
|
@ -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 });
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 `:`
|
|
||||||
},
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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 `:`
|
|
||||||
}
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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) => {},
|
||||||
_ => {},
|
_ => {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue