1
- use crate :: errors;
2
-
3
1
use super :: diagnostics:: { dummy_arg, ConsumeClosingDelim } ;
4
2
use super :: ty:: { AllowPlus , RecoverQPath , RecoverReturnSign } ;
5
3
use super :: { AttrWrapper , FollowedByType , ForceCollect , Parser , PathStyle , TrailingToken } ;
4
+ use crate :: errors:: { self , MacroExpandsToAdtField } ;
5
+ use crate :: fluent_generated as fluent;
6
6
use ast:: StaticItem ;
7
7
use rustc_ast:: ast:: * ;
8
8
use rustc_ast:: ptr:: P ;
@@ -1342,6 +1342,13 @@ impl<'a> Parser<'a> {
1342
1342
}
1343
1343
let ident = this. parse_field_ident ( "enum" , vlo) ?;
1344
1344
1345
+ if this. token == token:: Not {
1346
+ return this. unexpected ( ) . map_err ( |mut err| {
1347
+ err. note ( fluent:: parse_macro_expands_to_enum_variant) ;
1348
+ err
1349
+ } ) ;
1350
+ }
1351
+
1345
1352
let struct_def = if this. check ( & token:: OpenDelim ( Delimiter :: Brace ) ) {
1346
1353
// Parse a struct variant.
1347
1354
let ( fields, recovered) =
@@ -1369,7 +1376,7 @@ impl<'a> Parser<'a> {
1369
1376
1370
1377
Ok ( ( Some ( vr) , TrailingToken :: MaybeComma ) )
1371
1378
} ,
1372
- ) . map_err ( |mut err|{
1379
+ ) . map_err ( |mut err| {
1373
1380
err. help ( "enum variants can be `Variant`, `Variant = <integer>`, `Variant(Type, ..., TypeN)` or `Variant { fields: Types }`" ) ;
1374
1381
err
1375
1382
} )
@@ -1691,9 +1698,10 @@ impl<'a> Parser<'a> {
1691
1698
Ok ( a_var)
1692
1699
}
1693
1700
1694
- fn expect_field_ty_separator ( & mut self ) -> PResult < ' a , ( ) > {
1701
+ fn expect_field_ty_separator ( & mut self , adt_ty : & str ) -> PResult < ' a , ( ) > {
1695
1702
if let Err ( mut err) = self . expect ( & token:: Colon ) {
1696
1703
let sm = self . sess . source_map ( ) ;
1704
+ let mac_invoc = self . token . kind == token:: Not ;
1697
1705
let eq_typo = self . token . kind == token:: Eq && self . look_ahead ( 1 , |t| t. is_path_start ( ) ) ;
1698
1706
let semi_typo = self . token . kind == token:: Semi
1699
1707
&& self . look_ahead ( 1 , |t| {
@@ -1705,16 +1713,18 @@ impl<'a> Parser<'a> {
1705
1713
_ => true ,
1706
1714
}
1707
1715
} ) ;
1708
- if eq_typo || semi_typo {
1716
+ if mac_invoc {
1717
+ err. subdiagnostic ( MacroExpandsToAdtField { adt_ty } ) . emit ( ) ;
1718
+ } else if eq_typo || semi_typo {
1709
1719
self . bump ( ) ;
1710
1720
// Gracefully handle small typos.
1711
1721
err. span_suggestion_short (
1712
1722
self . prev_token . span ,
1713
1723
"field names and their types are separated with `:`" ,
1714
1724
":" ,
1715
1725
Applicability :: MachineApplicable ,
1716
- ) ;
1717
- err . emit ( ) ;
1726
+ )
1727
+ . emit ( ) ;
1718
1728
} else {
1719
1729
return Err ( err) ;
1720
1730
}
@@ -1731,7 +1741,7 @@ impl<'a> Parser<'a> {
1731
1741
attrs : AttrVec ,
1732
1742
) -> PResult < ' a , FieldDef > {
1733
1743
let name = self . parse_field_ident ( adt_ty, lo) ?;
1734
- self . expect_field_ty_separator ( ) ?;
1744
+ self . expect_field_ty_separator ( adt_ty ) ?;
1735
1745
let ty = self . parse_ty ( ) ?;
1736
1746
if self . token . kind == token:: Colon && self . look_ahead ( 1 , |tok| tok. kind != token:: Colon ) {
1737
1747
self . sess . emit_err ( errors:: SingleColonStructType { span : self . token . span } ) ;
0 commit comments