@@ -13,35 +13,19 @@ pub(super) enum StmtWithSemi {
1313
1414const EXPR_FIRST : TokenSet = LHS_FIRST ;
1515
16- pub ( super ) fn expr ( p : & mut Parser ) -> ( Option < CompletedMarker > , BlockLike ) {
16+ pub ( super ) fn expr ( p : & mut Parser ) -> bool {
1717 let r = Restrictions { forbid_structs : false , prefer_stmt : false } ;
18- expr_bp ( p, r, 1 )
18+ expr_bp ( p, None , r, 1 ) . is_some ( )
1919}
2020
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 ) > {
3822 let r = Restrictions { forbid_structs : false , prefer_stmt : true } ;
39- expr_bp ( p, r, 1 )
23+ expr_bp ( p, m , r, 1 )
4024}
4125
4226fn expr_no_struct ( p : & mut Parser ) {
4327 let r = Restrictions { forbid_structs : true , prefer_stmt : false } ;
44- expr_bp ( p, r, 1 ) ;
28+ expr_bp ( p, None , r, 1 ) ;
4529}
4630
4731pub ( 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) {
5337 // #[C] #[D] {}
5438 // #[D] return ();
5539 // }
56- let has_attrs = p. at ( T ! [ #] ) ;
5740 attributes:: outer_attrs ( p) ;
5841
5942 if p. at ( T ! [ let ] ) {
@@ -68,61 +51,39 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi, prefer_expr: bool) {
6851 Err ( m) => m,
6952 } ;
7053
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
7757 // 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!{}
8069 // }
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 => {
11874 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+ }
12182 }
12283 }
123- }
12484
125- m. complete ( p, EXPR_STMT ) ;
85+ m. complete ( p, EXPR_STMT ) ;
86+ }
12687 }
12788
12889 // test let_stmt
@@ -138,7 +99,7 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi, prefer_expr: bool) {
13899 if p. eat ( T ! [ =] ) {
139100 // test let_stmt_init
140101 // fn f() { let x = 92; }
141- expressions:: expr_with_attrs ( p) ;
102+ expressions:: expr ( p) ;
142103 }
143104
144105 match with_semi {
@@ -234,20 +195,34 @@ fn current_op(p: &Parser) -> (u8, SyntaxKind) {
234195}
235196
236197// 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+ } ) ;
238209 let mut lhs = match lhs ( p, r) {
239210 Some ( ( lhs, blocklike) ) => {
211+ let lhs = lhs. extend_to ( p, m) ;
240212 if r. prefer_stmt && blocklike. is_block ( ) {
241213 // test stmt_bin_expr_ambiguity
242214 // fn f() {
243215 // let _ = {1} & 2;
244216 // {1} &2;
245217 // }
246- return ( Some ( lhs) , BlockLike :: Block ) ;
218+ return Some ( ( lhs, BlockLike :: Block ) ) ;
247219 }
248220 lhs
249221 }
250- None => return ( None , BlockLike :: NotBlock ) ,
222+ None => {
223+ m. abandon ( p) ;
224+ return None ;
225+ }
251226 } ;
252227
253228 loop {
@@ -285,10 +260,10 @@ fn expr_bp(p: &mut Parser, mut r: Restrictions, bp: u8) -> (Option<CompletedMark
285260 }
286261 }
287262
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 ) ;
289264 lhs = m. complete ( p, if is_range { RANGE_EXPR } else { BIN_EXPR } ) ;
290265 }
291- ( Some ( lhs) , BlockLike :: NotBlock )
266+ Some ( ( lhs, BlockLike :: NotBlock ) )
292267}
293268
294269const LHS_FIRST : TokenSet =
@@ -341,9 +316,10 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)>
341316 m = p. start ( ) ;
342317 p. bump ( op) ;
343318 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 ) ;
345320 }
346- return Some ( ( m. complete ( p, RANGE_EXPR ) , BlockLike :: NotBlock ) ) ;
321+ let cm = m. complete ( p, RANGE_EXPR ) ;
322+ return Some ( ( cm, BlockLike :: NotBlock ) ) ;
347323 }
348324 }
349325
@@ -353,12 +329,15 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)>
353329 // {p}.x = 10;
354330 // }
355331 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) ) ;
357335 }
358336 } ;
359337 // 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 ) )
362341}
363342
364343fn postfix_expr (
@@ -536,7 +515,7 @@ fn arg_list(p: &mut Parser) {
536515 // fn main() {
537516 // foo(#[attr] 92)
538517 // }
539- if !expr_with_attrs ( p) {
518+ if !expr ( p) {
540519 break ;
541520 }
542521 if !p. at ( T ! [ ')' ] ) && !p. expect ( T ! [ , ] ) {
0 commit comments