diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_syntax/src/grammar/expressions.rs | 26 | ||||
-rw-r--r-- | crates/ra_syntax/tests/test.rs | 3 |
2 files changed, 12 insertions, 17 deletions
diff --git a/crates/ra_syntax/src/grammar/expressions.rs b/crates/ra_syntax/src/grammar/expressions.rs index 043f41b98..9d75bfb90 100644 --- a/crates/ra_syntax/src/grammar/expressions.rs +++ b/crates/ra_syntax/src/grammar/expressions.rs | |||
@@ -158,13 +158,14 @@ fn current_op(p: &Parser) -> (u8, Op) { | |||
158 | // Parses expression with binding power of at least bp. | 158 | // Parses expression with binding power of at least bp. |
159 | fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> BlockLike { | 159 | fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> BlockLike { |
160 | let mut lhs = match lhs(p, r) { | 160 | let mut lhs = match lhs(p, r) { |
161 | (Some(lhs), blocklike) => { | 161 | (Some(lhs), macro_blocklike) => { |
162 | // test stmt_bin_expr_ambiguity | 162 | // test stmt_bin_expr_ambiguity |
163 | // fn foo() { | 163 | // fn foo() { |
164 | // let _ = {1} & 2; | 164 | // let _ = {1} & 2; |
165 | // {1} &2; | 165 | // {1} &2; |
166 | // } | 166 | // } |
167 | if r.prefer_stmt && (is_block(lhs.kind()) || blocklike == Some(BlockLike::Block)) { | 167 | if r.prefer_stmt && (is_block(lhs.kind()) || macro_blocklike == Some(BlockLike::Block)) |
168 | { | ||
168 | return BlockLike::Block; | 169 | return BlockLike::Block; |
169 | } | 170 | } |
170 | lhs | 171 | lhs |
@@ -251,11 +252,11 @@ fn lhs(p: &mut Parser, r: Restrictions) -> (Option<CompletedMarker>, Option<Bloc | |||
251 | _ => { | 252 | _ => { |
252 | let (lhs_marker, macro_block_like) = atom::atom_expr(p, r); | 253 | let (lhs_marker, macro_block_like) = atom::atom_expr(p, r); |
253 | 254 | ||
255 | if macro_block_like == Some(BlockLike::Block) { | ||
256 | return (lhs_marker, macro_block_like); | ||
257 | } | ||
254 | if let Some(lhs_marker) = lhs_marker { | 258 | if let Some(lhs_marker) = lhs_marker { |
255 | return ( | 259 | return (Some(postfix_expr(p, r, lhs_marker)), macro_block_like); |
256 | Some(postfix_expr(p, r, lhs_marker, macro_block_like)), | ||
257 | macro_block_like, | ||
258 | ); | ||
259 | } else { | 260 | } else { |
260 | return (None, None); | 261 | return (None, None); |
261 | } | 262 | } |
@@ -265,14 +266,11 @@ fn lhs(p: &mut Parser, r: Restrictions) -> (Option<CompletedMarker>, Option<Bloc | |||
265 | (Some(m.complete(p, kind)), None) | 266 | (Some(m.complete(p, kind)), None) |
266 | } | 267 | } |
267 | 268 | ||
268 | fn postfix_expr( | 269 | fn postfix_expr(p: &mut Parser, r: Restrictions, mut lhs: CompletedMarker) -> CompletedMarker { |
269 | p: &mut Parser, | 270 | // Calls are disallowed if the type is a block and we prefer statements because the call cannot be disambiguated from a tuple |
270 | r: Restrictions, | 271 | // E.g. `while true {break}();` is parsed as |
271 | mut lhs: CompletedMarker, | 272 | // `while true {break}; ();` |
272 | macro_block_like: Option<BlockLike>, | 273 | let mut allow_calls = !r.prefer_stmt || !is_block(lhs.kind()); |
273 | ) -> CompletedMarker { | ||
274 | let mut allow_calls = | ||
275 | !r.prefer_stmt || !is_block(lhs.kind()) || macro_block_like != Some(BlockLike::Block); | ||
276 | loop { | 274 | loop { |
277 | lhs = match p.current() { | 275 | lhs = match p.current() { |
278 | // test stmt_postfix_expr_ambiguity | 276 | // test stmt_postfix_expr_ambiguity |
diff --git a/crates/ra_syntax/tests/test.rs b/crates/ra_syntax/tests/test.rs index 7f385f86f..a07855768 100644 --- a/crates/ra_syntax/tests/test.rs +++ b/crates/ra_syntax/tests/test.rs | |||
@@ -43,7 +43,6 @@ fn parser_fuzz_tests() { | |||
43 | fn self_hosting_parsing() { | 43 | fn self_hosting_parsing() { |
44 | let empty_vec = vec![]; | 44 | let empty_vec = vec![]; |
45 | let dir = project_dir(); | 45 | let dir = project_dir(); |
46 | let mut count = 0u32; | ||
47 | for entry in walkdir::WalkDir::new(dir) | 46 | for entry in walkdir::WalkDir::new(dir) |
48 | .into_iter() | 47 | .into_iter() |
49 | .filter_entry(|entry| { | 48 | .filter_entry(|entry| { |
@@ -64,7 +63,6 @@ fn self_hosting_parsing() { | |||
64 | !entry.path().is_dir() && (entry.path().extension() == Some(std::ffi::OsStr::new("rs"))) | 63 | !entry.path().is_dir() && (entry.path().extension() == Some(std::ffi::OsStr::new("rs"))) |
65 | }) | 64 | }) |
66 | { | 65 | { |
67 | count += 1; | ||
68 | let text = read_text(entry.path()); | 66 | let text = read_text(entry.path()); |
69 | let node = SourceFileNode::parse(&text); | 67 | let node = SourceFileNode::parse(&text); |
70 | let errors = node.errors(); | 68 | let errors = node.errors(); |
@@ -74,7 +72,6 @@ fn self_hosting_parsing() { | |||
74 | entry | 72 | entry |
75 | ); | 73 | ); |
76 | } | 74 | } |
77 | panic!("{}", count) | ||
78 | } | 75 | } |
79 | /// Read file and normalize newlines. | 76 | /// Read file and normalize newlines. |
80 | /// | 77 | /// |