@@ -19,6 +19,14 @@ pub(super) fn use_path(p: &mut Parser<'_>) {
19
19
path ( p, Mode :: Use ) ;
20
20
}
21
21
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
+
22
30
pub ( crate ) fn type_path ( p : & mut Parser < ' _ > ) {
23
31
path ( p, Mode :: Type ) ;
24
32
}
@@ -37,15 +45,20 @@ pub(crate) fn type_path_for_qualifier(
37
45
#[ derive( Clone , Copy , Eq , PartialEq ) ]
38
46
enum Mode {
39
47
Use ,
48
+ Attr ,
40
49
Type ,
41
50
Expr ,
51
+ Vis ,
42
52
}
43
53
44
- fn path ( p : & mut Parser < ' _ > , mode : Mode ) {
54
+ fn path ( p : & mut Parser < ' _ > , mode : Mode ) -> Option < CompletedMarker > {
45
55
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
+ }
47
60
let qual = path. complete ( p, PATH ) ;
48
- path_for_qualifier ( p, mode, qual) ;
61
+ Some ( path_for_qualifier ( p, mode, qual) )
49
62
}
50
63
51
64
fn path_for_qualifier (
@@ -71,7 +84,7 @@ const EXPR_PATH_SEGMENT_RECOVERY_SET: TokenSet =
71
84
items:: ITEM_RECOVERY_SET . union ( TokenSet :: new ( & [ T ! [ ')' ] , T ! [ , ] , T ! [ let ] ] ) ) ;
72
85
const TYPE_PATH_SEGMENT_RECOVERY_SET : TokenSet = types:: TYPE_RECOVERY_SET ;
73
86
74
- fn path_segment ( p : & mut Parser < ' _ > , mode : Mode , first : bool ) {
87
+ fn path_segment ( p : & mut Parser < ' _ > , mode : Mode , first : bool ) -> Option < CompletedMarker > {
75
88
let m = p. start ( ) ;
76
89
// test qual_paths
77
90
// type X = <A as B>::Output;
@@ -93,12 +106,7 @@ fn path_segment(p: &mut Parser<'_>, mode: Mode, first: bool) {
93
106
p. error ( "expected `::`" ) ;
94
107
}
95
108
} 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 } ;
102
110
match p. current ( ) {
103
111
IDENT => {
104
112
name_ref ( p) ;
@@ -114,25 +122,29 @@ fn path_segment(p: &mut Parser<'_>, mode: Mode, first: bool) {
114
122
_ => {
115
123
let recover_set = match mode {
116
124
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 ! [ ')' ] ] ) ) ,
117
129
Mode :: Type => TYPE_PATH_SEGMENT_RECOVERY_SET ,
118
130
Mode :: Expr => EXPR_PATH_SEGMENT_RECOVERY_SET ,
119
131
} ;
120
- p. err_recover ( "expected identifier" , recover_set) ;
132
+ empty &= p. err_recover ( "expected identifier" , recover_set) ;
121
133
if empty {
122
134
// test_err empty_segment
123
135
// use crate::;
124
136
m. abandon ( p) ;
125
- return ;
137
+ return None ;
126
138
}
127
139
}
128
140
} ;
129
141
}
130
- m. complete ( p, PATH_SEGMENT ) ;
142
+ Some ( m. complete ( p, PATH_SEGMENT ) )
131
143
}
132
144
133
145
fn opt_path_type_args ( p : & mut Parser < ' _ > , mode : Mode ) {
134
146
match mode {
135
- Mode :: Use => { }
147
+ Mode :: Use | Mode :: Attr | Mode :: Vis => { }
136
148
Mode :: Type => {
137
149
// test typepathfn_with_coloncolon
138
150
// type F = Start::(Middle) -> (Middle)::End;
0 commit comments