@@ -16,7 +16,6 @@ use ast::{Mod, Arg, Arm, Attribute, BindingMode, TraitItemKind};
1616use ast:: Block ;
1717use ast:: { BlockCheckMode , CaptureBy } ;
1818use ast:: { Constness , Crate } ;
19- use ast:: Generics ;
2019use ast:: Defaultness ;
2120use ast:: EnumDef ;
2221use ast:: { Expr , ExprKind , RangeLimits } ;
@@ -3874,6 +3873,16 @@ impl<'a> Parser<'a> {
38743873 self . look_ahead ( 1 , |t| t. is_ident ( ) && !t. is_reserved_ident ( ) )
38753874 }
38763875
3876+ fn eat_auto_trait ( & mut self ) -> bool {
3877+ if self . token . is_keyword ( keywords:: Auto )
3878+ && self . look_ahead ( 1 , |t| t. is_keyword ( keywords:: Trait ) )
3879+ {
3880+ self . eat_keyword ( keywords:: Auto ) && self . eat_keyword ( keywords:: Trait )
3881+ } else {
3882+ false
3883+ }
3884+ }
3885+
38773886 fn is_defaultness ( & self ) -> bool {
38783887 // `pub` is included for better error messages
38793888 self . token . is_keyword ( keywords:: Default ) &&
@@ -5052,7 +5061,7 @@ impl<'a> Parser<'a> {
50525061 }
50535062
50545063 /// Parse trait Foo { ... }
5055- fn parse_item_trait ( & mut self , unsafety : Unsafety ) -> PResult < ' a , ItemInfo > {
5064+ fn parse_item_trait ( & mut self , is_auto : IsAuto , unsafety : Unsafety ) -> PResult < ' a , ItemInfo > {
50565065 let ident = self . parse_ident ( ) ?;
50575066 let mut tps = self . parse_generics ( ) ?;
50585067
@@ -5079,17 +5088,7 @@ impl<'a> Parser<'a> {
50795088 }
50805089 }
50815090 }
5082- Ok ( ( ident, ItemKind :: Trait ( IsAuto :: No , unsafety, tps, bounds, trait_items) , None ) )
5083- }
5084-
5085- fn parse_item_auto_trait ( & mut self , unsafety : Unsafety ) -> PResult < ' a , ItemInfo > {
5086- let ident = self . parse_ident ( ) ?;
5087- self . expect ( & token:: OpenDelim ( token:: Brace ) ) ?;
5088- self . expect ( & token:: CloseDelim ( token:: Brace ) ) ?;
5089- // Auto traits cannot have generics, super traits nor contain items.
5090- Ok ( ( ident,
5091- ItemKind :: Trait ( IsAuto :: Yes , unsafety, Generics :: default ( ) , Vec :: new ( ) , Vec :: new ( ) ) ,
5092- None ) )
5091+ Ok ( ( ident, ItemKind :: Trait ( is_auto, unsafety, tps, bounds, trait_items) , None ) )
50935092 }
50945093
50955094 /// Parses items implementations variants
@@ -5999,44 +5998,19 @@ impl<'a> Parser<'a> {
59995998 return Ok ( Some ( item) ) ;
60005999 }
60016000 if self . check_keyword ( keywords:: Unsafe ) &&
6002- self . look_ahead ( 1 , |t| t. is_keyword ( keywords:: Trait ) )
6001+ ( self . look_ahead ( 1 , |t| t. is_keyword ( keywords:: Trait ) ) ||
6002+ self . look_ahead ( 1 , |t| t. is_keyword ( keywords:: Auto ) ) )
60036003 {
60046004 // UNSAFE TRAIT ITEM
60056005 self . expect_keyword ( keywords:: Unsafe ) ?;
6006- self . expect_keyword ( keywords:: Trait ) ?;
6006+ let is_auto = if self . eat_keyword ( keywords:: Trait ) {
6007+ IsAuto :: No
6008+ } else {
6009+ self . eat_auto_trait ( ) ;
6010+ IsAuto :: Yes
6011+ } ;
60076012 let ( ident, item_, extra_attrs) =
6008- self . parse_item_trait ( ast:: Unsafety :: Unsafe ) ?;
6009- let prev_span = self . prev_span ;
6010- let item = self . mk_item ( lo. to ( prev_span) ,
6011- ident,
6012- item_,
6013- visibility,
6014- maybe_append ( attrs, extra_attrs) ) ;
6015- return Ok ( Some ( item) ) ;
6016- }
6017- if self . eat_keyword ( keywords:: Auto ) {
6018- self . expect_keyword ( keywords:: Trait ) ?;
6019- // AUTO TRAIT ITEM
6020- let ( ident,
6021- item_,
6022- extra_attrs) = self . parse_item_auto_trait ( ast:: Unsafety :: Normal ) ?;
6023- let prev_span = self . prev_span ;
6024- let item = self . mk_item ( lo. to ( prev_span) ,
6025- ident,
6026- item_,
6027- visibility,
6028- maybe_append ( attrs, extra_attrs) ) ;
6029- return Ok ( Some ( item) ) ;
6030- }
6031- if self . check_keyword ( keywords:: Unsafe ) &&
6032- self . look_ahead ( 1 , |t| t. is_keyword ( keywords:: Auto ) ) {
6033- self . expect_keyword ( keywords:: Unsafe ) ?;
6034- self . expect_keyword ( keywords:: Auto ) ?;
6035- self . expect_keyword ( keywords:: Trait ) ?;
6036- // UNSAFE AUTO TRAIT ITEM
6037- let ( ident,
6038- item_,
6039- extra_attrs) = self . parse_item_auto_trait ( ast:: Unsafety :: Unsafe ) ?;
6013+ self . parse_item_trait ( is_auto, ast:: Unsafety :: Unsafe ) ?;
60406014 let prev_span = self . prev_span ;
60416015 let item = self . mk_item ( lo. to ( prev_span) ,
60426016 ident,
@@ -6139,10 +6113,19 @@ impl<'a> Parser<'a> {
61396113 maybe_append ( attrs, extra_attrs) ) ;
61406114 return Ok ( Some ( item) ) ;
61416115 }
6142- if self . eat_keyword ( keywords:: Trait ) {
6116+ if self . check_keyword ( keywords:: Trait )
6117+ || ( self . check_keyword ( keywords:: Auto )
6118+ && self . look_ahead ( 1 , |t| t. is_keyword ( keywords:: Trait ) ) )
6119+ {
6120+ let is_auto = if self . eat_keyword ( keywords:: Trait ) {
6121+ IsAuto :: No
6122+ } else {
6123+ self . eat_auto_trait ( ) ;
6124+ IsAuto :: Yes
6125+ } ;
61436126 // TRAIT ITEM
61446127 let ( ident, item_, extra_attrs) =
6145- self . parse_item_trait ( ast:: Unsafety :: Normal ) ?;
6128+ self . parse_item_trait ( is_auto , ast:: Unsafety :: Normal ) ?;
61466129 let prev_span = self . prev_span ;
61476130 let item = self . mk_item ( lo. to ( prev_span) ,
61486131 ident,
0 commit comments