@@ -1052,80 +1052,35 @@ impl<'a> Parser<'a> {
10521052 }
10531053 }
10541054
1055- /// Is there an `[ impl(in? path) ]? trait` item `dist` tokens ahead?
1056- fn is_trait_with_maybe_impl_restriction_in_front ( & self , dist : usize ) -> bool {
1057- // `trait`
1058- if self . is_keyword_ahead ( dist, & [ kw:: Trait ] ) {
1059- return true ;
1060- }
1061- // `impl(`
1062- if !self . is_keyword_ahead ( dist, & [ kw:: Impl ] )
1063- || !self . look_ahead ( dist + 1 , |t| t == & token:: OpenParen )
1064- {
1065- return false ;
1066- }
1067- // `crate | super | self) trait`
1068- if self . is_keyword_ahead ( dist + 2 , & [ kw:: Crate , kw:: Super , kw:: SelfLower ] )
1069- && self . look_ahead ( dist + 3 , |t| t == & token:: CloseParen )
1070- && self . is_keyword_ahead ( dist + 4 , & [ kw:: Trait ] )
1071- {
1072- return true ;
1073- }
1074- // `impl(in? something) trait`
1075- // We catch cases where the `in` keyword is missing to provide a
1076- // better error message. This is handled later in
1077- // `self.recover_incorrect_impl_restriction`.
1078- self . tree_look_ahead ( dist + 2 , |t| {
1079- if let TokenTree :: Token ( token, _) = t { token. is_keyword ( kw:: Trait ) } else { false }
1080- } )
1081- . unwrap_or ( false )
1082- }
1083-
1084- /// Is this an `(const unsafe? auto? [ impl(in? path) ]? | unsafe auto? [ impl(in? path) ]? | auto [ impl(in? path) ]? | [ impl(in? path) ]?) trait` item?
1055+ /// Is this an `[impl(in? path)]? const? unsafe? auto? trait` item?
10851056 fn check_trait_front_matter ( & mut self ) -> bool {
1086- // `[ impl(in? path) ]? trait`
1087- if self . is_trait_with_maybe_impl_restriction_in_front ( 0 ) {
1088- return true ;
1089- }
1090- // `auto [ impl(in? path) ]? trait`
1091- if self . check_keyword ( exp ! ( Auto ) ) && self . is_trait_with_maybe_impl_restriction_in_front ( 1 ) {
1092- return true ;
1093- }
1094- // `unsafe auto? [ impl(in? path) ]? trait`
1095- if self . check_keyword ( exp ! ( Unsafe ) )
1096- && ( self . is_trait_with_maybe_impl_restriction_in_front ( 1 )
1097- || self . is_keyword_ahead ( 1 , & [ kw:: Auto ] )
1098- && self . is_trait_with_maybe_impl_restriction_in_front ( 2 ) )
1099- {
1100- return true ;
1101- }
1102- // `const` ...
1103- if !self . check_keyword ( exp ! ( Const ) ) {
1104- return false ;
1105- }
1106- // `const [ impl(in? path) ]? trait`
1107- if self . is_trait_with_maybe_impl_restriction_in_front ( 1 ) {
1108- return true ;
1109- }
1110- // `const (unsafe | auto) [ impl(in? path) ]? trait`
1111- if self . is_keyword_ahead ( 1 , & [ kw:: Unsafe , kw:: Auto ] )
1112- && self . is_trait_with_maybe_impl_restriction_in_front ( 2 )
1113- {
1114- return true ;
1057+ // `impl(`
1058+ if self . check_keyword ( exp ! ( Impl ) ) && self . look_ahead ( 1 , |t| t == & token:: OpenParen ) {
1059+ // `impl(..) trait`
1060+ self . is_keyword_tree_ahead ( 2 , & [ kw:: Trait ] ) ||
1061+ // `impl(..) [const | unsafe | auto] trait`
1062+ ( self . is_keyword_tree_ahead ( 2 , & [ kw:: Const , kw:: Unsafe , kw:: Auto ] ) && self . is_keyword_tree_ahead ( 3 , & [ kw:: Trait ] ) ) ||
1063+ // `impl(..) const [unsafe | auto] trait`
1064+ ( self . is_keyword_tree_ahead ( 2 , & [ kw:: Const ] ) && self . is_keyword_tree_ahead ( 3 , & [ kw:: Unsafe , kw:: Auto ] ) && self . is_keyword_tree_ahead ( 4 , & [ kw:: Trait ] ) ) ||
1065+ // `impl(..) unsafe auto trait`
1066+ ( self . is_keyword_tree_ahead ( 2 , & [ kw:: Unsafe ] ) && self . is_keyword_tree_ahead ( 3 , & [ kw:: Auto ] ) && self . is_keyword_tree_ahead ( 4 , & [ kw:: Trait ] ) ) ||
1067+ // `impl(..) const unsafe auto trait`
1068+ ( self . is_keyword_tree_ahead ( 2 , & [ kw:: Const ] ) && self . is_keyword_tree_ahead ( 3 , & [ kw:: Unsafe ] ) && self . is_keyword_tree_ahead ( 4 , & [ kw:: Auto ] ) && self . is_keyword_tree_ahead ( 5 , & [ kw:: Trait ] ) )
1069+ } else {
1070+ // `trait`
1071+ self . check_keyword ( exp ! ( Trait ) ) ||
1072+ // `auto trait`
1073+ self . check_keyword ( exp ! ( Auto ) ) && self . is_keyword_ahead ( 1 , & [ kw:: Trait ] ) ||
1074+ // `unsafe auto? trait`
1075+ self . check_keyword ( exp ! ( Unsafe ) ) && ( self . is_keyword_ahead ( 1 , & [ kw:: Trait ] ) || self . is_keyword_ahead ( 1 , & [ kw:: Auto ] ) && self . is_keyword_ahead ( 2 , & [ kw:: Trait ] ) ) ||
1076+ // `const unsafe? auto? trait`
1077+ self . check_keyword ( exp ! ( Const ) ) && ( self . is_keyword_ahead ( 1 , & [ kw:: Trait ] ) || self . is_keyword_ahead ( 1 , & [ kw:: Unsafe , kw:: Auto ] ) && self . is_keyword_ahead ( 2 , & [ kw:: Trait ] ) || self . is_keyword_ahead ( 1 , & [ kw:: Unsafe ] ) && self . is_keyword_ahead ( 2 , & [ kw:: Auto ] ) && self . is_keyword_ahead ( 3 , & [ kw:: Trait ] ) )
11151078 }
1116- // `const unsafe auto [ impl(in? path) ]? trait`
1117- self . is_keyword_ahead ( 1 , & [ kw:: Unsafe ] )
1118- && self . is_keyword_ahead ( 2 , & [ kw:: Auto ] )
1119- && self . is_trait_with_maybe_impl_restriction_in_front ( 3 )
11201079 }
11211080
1122- /// Parses `const? unsafe? auto? [impl(in? path)]? trait Foo { ... }` or `trait Foo = Bar;`.
1123- ///
1124- /// FIXME(restrictions): The current keyword order follows the grammar specified in RFC 3323.
1125- /// However, whether the restriction should be grouped closer to the visibility modifier
1126- /// (e.g., `pub impl(crate) const unsafe auto trait`) remains an unresolved design question.
1127- /// This ordering must be kept in sync with the logic in `check_trait_front_matter`.
1081+ /// Parses `[impl(in? path)]? const? unsafe? auto? trait Foo { ... }` or `trait Foo = Bar;`.
11281082 fn parse_item_trait ( & mut self , attrs : & mut AttrVec , lo : Span ) -> PResult < ' a , ItemKind > {
1083+ let impl_restriction = self . parse_impl_restriction ( ) ?;
11291084 let constness = self . parse_constness ( Case :: Sensitive ) ;
11301085 if let Const :: Yes ( span) = constness {
11311086 self . psess . gated_spans . gate ( sym:: const_trait_impl, span) ;
@@ -1139,8 +1094,6 @@ impl<'a> Parser<'a> {
11391094 IsAuto :: No
11401095 } ;
11411096
1142- let impl_restriction = self . parse_impl_restriction ( ) ?;
1143-
11441097 self . expect_keyword ( exp ! ( Trait ) ) ?;
11451098 let ident = self . parse_ident ( ) ?;
11461099 let mut generics = self . parse_generics ( ) ?;
@@ -2966,8 +2919,8 @@ impl<'a> Parser<'a> {
29662919 && !self . is_unsafe_foreign_mod ( )
29672920 // Rule out `async gen {` and `async gen move {`
29682921 && !self . is_async_gen_block ( )
2969- // Rule out `const unsafe auto` and `const unsafe trait` and `const unsafe impl`.
2970- && !self . is_keyword_ahead ( 2 , & [ kw:: Auto , kw:: Trait , kw :: Impl ] )
2922+ // Rule out `const unsafe auto` and `const unsafe trait`
2923+ && !self . is_keyword_ahead ( 2 , & [ kw:: Auto , kw:: Trait ] )
29712924 )
29722925 } )
29732926 // `extern ABI fn`
0 commit comments