@@ -13,35 +13,19 @@ pub(super) enum StmtWithSemi {
13
13
14
14
const EXPR_FIRST : TokenSet = LHS_FIRST ;
15
15
16
- pub ( super ) fn expr ( p : & mut Parser ) -> ( Option < CompletedMarker > , BlockLike ) {
16
+ pub ( super ) fn expr ( p : & mut Parser ) -> bool {
17
17
let r = Restrictions { forbid_structs : false , prefer_stmt : false } ;
18
- expr_bp ( p, r, 1 )
18
+ expr_bp ( p, None , r, 1 ) . is_some ( )
19
19
}
20
20
21
- pub ( super ) fn expr_with_attrs ( p : & mut Parser ) -> bool {
22
- let m = p. start ( ) ;
23
- let has_attrs = p. at ( T ! [ #] ) ;
24
- attributes:: outer_attrs ( p) ;
25
-
26
- let ( cm, _block_like) = expr ( p) ;
27
- let success = cm. is_some ( ) ;
28
-
29
- match ( has_attrs, cm) {
30
- ( true , Some ( cm) ) => cm. extend_to ( p, m) ,
31
- _ => m. abandon ( p) ,
32
- }
33
-
34
- success
35
- }
36
-
37
- pub ( super ) fn expr_stmt ( p : & mut Parser ) -> ( Option < CompletedMarker > , BlockLike ) {
21
+ pub ( super ) fn expr_stmt ( p : & mut Parser , m : Option < Marker > ) -> Option < ( CompletedMarker , BlockLike ) > {
38
22
let r = Restrictions { forbid_structs : false , prefer_stmt : true } ;
39
- expr_bp ( p, r, 1 )
23
+ expr_bp ( p, m , r, 1 )
40
24
}
41
25
42
26
fn expr_no_struct ( p : & mut Parser ) {
43
27
let r = Restrictions { forbid_structs : true , prefer_stmt : false } ;
44
- expr_bp ( p, r, 1 ) ;
28
+ expr_bp ( p, None , r, 1 ) ;
45
29
}
46
30
47
31
pub ( super ) fn stmt ( p : & mut Parser , with_semi : StmtWithSemi , prefer_expr : bool ) {
@@ -53,7 +37,6 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi, prefer_expr: bool) {
53
37
// #[C] #[D] {}
54
38
// #[D] return ();
55
39
// }
56
- let has_attrs = p. at ( T ! [ #] ) ;
57
40
attributes:: outer_attrs ( p) ;
58
41
59
42
if p. at ( T ! [ let ] ) {
@@ -68,61 +51,39 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi, prefer_expr: bool) {
68
51
Err ( m) => m,
69
52
} ;
70
53
71
- let ( cm, blocklike) = expr_stmt ( p) ;
72
- let kind = cm. as_ref ( ) . map ( |cm| cm. kind ( ) ) . unwrap_or ( ERROR ) ;
73
-
74
- if has_attrs {
75
- if matches ! ( kind, BIN_EXPR | RANGE_EXPR ) {
76
- // test_err attr_on_expr_not_allowed
54
+ if let Some ( ( cm, blocklike) ) = expr_stmt ( p, Some ( m) ) {
55
+ if !( p. at ( T ! [ '}' ] ) || ( prefer_expr && p. at ( EOF ) ) ) {
56
+ // test no_semi_after_block
77
57
// fn foo() {
78
- // #[A] 1 + 2;
79
- // #[B] if true {};
58
+ // if true {}
59
+ // loop {}
60
+ // match () {}
61
+ // while true {}
62
+ // for _ in () {}
63
+ // {}
64
+ // {}
65
+ // macro_rules! test {
66
+ // () => {}
67
+ // }
68
+ // test!{}
80
69
// }
81
- p. error ( format ! ( "attributes are not allowed on {:?}" , kind) ) ;
82
- }
83
- }
84
-
85
- if p. at ( T ! [ '}' ] ) || ( prefer_expr && p. at ( EOF ) ) {
86
- // test attr_on_last_expr_in_block
87
- // fn foo() {
88
- // { #[A] bar!()? }
89
- // #[B] &()
90
- // }
91
- match cm {
92
- Some ( cm) => cm. extend_to ( p, m) ,
93
- None => m. abandon ( p) ,
94
- }
95
- } else {
96
- // test no_semi_after_block
97
- // fn foo() {
98
- // if true {}
99
- // loop {}
100
- // match () {}
101
- // while true {}
102
- // for _ in () {}
103
- // {}
104
- // {}
105
- // macro_rules! test {
106
- // () => {}
107
- // }
108
- // test!{}
109
- // }
110
-
111
- match with_semi {
112
- StmtWithSemi :: No => ( ) ,
113
- StmtWithSemi :: Optional => {
114
- p. eat ( T ! [ ; ] ) ;
115
- }
116
- StmtWithSemi :: Yes => {
117
- if blocklike. is_block ( ) {
70
+ let m = cm. precede ( p) ;
71
+ match with_semi {
72
+ StmtWithSemi :: No => ( ) ,
73
+ StmtWithSemi :: Optional => {
118
74
p. eat ( T ! [ ; ] ) ;
119
- } else {
120
- p. expect ( T ! [ ; ] ) ;
75
+ }
76
+ StmtWithSemi :: Yes => {
77
+ if blocklike. is_block ( ) {
78
+ p. eat ( T ! [ ; ] ) ;
79
+ } else {
80
+ p. expect ( T ! [ ; ] ) ;
81
+ }
121
82
}
122
83
}
123
- }
124
84
125
- m. complete ( p, EXPR_STMT ) ;
85
+ m. complete ( p, EXPR_STMT ) ;
86
+ }
126
87
}
127
88
128
89
// test let_stmt
@@ -138,7 +99,7 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi, prefer_expr: bool) {
138
99
if p. eat ( T ! [ =] ) {
139
100
// test let_stmt_init
140
101
// fn f() { let x = 92; }
141
- expressions:: expr_with_attrs ( p) ;
102
+ expressions:: expr ( p) ;
142
103
}
143
104
144
105
match with_semi {
@@ -234,20 +195,34 @@ fn current_op(p: &Parser) -> (u8, SyntaxKind) {
234
195
}
235
196
236
197
// Parses expression with binding power of at least bp.
237
- fn expr_bp ( p : & mut Parser , mut r : Restrictions , bp : u8 ) -> ( Option < CompletedMarker > , BlockLike ) {
198
+ fn expr_bp (
199
+ p : & mut Parser ,
200
+ m : Option < Marker > ,
201
+ mut r : Restrictions ,
202
+ bp : u8 ,
203
+ ) -> Option < ( CompletedMarker , BlockLike ) > {
204
+ let m = m. unwrap_or_else ( || {
205
+ let m = p. start ( ) ;
206
+ attributes:: outer_attrs ( p) ;
207
+ m
208
+ } ) ;
238
209
let mut lhs = match lhs ( p, r) {
239
210
Some ( ( lhs, blocklike) ) => {
211
+ let lhs = lhs. extend_to ( p, m) ;
240
212
if r. prefer_stmt && blocklike. is_block ( ) {
241
213
// test stmt_bin_expr_ambiguity
242
214
// fn f() {
243
215
// let _ = {1} & 2;
244
216
// {1} &2;
245
217
// }
246
- return ( Some ( lhs) , BlockLike :: Block ) ;
218
+ return Some ( ( lhs, BlockLike :: Block ) ) ;
247
219
}
248
220
lhs
249
221
}
250
- None => return ( None , BlockLike :: NotBlock ) ,
222
+ None => {
223
+ m. abandon ( p) ;
224
+ return None ;
225
+ }
251
226
} ;
252
227
253
228
loop {
@@ -285,10 +260,10 @@ fn expr_bp(p: &mut Parser, mut r: Restrictions, bp: u8) -> (Option<CompletedMark
285
260
}
286
261
}
287
262
288
- expr_bp ( p, Restrictions { prefer_stmt : false , ..r } , op_bp + 1 ) ;
263
+ expr_bp ( p, None , Restrictions { prefer_stmt : false , ..r } , op_bp + 1 ) ;
289
264
lhs = m. complete ( p, if is_range { RANGE_EXPR } else { BIN_EXPR } ) ;
290
265
}
291
- ( Some ( lhs) , BlockLike :: NotBlock )
266
+ Some ( ( lhs, BlockLike :: NotBlock ) )
292
267
}
293
268
294
269
const LHS_FIRST : TokenSet =
@@ -341,9 +316,10 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)>
341
316
m = p. start ( ) ;
342
317
p. bump ( op) ;
343
318
if p. at_ts ( EXPR_FIRST ) && !( r. forbid_structs && p. at ( T ! [ '{' ] ) ) {
344
- expr_bp ( p, r, 2 ) ;
319
+ expr_bp ( p, None , r, 2 ) ;
345
320
}
346
- return Some ( ( m. complete ( p, RANGE_EXPR ) , BlockLike :: NotBlock ) ) ;
321
+ let cm = m. complete ( p, RANGE_EXPR ) ;
322
+ return Some ( ( cm, BlockLike :: NotBlock ) ) ;
347
323
}
348
324
}
349
325
@@ -353,12 +329,15 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)>
353
329
// {p}.x = 10;
354
330
// }
355
331
let ( lhs, blocklike) = atom:: atom_expr ( p, r) ?;
356
- return Some ( postfix_expr ( p, lhs, blocklike, !( r. prefer_stmt && blocklike. is_block ( ) ) ) ) ;
332
+ let ( cm, block_like) =
333
+ postfix_expr ( p, lhs, blocklike, !( r. prefer_stmt && blocklike. is_block ( ) ) ) ;
334
+ return Some ( ( cm, block_like) ) ;
357
335
}
358
336
} ;
359
337
// parse the interior of the unary expression
360
- expr_bp ( p, r, 255 ) ;
361
- Some ( ( m. complete ( p, kind) , BlockLike :: NotBlock ) )
338
+ expr_bp ( p, None , r, 255 ) ;
339
+ let cm = m. complete ( p, kind) ;
340
+ Some ( ( cm, BlockLike :: NotBlock ) )
362
341
}
363
342
364
343
fn postfix_expr (
@@ -536,7 +515,7 @@ fn arg_list(p: &mut Parser) {
536
515
// fn main() {
537
516
// foo(#[attr] 92)
538
517
// }
539
- if !expr_with_attrs ( p) {
518
+ if !expr ( p) {
540
519
break ;
541
520
}
542
521
if !p. at ( T ! [ ')' ] ) && !p. expect ( T ! [ , ] ) {
0 commit comments