aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser')
-rw-r--r--crates/ra_parser/src/grammar.rs11
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs42
-rw-r--r--crates/ra_parser/src/grammar/expressions/atom.rs74
-rw-r--r--crates/ra_parser/src/grammar/items.rs2
-rw-r--r--crates/ra_parser/src/grammar/type_args.rs2
-rw-r--r--crates/ra_parser/src/lib.rs4
-rw-r--r--crates/ra_parser/src/parser.rs2
-rw-r--r--crates/ra_parser/src/syntax_kind/generated.rs2
8 files changed, 73 insertions, 66 deletions
diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs
index c2a6e82e9..293baecf6 100644
--- a/crates/ra_parser/src/grammar.rs
+++ b/crates/ra_parser/src/grammar.rs
@@ -18,9 +18,10 @@
18//! // fn foo() {} 18//! // fn foo() {}
19//! ``` 19//! ```
20//! 20//!
21//! After adding a new inline-test, run `cargo collect-tests` to extract 21//! After adding a new inline-test, run `cargo xtask codegen` to
22//! it as a standalone text-fixture into `tests/data/parser/inline`, and 22//! extract it as a standalone text-fixture into
23//! run `cargo test` once to create the "gold" value. 23//! `crates/ra_syntax/test_data/parser/`, and run `cargo test` once to
24//! create the "gold" value.
24//! 25//!
25//! Coding convention: rules like `where_clause` always produce either a 26//! Coding convention: rules like `where_clause` always produce either a
26//! node or an error, rules like `opt_where_clause` may produce nothing. 27//! node or an error, rules like `opt_where_clause` may produce nothing.
@@ -54,7 +55,7 @@ pub(crate) mod fragments {
54 use super::*; 55 use super::*;
55 56
56 pub(crate) use super::{ 57 pub(crate) use super::{
57 expressions::block, paths::type_path as path, patterns::pattern, types::type_, 58 expressions::block_expr, paths::type_path as path, patterns::pattern, types::type_,
58 }; 59 };
59 60
60 pub(crate) fn expr(p: &mut Parser) { 61 pub(crate) fn expr(p: &mut Parser) {
@@ -143,7 +144,7 @@ pub(crate) fn reparser(
143 parent: Option<SyntaxKind>, 144 parent: Option<SyntaxKind>,
144) -> Option<fn(&mut Parser)> { 145) -> Option<fn(&mut Parser)> {
145 let res = match node { 146 let res = match node {
146 BLOCK => expressions::naked_block, 147 BLOCK_EXPR => expressions::block_expr,
147 RECORD_FIELD_DEF_LIST => items::record_field_def_list, 148 RECORD_FIELD_DEF_LIST => items::record_field_def_list,
148 RECORD_FIELD_LIST => items::record_field_list, 149 RECORD_FIELD_LIST => items::record_field_list,
149 ENUM_VARIANT_LIST => items::enum_variant_list, 150 ENUM_VARIANT_LIST => items::enum_variant_list,
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index cb30b25a8..d6e8df32a 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -2,7 +2,7 @@
2 2
3mod atom; 3mod atom;
4 4
5pub(crate) use self::atom::match_arm_list; 5pub(crate) use self::atom::{block_expr, match_arm_list};
6pub(super) use self::atom::{literal, LITERAL_FIRST}; 6pub(super) use self::atom::{literal, LITERAL_FIRST};
7use super::*; 7use super::*;
8 8
@@ -49,28 +49,6 @@ fn expr_no_struct(p: &mut Parser) {
49 expr_bp(p, r, 1); 49 expr_bp(p, r, 1);
50} 50}
51 51
52// test block
53// fn a() {}
54// fn b() { let _ = 1; }
55// fn c() { 1; 2; }
56// fn d() { 1; 2 }
57pub(crate) fn block(p: &mut Parser) {
58 if !p.at(T!['{']) {
59 p.error("expected a block");
60 return;
61 }
62 atom::block_expr(p, None);
63}
64
65pub(crate) fn naked_block(p: &mut Parser) {
66 assert!(p.at(T!['{']));
67 let m = p.start();
68 p.bump(T!['{']);
69 expr_block_contents(p);
70 p.expect(T!['}']);
71 m.complete(p, BLOCK);
72}
73
74fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool { 52fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool {
75 match kind { 53 match kind {
76 BIN_EXPR | RANGE_EXPR | IF_EXPR => false, 54 BIN_EXPR | RANGE_EXPR | IF_EXPR => false,
@@ -197,7 +175,7 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) {
197 } 175 }
198} 176}
199 177
200pub(crate) fn expr_block_contents(p: &mut Parser) { 178pub(super) fn expr_block_contents(p: &mut Parser) {
201 // This is checked by a validator 179 // This is checked by a validator
202 attributes::inner_attributes(p); 180 attributes::inner_attributes(p);
203 181
@@ -347,13 +325,27 @@ fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)>
347 let kind = match p.current() { 325 let kind = match p.current() {
348 // test ref_expr 326 // test ref_expr
349 // fn foo() { 327 // fn foo() {
328 // // reference operator
350 // let _ = &1; 329 // let _ = &1;
351 // let _ = &mut &f(); 330 // let _ = &mut &f();
331 // let _ = &raw;
332 // let _ = &raw.0;
333 // // raw reference operator
334 // let _ = &raw mut foo;
335 // let _ = &raw const foo;
352 // } 336 // }
353 T![&] => { 337 T![&] => {
354 m = p.start(); 338 m = p.start();
355 p.bump(T![&]); 339 p.bump(T![&]);
356 p.eat(T![mut]); 340 if p.at(IDENT)
341 && p.at_contextual_kw("raw")
342 && (p.nth_at(1, T![mut]) || p.nth_at(1, T![const]))
343 {
344 p.bump_remap(T![raw]);
345 p.bump_any();
346 } else {
347 p.eat(T![mut]);
348 }
357 REF_EXPR 349 REF_EXPR
358 } 350 }
359 // test unary_expr 351 // test unary_expr
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs
index 76aa601cb..706a2f796 100644
--- a/crates/ra_parser/src/grammar/expressions/atom.rs
+++ b/crates/ra_parser/src/grammar/expressions/atom.rs
@@ -84,7 +84,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
84 T![box] => box_expr(p, None), 84 T![box] => box_expr(p, None),
85 T![for] => for_expr(p, None), 85 T![for] => for_expr(p, None),
86 T![while] => while_expr(p, None), 86 T![while] => while_expr(p, None),
87 T![try] => try_expr(p, None), 87 T![try] => try_block_expr(p, None),
88 LIFETIME if la == T![:] => { 88 LIFETIME if la == T![:] => {
89 let m = p.start(); 89 let m = p.start();
90 label(p); 90 label(p);
@@ -92,7 +92,12 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
92 T![loop] => loop_expr(p, Some(m)), 92 T![loop] => loop_expr(p, Some(m)),
93 T![for] => for_expr(p, Some(m)), 93 T![for] => for_expr(p, Some(m)),
94 T![while] => while_expr(p, Some(m)), 94 T![while] => while_expr(p, Some(m)),
95 T!['{'] => block_expr(p, Some(m)), 95 // test labeled_block
96 // fn f() { 'label: {}; }
97 T!['{'] => {
98 block_expr(p);
99 m.complete(p, EFFECT_EXPR)
100 }
96 _ => { 101 _ => {
97 // test_err misplaced_label_err 102 // test_err misplaced_label_err
98 // fn main() { 103 // fn main() {
@@ -108,13 +113,17 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
108 let m = p.start(); 113 let m = p.start();
109 p.bump(T![async]); 114 p.bump(T![async]);
110 p.eat(T![move]); 115 p.eat(T![move]);
111 block_expr(p, Some(m)) 116 block_expr(p);
117 m.complete(p, EFFECT_EXPR)
112 } 118 }
113 T![match] => match_expr(p), 119 T![match] => match_expr(p),
120 // test unsafe_block
121 // fn f() { unsafe { } }
114 T![unsafe] if la == T!['{'] => { 122 T![unsafe] if la == T!['{'] => {
115 let m = p.start(); 123 let m = p.start();
116 p.bump(T![unsafe]); 124 p.bump(T![unsafe]);
117 block_expr(p, Some(m)) 125 block_expr(p);
126 m.complete(p, EFFECT_EXPR)
118 } 127 }
119 T!['{'] => { 128 T!['{'] => {
120 // test for_range_from 129 // test for_range_from
@@ -123,7 +132,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
123 // break; 132 // break;
124 // } 133 // }
125 // } 134 // }
126 block_expr(p, None) 135 block_expr_unchecked(p)
127 } 136 }
128 T![return] => return_expr(p), 137 T![return] => return_expr(p),
129 T![continue] => continue_expr(p), 138 T![continue] => continue_expr(p),
@@ -134,7 +143,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
134 } 143 }
135 }; 144 };
136 let blocklike = match done.kind() { 145 let blocklike = match done.kind() {
137 IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | TRY_EXPR => { 146 IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | EFFECT_EXPR => {
138 BlockLike::Block 147 BlockLike::Block
139 } 148 }
140 _ => BlockLike::NotBlock, 149 _ => BlockLike::NotBlock,
@@ -231,13 +240,9 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
231 p.eat(T![move]); 240 p.eat(T![move]);
232 params::param_list_closure(p); 241 params::param_list_closure(p);
233 if opt_fn_ret_type(p) { 242 if opt_fn_ret_type(p) {
234 if p.at(T!['{']) { 243 // test lambda_ret_block
235 // test lambda_ret_block 244 // fn main() { || -> i32 { 92 }(); }
236 // fn main() { || -> i32 { 92 }(); } 245 block_expr(p);
237 block_expr(p, None);
238 } else {
239 p.error("expected `{`");
240 }
241 } else { 246 } else {
242 if p.at_ts(EXPR_FIRST) { 247 if p.at_ts(EXPR_FIRST) {
243 expr(p); 248 expr(p);
@@ -261,13 +266,13 @@ fn if_expr(p: &mut Parser) -> CompletedMarker {
261 let m = p.start(); 266 let m = p.start();
262 p.bump(T![if]); 267 p.bump(T![if]);
263 cond(p); 268 cond(p);
264 block(p); 269 block_expr(p);
265 if p.at(T![else]) { 270 if p.at(T![else]) {
266 p.bump(T![else]); 271 p.bump(T![else]);
267 if p.at(T![if]) { 272 if p.at(T![if]) {
268 if_expr(p); 273 if_expr(p);
269 } else { 274 } else {
270 block(p); 275 block_expr(p);
271 } 276 }
272 } 277 }
273 m.complete(p, IF_EXPR) 278 m.complete(p, IF_EXPR)
@@ -295,7 +300,7 @@ fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
295 assert!(p.at(T![loop])); 300 assert!(p.at(T![loop]));
296 let m = m.unwrap_or_else(|| p.start()); 301 let m = m.unwrap_or_else(|| p.start());
297 p.bump(T![loop]); 302 p.bump(T![loop]);
298 block(p); 303 block_expr(p);
299 m.complete(p, LOOP_EXPR) 304 m.complete(p, LOOP_EXPR)
300} 305}
301 306
@@ -310,7 +315,7 @@ fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
310 let m = m.unwrap_or_else(|| p.start()); 315 let m = m.unwrap_or_else(|| p.start());
311 p.bump(T![while]); 316 p.bump(T![while]);
312 cond(p); 317 cond(p);
313 block(p); 318 block_expr(p);
314 m.complete(p, WHILE_EXPR) 319 m.complete(p, WHILE_EXPR)
315} 320}
316 321
@@ -325,7 +330,7 @@ fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
325 patterns::pattern(p); 330 patterns::pattern(p);
326 p.expect(T![in]); 331 p.expect(T![in]);
327 expr_no_struct(p); 332 expr_no_struct(p);
328 block(p); 333 block_expr(p);
329 m.complete(p, FOR_EXPR) 334 m.complete(p, FOR_EXPR)
330} 335}
331 336
@@ -458,16 +463,25 @@ fn match_guard(p: &mut Parser) -> CompletedMarker {
458 m.complete(p, MATCH_GUARD) 463 m.complete(p, MATCH_GUARD)
459} 464}
460 465
461// test block_expr 466// test block
462// fn foo() { 467// fn a() {}
463// {}; 468// fn b() { let _ = 1; }
464// unsafe {}; 469// fn c() { 1; 2; }
465// 'label: {}; 470// fn d() { 1; 2 }
466// } 471pub(crate) fn block_expr(p: &mut Parser) {
467pub(super) fn block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { 472 if !p.at(T!['{']) {
473 p.error("expected a block");
474 return;
475 }
476 block_expr_unchecked(p);
477}
478
479fn block_expr_unchecked(p: &mut Parser) -> CompletedMarker {
468 assert!(p.at(T!['{'])); 480 assert!(p.at(T!['{']));
469 let m = m.unwrap_or_else(|| p.start()); 481 let m = p.start();
470 naked_block(p); 482 p.bump(T!['{']);
483 expr_block_contents(p);
484 p.expect(T!['}']);
471 m.complete(p, BLOCK_EXPR) 485 m.complete(p, BLOCK_EXPR)
472} 486}
473 487
@@ -532,7 +546,7 @@ fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
532// fn foo() { 546// fn foo() {
533// let _ = try {}; 547// let _ = try {};
534// } 548// }
535fn try_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { 549fn try_block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
536 assert!(p.at(T![try])); 550 assert!(p.at(T![try]));
537 let m = m.unwrap_or_else(|| p.start()); 551 let m = m.unwrap_or_else(|| p.start());
538 // Special-case `try!` as macro. 552 // Special-case `try!` as macro.
@@ -552,8 +566,8 @@ fn try_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
552 } 566 }
553 567
554 p.bump(T![try]); 568 p.bump(T![try]);
555 block(p); 569 block_expr(p);
556 m.complete(p, TRY_EXPR) 570 m.complete(p, EFFECT_EXPR)
557} 571}
558 572
559// test box_expr 573// test box_expr
diff --git a/crates/ra_parser/src/grammar/items.rs b/crates/ra_parser/src/grammar/items.rs
index 1503a8730..67a924de5 100644
--- a/crates/ra_parser/src/grammar/items.rs
+++ b/crates/ra_parser/src/grammar/items.rs
@@ -329,7 +329,7 @@ fn fn_def(p: &mut Parser) {
329 if p.at(T![;]) { 329 if p.at(T![;]) {
330 p.bump(T![;]); 330 p.bump(T![;]);
331 } else { 331 } else {
332 expressions::block(p) 332 expressions::block_expr(p)
333 } 333 }
334} 334}
335 335
diff --git a/crates/ra_parser/src/grammar/type_args.rs b/crates/ra_parser/src/grammar/type_args.rs
index 33d9973e9..2d61f9d80 100644
--- a/crates/ra_parser/src/grammar/type_args.rs
+++ b/crates/ra_parser/src/grammar/type_args.rs
@@ -48,7 +48,7 @@ fn type_arg(p: &mut Parser) {
48 m.complete(p, ASSOC_TYPE_ARG); 48 m.complete(p, ASSOC_TYPE_ARG);
49 } 49 }
50 T!['{'] => { 50 T!['{'] => {
51 expressions::block(p); 51 expressions::block_expr(p);
52 m.complete(p, CONST_ARG); 52 m.complete(p, CONST_ARG);
53 } 53 }
54 k if k.is_literal() => { 54 k if k.is_literal() => {
diff --git a/crates/ra_parser/src/lib.rs b/crates/ra_parser/src/lib.rs
index 652492c1e..eeb8ad66b 100644
--- a/crates/ra_parser/src/lib.rs
+++ b/crates/ra_parser/src/lib.rs
@@ -25,7 +25,7 @@ pub(crate) use token_set::TokenSet;
25pub use syntax_kind::SyntaxKind; 25pub use syntax_kind::SyntaxKind;
26 26
27#[derive(Debug, Clone, PartialEq, Eq, Hash)] 27#[derive(Debug, Clone, PartialEq, Eq, Hash)]
28pub struct ParseError(pub String); 28pub struct ParseError(pub Box<String>);
29 29
30/// `TokenSource` abstracts the source of the tokens parser operates on. 30/// `TokenSource` abstracts the source of the tokens parser operates on.
31/// 31///
@@ -112,7 +112,7 @@ pub fn parse_fragment(
112 FragmentKind::Type => grammar::fragments::type_, 112 FragmentKind::Type => grammar::fragments::type_,
113 FragmentKind::Pattern => grammar::fragments::pattern, 113 FragmentKind::Pattern => grammar::fragments::pattern,
114 FragmentKind::Item => grammar::fragments::item, 114 FragmentKind::Item => grammar::fragments::item,
115 FragmentKind::Block => grammar::fragments::block, 115 FragmentKind::Block => grammar::fragments::block_expr,
116 FragmentKind::Visibility => grammar::fragments::opt_visibility, 116 FragmentKind::Visibility => grammar::fragments::opt_visibility,
117 FragmentKind::MetaItem => grammar::fragments::meta_item, 117 FragmentKind::MetaItem => grammar::fragments::meta_item,
118 FragmentKind::Statement => grammar::fragments::stmt, 118 FragmentKind::Statement => grammar::fragments::stmt,
diff --git a/crates/ra_parser/src/parser.rs b/crates/ra_parser/src/parser.rs
index faa63d53f..4f59b0a23 100644
--- a/crates/ra_parser/src/parser.rs
+++ b/crates/ra_parser/src/parser.rs
@@ -192,7 +192,7 @@ impl<'t> Parser<'t> {
192 /// structured errors with spans and notes, like rustc 192 /// structured errors with spans and notes, like rustc
193 /// does. 193 /// does.
194 pub(crate) fn error<T: Into<String>>(&mut self, message: T) { 194 pub(crate) fn error<T: Into<String>>(&mut self, message: T) {
195 let msg = ParseError(message.into()); 195 let msg = ParseError(Box::new(message.into()));
196 self.push_event(Event::Error { msg }) 196 self.push_event(Event::Error { msg })
197 } 197 }
198 198
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs
index ab727ed7e..e7404492a 100644
--- a/crates/ra_parser/src/syntax_kind/generated.rs
+++ b/crates/ra_parser/src/syntax_kind/generated.rs
@@ -191,6 +191,7 @@ pub enum SyntaxKind {
191 RECORD_LIT, 191 RECORD_LIT,
192 RECORD_FIELD_LIST, 192 RECORD_FIELD_LIST,
193 RECORD_FIELD, 193 RECORD_FIELD,
194 EFFECT_EXPR,
194 BOX_EXPR, 195 BOX_EXPR,
195 CALL_EXPR, 196 CALL_EXPR,
196 INDEX_EXPR, 197 INDEX_EXPR,
@@ -203,7 +204,6 @@ pub enum SyntaxKind {
203 PREFIX_EXPR, 204 PREFIX_EXPR,
204 RANGE_EXPR, 205 RANGE_EXPR,
205 BIN_EXPR, 206 BIN_EXPR,
206 BLOCK,
207 EXTERN_BLOCK, 207 EXTERN_BLOCK,
208 EXTERN_ITEM_LIST, 208 EXTERN_ITEM_LIST,
209 ENUM_VARIANT, 209 ENUM_VARIANT,