@@ -10,6 +10,7 @@ use crate::{
1010 error:: { Buffer as ErrorBuffer , Error } ,
1111 span:: Span ,
1212} ;
13+ use std:: mem;
1314
1415impl < ' src > Parser < ' _ , ' _ , ' src > {
1516 /// Parse a sequence of items.
@@ -156,11 +157,11 @@ impl<'src> Parser<'_, '_, 'src> {
156157
157158 let start = self . token . span ;
158159
159- let qualifiers: Vec < _ > =
160+ let mut qualifiers: Vec < _ > =
160161 self . parse_item_qualifiers ( ) . map ( |( qualifier, _) | qualifier) . collect ( ) ;
161162
162163 // FIXME: Provide more targeted diagnostics if the qualifiers don't make sense.
163- match qualifiers. as_slice ( ) {
164+ match qualifiers. as_mut_slice ( ) {
164165 [ ] => { }
165166 [ Qualifier :: Type ] => return self . fin_parse_ty_alias_item ( defaultness) ,
166167 // FEATURE: `const_block_items` <https://github.com/rust-lang/rust/issues/149226>
@@ -201,7 +202,7 @@ impl<'src> Parser<'_, '_, 'src> {
201202
202203 return self . fin_parse_static_item ( safety) ;
203204 }
204- & [ mut ref qualifiers @ .., Qualifier :: Fn ] => {
205+ & mut [ mut ref mut qualifiers @ .., Qualifier :: Fn ] => {
205206 let mut modifiers = ast:: FnItemModifiers { defaultness, .. } ;
206207
207208 ( modifiers. constness , qualifiers) = Qualifier :: strip_const ( qualifiers) ;
@@ -222,7 +223,7 @@ impl<'src> Parser<'_, '_, 'src> {
222223
223224 return self . fin_parse_fn_item ( modifiers, cx, attrs) ;
224225 }
225- & [ mut ref qualifiers @ .., Qualifier :: Trait ] => {
226+ & mut [ mut ref mut qualifiers @ .., Qualifier :: Trait ] => {
226227 let mut modifiers = ast:: TraitItemModifiers :: default ( ) ;
227228
228229 // FEATURE: `const_trait_impl` <https://github.com/rust-lang/rust/issues/143874>
@@ -233,6 +234,13 @@ impl<'src> Parser<'_, '_, 'src> {
233234 [ Qualifier :: Auto , qualifiers @ ..] => ( ast:: Autoness :: Auto , qualifiers) ,
234235 _ => ( ast:: Autoness :: Not , qualifiers) ,
235236 } ;
237+ ( modifiers. impl_restriction , qualifiers) = match qualifiers {
238+ [ Qualifier :: ImplRestriction ( path) , qualifiers @ ..] => {
239+ let Ok ( path) = path else { return Err ( ( ) ) } ;
240+ ( Some ( mem:: replace ( path, ast:: Path { segs : Vec :: new ( ) } ) ) , qualifiers)
241+ }
242+ _ => ( None , qualifiers) ,
243+ } ;
236244 if !qualifiers. is_empty ( ) {
237245 self . error ( Error :: InvalidItemPrefix ( start. until ( self . token . span ) ) ) ;
238246 }
@@ -327,6 +335,13 @@ impl<'src> Parser<'_, '_, 'src> {
327335 } ,
328336 TokenKind :: Impl => {
329337 self . advance ( ) ;
338+
339+ // FEATURE: `impl_restriction` <https://github.com/rust-lang/rust/issues/105077>
340+ if let Some ( path) = self . parse_restriction ( Some ( TokenKind :: Trait ) ) {
341+ yield ( Qualifier :: ImplRestriction ( Box :: new ( path) ) , self . token . kind ) ;
342+ continue ;
343+ }
344+
330345 yield ( Qualifier :: Impl , self . token . kind ) ;
331346 // Once we encounter `impl`, don't attempt to look for more item qualifiers.
332347 // That's because the grammar following an impl item's `impl` is very complex &
@@ -807,7 +822,7 @@ impl<'src> Parser<'_, '_, 'src> {
807822 /// <!-- FIXME: Add an EBNF section back in -->
808823 fn fin_parse_trait_item (
809824 & mut self ,
810- modifiers : ast:: TraitItemModifiers ,
825+ modifiers : ast:: TraitItemModifiers < ' src > ,
811826 attrs : & mut Vec < ast:: Attr < ' src > > ,
812827 ) -> Result < ast:: ItemKind < ' src > > {
813828 let binder = self . parse_common_ident ( ) ?;
@@ -836,7 +851,7 @@ impl<'src> Parser<'_, '_, 'src> {
836851 /// Finish parsing a trait alias item.
837852 fn fin_parse_trait_alias_item (
838853 & mut self ,
839- modifiers : ast:: TraitItemModifiers ,
854+ modifiers : ast:: TraitItemModifiers < ' src > ,
840855 binder : ast:: Ident < ' src > ,
841856 params : Vec < ast:: GenericParam < ' src > > ,
842857 ) -> Result < ast:: ItemKind < ' src > > {
@@ -845,7 +860,7 @@ impl<'src> Parser<'_, '_, 'src> {
845860
846861 self . parse ( TokenKind :: Semicolon ) ?;
847862
848- let ast:: TraitItemModifiers { constness, safety, autoness } = modifiers;
863+ let ast:: TraitItemModifiers { constness, safety, autoness, impl_restriction } = modifiers;
849864
850865 match safety {
851866 ast:: Safety :: Inherited => { }
@@ -857,6 +872,10 @@ impl<'src> Parser<'_, '_, 'src> {
857872 ast:: Autoness :: Not => { }
858873 }
859874
875+ if impl_restriction. is_some ( ) {
876+ self . error ( Error :: ImplRestrictedTraitAlias ) ;
877+ }
878+
860879 Ok ( ast:: ItemKind :: TraitAlias ( Box :: new ( ast:: TraitAliasItem {
861880 constness,
862881 binder,
@@ -1025,43 +1044,57 @@ impl<'src> Parser<'_, '_, 'src> {
10251044 return Ok ( ast:: Visibility :: Inherited ) ;
10261045 }
10271046
1028- enum VisKeyword {
1047+ if let Some ( path) = self . parse_restriction ( None ) {
1048+ return Ok ( ast:: Visibility :: Restricted ( path?) ) ;
1049+ }
1050+
1051+ Ok ( ast:: Visibility :: Public )
1052+ }
1053+
1054+ fn begins_visibility ( & self ) -> bool {
1055+ // To kept in sync with `Self::parse_visibility`.
1056+
1057+ self . token . kind == TokenKind :: Pub
1058+ }
1059+
1060+ fn parse_restriction (
1061+ & mut self ,
1062+ disambiguator : Option < TokenKind > ,
1063+ ) -> Option < Result < ast:: Path < ' src , ast:: NoGenericArgs > > > {
1064+ enum Herald {
10291065 In ,
10301066 CrateSuperSelf ( Span ) ,
10311067 }
10321068
1033- // FIXME: Only do this lookahead dance for tuple struct fields. This way, we can
1034- // can give better errors on invalid vis restrictions in the common cases.
10351069 if self . token . kind == TokenKind :: OpenRoundBracket
10361070 && let token = self . peek ( 1 )
1037- && let Some ( keyword ) = match token. kind {
1071+ && let Some ( herald ) = match token. kind {
10381072 TokenKind :: Crate | TokenKind :: Super | TokenKind :: SelfLower
1039- if let TokenKind :: CloseRoundBracket = self . peek ( 2 ) . kind =>
1073+ if let TokenKind :: CloseRoundBracket = self . peek ( 2 ) . kind
1074+ && disambiguator. is_none_or ( |t| self . peek ( 3 ) . kind == t) =>
10401075 {
1041- Some ( VisKeyword :: CrateSuperSelf ( token. span ) )
1076+ Some ( Herald :: CrateSuperSelf ( token. span ) )
10421077 }
1043- TokenKind :: In => Some ( VisKeyword :: In ) ,
1078+ TokenKind :: In => Some ( Herald :: In ) ,
10441079 _ => None ,
10451080 }
10461081 {
1047- self . advance ( ) ;
1048- self . advance ( ) ;
1082+ self . advance ( ) ; // parenthesis
1083+ self . advance ( ) ; // herald
10491084
1050- let path = match keyword {
1051- VisKeyword :: In => self . parse_path ( PathMode :: Normal ) ?,
1052- VisKeyword :: CrateSuperSelf ( span) => ast:: Path :: ident ( self . ident ( span) ) ,
1085+ let path = try {
1086+ let path = match herald {
1087+ Herald :: In => self . parse_path ( PathMode :: Normal ) ?,
1088+ Herald :: CrateSuperSelf ( span) => ast:: Path :: ident ( self . ident ( span) ) ,
1089+ } ;
1090+ self . parse ( TokenKind :: CloseRoundBracket ) ?;
1091+ path
10531092 } ;
1054- self . parse ( TokenKind :: CloseRoundBracket ) ?;
1055- return Ok ( ast:: Visibility :: Restricted ( path) ) ;
1056- }
10571093
1058- Ok ( ast:: Visibility :: Public )
1059- }
1060-
1061- fn begins_visibility ( & self ) -> bool {
1062- // To kept in sync with `Self::parse_visibility`.
1094+ return Some ( path) ;
1095+ }
10631096
1064- self . token . kind == TokenKind :: Pub
1097+ None
10651098 }
10661099}
10671100
@@ -1121,7 +1154,6 @@ pub(super) enum ItemCx {
11211154 Trait ,
11221155}
11231156
1124- #[ derive( Clone , Copy ) ]
11251157enum Qualifier < ' src > {
11261158 Async ,
11271159 Auto ,
@@ -1130,6 +1162,7 @@ enum Qualifier<'src> {
11301162 Fn ,
11311163 Gen ,
11321164 Impl ,
1165+ ImplRestriction ( Box < Result < ast:: Path < ' src , ast:: NoGenericArgs > > > ) ,
11331166 Mod ,
11341167 Reuse ,
11351168 Safe ,
@@ -1140,29 +1173,29 @@ enum Qualifier<'src> {
11401173}
11411174
11421175impl < ' src > Qualifier < ' src > {
1143- fn strip_const ( qualifiers : & [ Self ] ) -> ( ast:: Constness , & [ Self ] ) {
1176+ fn strip_const ( qualifiers : & mut [ Self ] ) -> ( ast:: Constness , & mut [ Self ] ) {
11441177 match qualifiers {
11451178 [ Self :: Const , qualifiers @ ..] => ( ast:: Constness :: Const , qualifiers) ,
11461179 _ => ( ast:: Constness :: Not , qualifiers) ,
11471180 }
11481181 }
11491182
1150- fn strip_unsafe ( qualifiers : & [ Self ] ) -> ( ast:: Safety , & [ Self ] ) {
1183+ fn strip_unsafe ( qualifiers : & mut [ Self ] ) -> ( ast:: Safety , & mut [ Self ] ) {
11511184 match qualifiers {
11521185 [ Self :: Unsafe , qualifiers @ ..] => ( ast:: Safety :: Unsafe , qualifiers) ,
11531186 _ => ( ast:: Safety :: Inherited , qualifiers) ,
11541187 }
11551188 }
11561189
1157- fn strip_safety ( qualifiers : & [ Self ] ) -> ( ast:: Safety < ( ) > , & [ Self ] ) {
1190+ fn strip_safety ( qualifiers : & mut [ Self ] ) -> ( ast:: Safety < ( ) > , & mut [ Self ] ) {
11581191 match qualifiers {
11591192 [ Self :: Unsafe , qualifiers @ ..] => ( ast:: Safety :: Unsafe , qualifiers) ,
11601193 [ Self :: Safe , qualifiers @ ..] => ( ast:: Safety :: Safe ( ( ) ) , qualifiers) ,
11611194 _ => ( ast:: Safety :: Inherited , qualifiers) ,
11621195 }
11631196 }
11641197
1165- fn strip_extern ( qualifiers : & [ Self ] ) -> ( ast:: Externness < ' src > , & [ Self ] ) {
1198+ fn strip_extern ( qualifiers : & mut [ Self ] ) -> ( ast:: Externness < ' src > , & mut [ Self ] ) {
11661199 match qualifiers {
11671200 [ Self :: Extern ( abi) , qualifiers @ ..] => ( ast:: Externness :: Extern ( * abi) , qualifiers) ,
11681201 _ => ( ast:: Externness :: Not , qualifiers) ,
0 commit comments