@@ -19,6 +19,14 @@ pub(super) fn use_path(p: &mut Parser<'_>) {
1919 path ( p, Mode :: Use ) ;
2020}
2121
22+ pub ( super ) fn vis_path ( p : & mut Parser < ' _ > ) {
23+ path ( p, Mode :: Vis ) ;
24+ }
25+
26+ pub ( super ) fn attr_path ( p : & mut Parser < ' _ > ) {
27+ path ( p, Mode :: Attr ) ;
28+ }
29+
2230pub ( crate ) fn type_path ( p : & mut Parser < ' _ > ) {
2331 path ( p, Mode :: Type ) ;
2432}
@@ -37,15 +45,20 @@ pub(crate) fn type_path_for_qualifier(
3745#[ derive( Clone , Copy , Eq , PartialEq ) ]
3846enum Mode {
3947 Use ,
48+ Attr ,
4049 Type ,
4150 Expr ,
51+ Vis ,
4252}
4353
44- fn path ( p : & mut Parser < ' _ > , mode : Mode ) {
54+ fn path ( p : & mut Parser < ' _ > , mode : Mode ) -> Option < CompletedMarker > {
4555 let path = p. start ( ) ;
46- path_segment ( p, mode, true ) ;
56+ if path_segment ( p, mode, true ) . is_none ( ) {
57+ path. abandon ( p) ;
58+ return None ;
59+ }
4760 let qual = path. complete ( p, PATH ) ;
48- path_for_qualifier ( p, mode, qual) ;
61+ Some ( path_for_qualifier ( p, mode, qual) )
4962}
5063
5164fn path_for_qualifier (
@@ -71,7 +84,7 @@ const EXPR_PATH_SEGMENT_RECOVERY_SET: TokenSet =
7184 items:: ITEM_RECOVERY_SET . union ( TokenSet :: new ( & [ T ! [ ')' ] , T ! [ , ] , T ! [ let ] ] ) ) ;
7285const TYPE_PATH_SEGMENT_RECOVERY_SET : TokenSet = types:: TYPE_RECOVERY_SET ;
7386
74- fn path_segment ( p : & mut Parser < ' _ > , mode : Mode , first : bool ) {
87+ fn path_segment ( p : & mut Parser < ' _ > , mode : Mode , first : bool ) -> Option < CompletedMarker > {
7588 let m = p. start ( ) ;
7689 // test qual_paths
7790 // type X = <A as B>::Output;
@@ -93,12 +106,7 @@ fn path_segment(p: &mut Parser<'_>, mode: Mode, first: bool) {
93106 p. error ( "expected `::`" ) ;
94107 }
95108 } else {
96- let empty = if first {
97- p. eat ( T ! [ :: ] ) ;
98- false
99- } else {
100- true
101- } ;
109+ let mut empty = if first { !p. eat ( T ! [ :: ] ) } else { true } ;
102110 match p. current ( ) {
103111 IDENT => {
104112 name_ref ( p) ;
@@ -114,25 +122,29 @@ fn path_segment(p: &mut Parser<'_>, mode: Mode, first: bool) {
114122 _ => {
115123 let recover_set = match mode {
116124 Mode :: Use => items:: ITEM_RECOVERY_SET ,
125+ Mode :: Attr => {
126+ items:: ITEM_RECOVERY_SET . union ( TokenSet :: new ( & [ T ! [ ']' ] , T ! [ =] , T ! [ #] ] ) )
127+ }
128+ Mode :: Vis => items:: ITEM_RECOVERY_SET . union ( TokenSet :: new ( & [ T ! [ ')' ] ] ) ) ,
117129 Mode :: Type => TYPE_PATH_SEGMENT_RECOVERY_SET ,
118130 Mode :: Expr => EXPR_PATH_SEGMENT_RECOVERY_SET ,
119131 } ;
120- p. err_recover ( "expected identifier" , recover_set) ;
132+ empty &= p. err_recover ( "expected identifier" , recover_set) ;
121133 if empty {
122134 // test_err empty_segment
123135 // use crate::;
124136 m. abandon ( p) ;
125- return ;
137+ return None ;
126138 }
127139 }
128140 } ;
129141 }
130- m. complete ( p, PATH_SEGMENT ) ;
142+ Some ( m. complete ( p, PATH_SEGMENT ) )
131143}
132144
133145fn opt_path_type_args ( p : & mut Parser < ' _ > , mode : Mode ) {
134146 match mode {
135- Mode :: Use => { }
147+ Mode :: Use | Mode :: Attr | Mode :: Vis => { }
136148 Mode :: Type => {
137149 // test typepathfn_with_coloncolon
138150 // type F = Start::(Middle) -> (Middle)::End;
0 commit comments