@@ -457,7 +457,8 @@ impl<'a> Parser<'a> {
457
457
458
458
generics. where_clause = self . parse_where_clause ( ) ?;
459
459
460
- let impl_items = self . parse_item_list ( attrs, |p, at_end| p. parse_impl_item ( at_end) ) ?;
460
+ let impl_items =
461
+ self . parse_item_list ( attrs, |p, at_end| p. parse_impl_item ( at_end) . map ( Some ) . map ( Some ) ) ?;
461
462
462
463
let item_kind = match ty_second {
463
464
Some ( ty_second) => {
@@ -516,8 +517,9 @@ impl<'a> Parser<'a> {
516
517
fn parse_item_list < T > (
517
518
& mut self ,
518
519
attrs : & mut Vec < Attribute > ,
519
- mut parse_item : impl FnMut ( & mut Parser < ' a > , & mut bool ) -> PResult < ' a , T > ,
520
+ mut parse_item : impl FnMut ( & mut Parser < ' a > , & mut bool ) -> PResult < ' a , Option < Option < T > > > ,
520
521
) -> PResult < ' a , Vec < T > > {
522
+ let open_brace_span = self . token . span ;
521
523
self . expect ( & token:: OpenDelim ( token:: Brace ) ) ?;
522
524
attrs. append ( & mut self . parse_inner_attributes ( ) ?) ;
523
525
@@ -528,7 +530,18 @@ impl<'a> Parser<'a> {
528
530
}
529
531
let mut at_end = false ;
530
532
match parse_item ( self , & mut at_end) {
531
- Ok ( item) => items. push ( item) ,
533
+ Ok ( None ) => {
534
+ // We have to bail or we'll potentially never make progress.
535
+ let non_item_span = self . token . span ;
536
+ self . consume_block ( token:: Brace , ConsumeClosingDelim :: Yes ) ;
537
+ self . struct_span_err ( non_item_span, "non-item in item list" )
538
+ . span_label ( open_brace_span, "item list starts here" )
539
+ . span_label ( non_item_span, "non-item starts here" )
540
+ . span_label ( self . prev_span , "item list ends here" )
541
+ . emit ( ) ;
542
+ break ;
543
+ }
544
+ Ok ( Some ( item) ) => items. extend ( item) ,
532
545
Err ( mut err) => {
533
546
err. emit ( ) ;
534
547
if !at_end {
@@ -631,7 +644,9 @@ impl<'a> Parser<'a> {
631
644
} else {
632
645
// It's a normal trait.
633
646
tps. where_clause = self . parse_where_clause ( ) ?;
634
- let items = self . parse_item_list ( attrs, |p, at_end| p. parse_trait_item ( at_end) ) ?;
647
+ let items = self . parse_item_list ( attrs, |p, at_end| {
648
+ p. parse_trait_item ( at_end) . map ( Some ) . map ( Some )
649
+ } ) ?;
635
650
Ok ( ( ident, ItemKind :: Trait ( is_auto, unsafety, tps, bounds, items) ) )
636
651
}
637
652
}
@@ -892,38 +907,48 @@ impl<'a> Parser<'a> {
892
907
/// ```
893
908
fn parse_item_foreign_mod ( & mut self , attrs : & mut Vec < Attribute > ) -> PResult < ' a , ItemInfo > {
894
909
let abi = self . parse_abi ( ) ; // ABI?
895
- let items = self . parse_item_list ( attrs, |p, at_end | p. parse_foreign_item ( at_end ) ) ?;
910
+ let items = self . parse_item_list ( attrs, |p, _ | p. parse_foreign_item ( ) ) ?;
896
911
let module = ast:: ForeignMod { abi, items } ;
897
912
Ok ( ( Ident :: invalid ( ) , ItemKind :: ForeignMod ( module) ) )
898
913
}
899
914
900
915
/// Parses a foreign item (one in an `extern { ... }` block).
901
- pub fn parse_foreign_item ( & mut self , at_end : & mut bool ) -> PResult < ' a , P < ForeignItem > > {
902
- maybe_whole ! ( self , NtForeignItem , |ni| ni ) ;
916
+ pub fn parse_foreign_item ( & mut self ) -> PResult < ' a , Option < Option < P < ForeignItem > > > > {
917
+ maybe_whole ! ( self , NtForeignItem , |item| Some ( Some ( item ) ) ) ;
903
918
904
- let mut attrs = self . parse_outer_attributes ( ) ?;
905
- let lo = self . token . span ;
906
- let vis = self . parse_visibility ( FollowedByType :: No ) ?;
907
- let ( ident, kind) = self . parse_assoc_item_kind ( at_end, & mut attrs, |_| true , & vis) ?;
908
- let item = self . mk_item ( lo, ident, kind, vis, Defaultness :: Final , attrs) ;
909
- self . error_on_foreign_const ( & item) ;
910
- Ok ( P ( item) )
919
+ let attrs = self . parse_outer_attributes ( ) ?;
920
+ let it = self . parse_item_common ( attrs, true , false ) ?;
921
+ Ok ( it. map ( |Item { attrs, id, span, vis, ident, defaultness, kind, tokens } | {
922
+ self . error_on_illegal_default ( defaultness) ;
923
+ let kind = match kind {
924
+ ItemKind :: Mac ( a) => AssocItemKind :: Macro ( a) ,
925
+ ItemKind :: Fn ( a, b, c) => AssocItemKind :: Fn ( a, b, c) ,
926
+ ItemKind :: TyAlias ( a, b, c) => AssocItemKind :: TyAlias ( a, b, c) ,
927
+ ItemKind :: Static ( a, b, c) => AssocItemKind :: Static ( a, b, c) ,
928
+ ItemKind :: Const ( a, b) => {
929
+ self . error_on_foreign_const ( span, ident) ;
930
+ AssocItemKind :: Static ( a, Mutability :: Not , b)
931
+ }
932
+ _ => {
933
+ let span = self . sess . source_map ( ) . def_span ( span) ;
934
+ self . struct_span_err ( span, "item kind not supported in `extern` block" ) . emit ( ) ;
935
+ return None ;
936
+ }
937
+ } ;
938
+ Some ( P ( Item { attrs, id, span, vis, ident, defaultness, kind, tokens } ) )
939
+ } ) )
911
940
}
912
941
913
- fn error_on_foreign_const ( & self , item : & ForeignItem ) {
914
- if let AssocItemKind :: Const ( ..) = item. kind {
915
- self . struct_span_err ( item. ident . span , "extern items cannot be `const`" )
916
- . span_suggestion (
917
- item. span . with_hi ( item. ident . span . lo ( ) ) ,
918
- "try using a static value" ,
919
- "static " . to_string ( ) ,
920
- Applicability :: MachineApplicable ,
921
- )
922
- . note (
923
- "for more information, visit https://doc.rust-lang.org/std/keyword.extern.html" ,
924
- )
925
- . emit ( ) ;
926
- }
942
+ fn error_on_foreign_const ( & self , span : Span , ident : Ident ) {
943
+ self . struct_span_err ( ident. span , "extern items cannot be `const`" )
944
+ . span_suggestion (
945
+ span. with_hi ( ident. span . lo ( ) ) ,
946
+ "try using a static value" ,
947
+ "static " . to_string ( ) ,
948
+ Applicability :: MachineApplicable ,
949
+ )
950
+ . note ( "for more information, visit https://doc.rust-lang.org/std/keyword.extern.html" )
951
+ . emit ( ) ;
927
952
}
928
953
929
954
fn is_static_global ( & mut self ) -> bool {
0 commit comments