aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/handlers/early_return.rs16
-rw-r--r--crates/ra_assists/src/handlers/inline_local_variable.rs1
-rw-r--r--crates/ra_assists/src/handlers/introduce_variable.rs2
-rw-r--r--crates/ra_assists/src/handlers/move_guard.rs4
-rw-r--r--crates/ra_fmt/src/lib.rs1
-rw-r--r--crates/ra_hir_def/src/body/lower.rs24
-rw-r--r--crates/ra_hir_expand/src/db.rs3
-rw-r--r--crates/ra_ide/src/completion/completion_context.rs2
-rw-r--r--crates/ra_ide/src/folding_ranges.rs2
-rw-r--r--crates/ra_ide/src/join_lines.rs3
-rw-r--r--crates/ra_ide/src/syntax_tree.rs77
-rw-r--r--crates/ra_mbe/src/tests.rs152
-rw-r--r--crates/ra_parser/src/grammar.rs2
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs13
-rw-r--r--crates/ra_parser/src/grammar/expressions/atom.rs29
-rw-r--r--crates/ra_parser/src/syntax_kind/generated.rs3
-rw-r--r--crates/ra_syntax/src/ast.rs2
-rw-r--r--crates/ra_syntax/src/ast/edit.rs2
-rw-r--r--crates/ra_syntax/src/ast/expr_extensions.rs40
-rw-r--r--crates/ra_syntax/src/ast/generated/nodes.rs74
-rw-r--r--crates/ra_syntax/src/ast/make.rs4
-rw-r--r--crates/ra_syntax/src/lib.rs7
-rw-r--r--crates/ra_syntax/src/validation/block.rs20
-rw-r--r--xtask/src/ast_src.rs19
-rw-r--r--xtask/src/codegen/gen_syntax.rs1
25 files changed, 242 insertions, 261 deletions
diff --git a/crates/ra_assists/src/handlers/early_return.rs b/crates/ra_assists/src/handlers/early_return.rs
index ea6c56f8c..eede2fe91 100644
--- a/crates/ra_assists/src/handlers/early_return.rs
+++ b/crates/ra_assists/src/handlers/early_return.rs
@@ -2,7 +2,7 @@ use std::{iter::once, ops::RangeInclusive};
2 2
3use ra_syntax::{ 3use ra_syntax::{
4 algo::replace_children, 4 algo::replace_children,
5 ast::{self, edit::IndentLevel, make, Block, Pat::TupleStructPat}, 5 ast::{self, edit::IndentLevel, make},
6 AstNode, 6 AstNode,
7 SyntaxKind::{FN_DEF, LOOP_EXPR, L_CURLY, R_CURLY, WHILE_EXPR, WHITESPACE}, 7 SyntaxKind::{FN_DEF, LOOP_EXPR, L_CURLY, R_CURLY, WHILE_EXPR, WHITESPACE},
8 SyntaxNode, 8 SyntaxNode,
@@ -47,7 +47,7 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx) -> Option<Assist> {
47 // Check if there is an IfLet that we can handle. 47 // Check if there is an IfLet that we can handle.
48 let if_let_pat = match cond.pat() { 48 let if_let_pat = match cond.pat() {
49 None => None, // No IfLet, supported. 49 None => None, // No IfLet, supported.
50 Some(TupleStructPat(pat)) if pat.args().count() == 1 => { 50 Some(ast::Pat::TupleStructPat(pat)) if pat.args().count() == 1 => {
51 let path = pat.path()?; 51 let path = pat.path()?;
52 match path.qualifier() { 52 match path.qualifier() {
53 None => { 53 None => {
@@ -61,9 +61,9 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx) -> Option<Assist> {
61 }; 61 };
62 62
63 let cond_expr = cond.expr()?; 63 let cond_expr = cond.expr()?;
64 let then_block = if_expr.then_branch()?.block()?; 64 let then_block = if_expr.then_branch()?;
65 65
66 let parent_block = if_expr.syntax().parent()?.ancestors().find_map(ast::Block::cast)?; 66 let parent_block = if_expr.syntax().parent()?.ancestors().find_map(ast::BlockExpr::cast)?;
67 67
68 if parent_block.expr()? != if_expr.clone().into() { 68 if parent_block.expr()? != if_expr.clone().into() {
69 return None; 69 return None;
@@ -80,7 +80,7 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx) -> Option<Assist> {
80 return None; 80 return None;
81 } 81 }
82 82
83 let parent_container = parent_block.syntax().parent()?.parent()?; 83 let parent_container = parent_block.syntax().parent()?;
84 84
85 let early_expression: ast::Expr = match parent_container.kind() { 85 let early_expression: ast::Expr = match parent_container.kind() {
86 WHILE_EXPR | LOOP_EXPR => make::expr_continue(), 86 WHILE_EXPR | LOOP_EXPR => make::expr_continue(),
@@ -144,13 +144,13 @@ pub(crate) fn convert_to_guarded_return(ctx: AssistCtx) -> Option<Assist> {
144 } 144 }
145 }; 145 };
146 edit.target(if_expr.syntax().text_range()); 146 edit.target(if_expr.syntax().text_range());
147 edit.replace_ast(parent_block, ast::Block::cast(new_block).unwrap()); 147 edit.replace_ast(parent_block, ast::BlockExpr::cast(new_block).unwrap());
148 edit.set_cursor(cursor_position); 148 edit.set_cursor(cursor_position);
149 149
150 fn replace( 150 fn replace(
151 new_expr: &SyntaxNode, 151 new_expr: &SyntaxNode,
152 then_block: &Block, 152 then_block: &ast::BlockExpr,
153 parent_block: &Block, 153 parent_block: &ast::BlockExpr,
154 if_expr: &ast::IfExpr, 154 if_expr: &ast::IfExpr,
155 ) -> SyntaxNode { 155 ) -> SyntaxNode {
156 let then_block_items = IndentLevel::from(1).decrease_indent(then_block.clone()); 156 let then_block_items = IndentLevel::from(1).decrease_indent(then_block.clone());
diff --git a/crates/ra_assists/src/handlers/inline_local_variable.rs b/crates/ra_assists/src/handlers/inline_local_variable.rs
index f5702f6e0..60ec536a7 100644
--- a/crates/ra_assists/src/handlers/inline_local_variable.rs
+++ b/crates/ra_assists/src/handlers/inline_local_variable.rs
@@ -89,6 +89,7 @@ pub(crate) fn inline_local_variable(ctx: AssistCtx) -> Option<Assist> {
89 | (ast::Expr::ParenExpr(_), _) 89 | (ast::Expr::ParenExpr(_), _)
90 | (ast::Expr::PathExpr(_), _) 90 | (ast::Expr::PathExpr(_), _)
91 | (ast::Expr::BlockExpr(_), _) 91 | (ast::Expr::BlockExpr(_), _)
92 | (ast::Expr::EffectExpr(_), _)
92 | (_, ast::Expr::CallExpr(_)) 93 | (_, ast::Expr::CallExpr(_))
93 | (_, ast::Expr::TupleExpr(_)) 94 | (_, ast::Expr::TupleExpr(_))
94 | (_, ast::Expr::ArrayExpr(_)) 95 | (_, ast::Expr::ArrayExpr(_))
diff --git a/crates/ra_assists/src/handlers/introduce_variable.rs b/crates/ra_assists/src/handlers/introduce_variable.rs
index eda9ac296..39c656305 100644
--- a/crates/ra_assists/src/handlers/introduce_variable.rs
+++ b/crates/ra_assists/src/handlers/introduce_variable.rs
@@ -111,7 +111,7 @@ fn valid_target_expr(node: SyntaxNode) -> Option<ast::Expr> {
111/// expression like a lambda or match arm. 111/// expression like a lambda or match arm.
112fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> { 112fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> {
113 expr.syntax().ancestors().find_map(|node| { 113 expr.syntax().ancestors().find_map(|node| {
114 if let Some(expr) = node.parent().and_then(ast::Block::cast).and_then(|it| it.expr()) { 114 if let Some(expr) = node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.expr()) {
115 if expr.syntax() == &node { 115 if expr.syntax() == &node {
116 tested_by!(test_introduce_var_last_expr); 116 tested_by!(test_introduce_var_last_expr);
117 return Some((node, false)); 117 return Some((node, false));
diff --git a/crates/ra_assists/src/handlers/move_guard.rs b/crates/ra_assists/src/handlers/move_guard.rs
index d5ccdd91c..b084dd9ee 100644
--- a/crates/ra_assists/src/handlers/move_guard.rs
+++ b/crates/ra_assists/src/handlers/move_guard.rs
@@ -113,9 +113,9 @@ pub(crate) fn move_arm_cond_to_match_guard(ctx: AssistCtx) -> Option<Assist> {
113 "Move condition to match guard", 113 "Move condition to match guard",
114 |edit| { 114 |edit| {
115 edit.target(if_expr.syntax().text_range()); 115 edit.target(if_expr.syntax().text_range());
116 let then_only_expr = then_block.block().and_then(|it| it.statements().next()).is_none(); 116 let then_only_expr = then_block.statements().next().is_none();
117 117
118 match &then_block.block().and_then(|it| it.expr()) { 118 match &then_block.expr() {
119 Some(then_expr) if then_only_expr => { 119 Some(then_expr) if then_only_expr => {
120 edit.replace(if_expr.syntax().text_range(), then_expr.syntax().text()) 120 edit.replace(if_expr.syntax().text_range(), then_expr.syntax().text())
121 } 121 }
diff --git a/crates/ra_fmt/src/lib.rs b/crates/ra_fmt/src/lib.rs
index 1a30b2b3a..f910ded9d 100644
--- a/crates/ra_fmt/src/lib.rs
+++ b/crates/ra_fmt/src/lib.rs
@@ -42,7 +42,6 @@ pub fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr {
42} 42}
43 43
44pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> { 44pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> {
45 let block = block.block()?;
46 let has_anything_else = |thing: &SyntaxNode| -> bool { 45 let has_anything_else = |thing: &SyntaxNode| -> bool {
47 let mut non_trivial_children = 46 let mut non_trivial_children =
48 block.syntax().children_with_tokens().filter(|it| match it.kind() { 47 block.syntax().children_with_tokens().filter(|it| match it.kind() {
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index f06cc115b..58b3d10d8 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -203,10 +203,16 @@ impl ExprCollector<'_> {
203 203
204 self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) 204 self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr)
205 } 205 }
206 ast::Expr::TryBlockExpr(e) => { 206 ast::Expr::EffectExpr(e) => match e.effect() {
207 let body = self.collect_block_opt(e.body()); 207 ast::Effect::Try(_) => {
208 self.alloc_expr(Expr::TryBlock { body }, syntax_ptr) 208 let body = self.collect_block_opt(e.block_expr());
209 } 209 self.alloc_expr(Expr::TryBlock { body }, syntax_ptr)
210 }
211 // FIXME: we need to record these effects somewhere...
212 ast::Effect::Async(_) | ast::Effect::Label(_) | ast::Effect::Unsafe(_) => {
213 self.collect_block_opt(e.block_expr())
214 }
215 },
210 ast::Expr::BlockExpr(e) => self.collect_block(e), 216 ast::Expr::BlockExpr(e) => self.collect_block(e),
211 ast::Expr::LoopExpr(e) => { 217 ast::Expr::LoopExpr(e) => {
212 let body = self.collect_block_opt(e.loop_body()); 218 let body = self.collect_block_opt(e.loop_body());
@@ -494,12 +500,8 @@ impl ExprCollector<'_> {
494 } 500 }
495 } 501 }
496 502
497 fn collect_block(&mut self, expr: ast::BlockExpr) -> ExprId { 503 fn collect_block(&mut self, block: ast::BlockExpr) -> ExprId {
498 let syntax_node_ptr = AstPtr::new(&expr.clone().into()); 504 let syntax_node_ptr = AstPtr::new(&block.clone().into());
499 let block = match expr.block() {
500 Some(block) => block,
501 None => return self.alloc_expr(Expr::Missing, syntax_node_ptr),
502 };
503 self.collect_block_items(&block); 505 self.collect_block_items(&block);
504 let statements = block 506 let statements = block
505 .statements() 507 .statements()
@@ -517,7 +519,7 @@ impl ExprCollector<'_> {
517 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr) 519 self.alloc_expr(Expr::Block { statements, tail }, syntax_node_ptr)
518 } 520 }
519 521
520 fn collect_block_items(&mut self, block: &ast::Block) { 522 fn collect_block_items(&mut self, block: &ast::BlockExpr) {
521 let container = ContainerId::DefWithBodyId(self.def); 523 let container = ContainerId::DefWithBodyId(self.def);
522 for item in block.items() { 524 for item in block.items() {
523 let (def, name): (ModuleDefId, Option<ast::Name>) = match item { 525 let (def, name): (ModuleDefId, Option<ast::Name>) = match item {
diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs
index 047452306..4c12d0a15 100644
--- a/crates/ra_hir_expand/src/db.rs
+++ b/crates/ra_hir_expand/src/db.rs
@@ -330,7 +330,7 @@ fn to_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind {
330 FragmentKind::Expr 330 FragmentKind::Expr
331 } 331 }
332 // FIXME: Expand to statements in appropriate positions; HIR lowering needs to handle that 332 // FIXME: Expand to statements in appropriate positions; HIR lowering needs to handle that
333 EXPR_STMT | BLOCK => FragmentKind::Expr, 333 EXPR_STMT | BLOCK_EXPR => FragmentKind::Expr,
334 ARG_LIST => FragmentKind::Expr, 334 ARG_LIST => FragmentKind::Expr,
335 TRY_EXPR => FragmentKind::Expr, 335 TRY_EXPR => FragmentKind::Expr,
336 TUPLE_EXPR => FragmentKind::Expr, 336 TUPLE_EXPR => FragmentKind::Expr,
@@ -342,7 +342,6 @@ fn to_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind {
342 CONDITION => FragmentKind::Expr, 342 CONDITION => FragmentKind::Expr,
343 BREAK_EXPR => FragmentKind::Expr, 343 BREAK_EXPR => FragmentKind::Expr,
344 RETURN_EXPR => FragmentKind::Expr, 344 RETURN_EXPR => FragmentKind::Expr,
345 BLOCK_EXPR => FragmentKind::Expr,
346 MATCH_EXPR => FragmentKind::Expr, 345 MATCH_EXPR => FragmentKind::Expr,
347 MATCH_ARM => FragmentKind::Expr, 346 MATCH_ARM => FragmentKind::Expr,
348 MATCH_GUARD => FragmentKind::Expr, 347 MATCH_GUARD => FragmentKind::Expr,
diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs
index 118fceb2e..c529752d4 100644
--- a/crates/ra_ide/src/completion/completion_context.rs
+++ b/crates/ra_ide/src/completion/completion_context.rs
@@ -344,7 +344,7 @@ impl<'a> CompletionContext<'a> {
344 stmt.syntax().text_range() == name_ref.syntax().text_range(), 344 stmt.syntax().text_range() == name_ref.syntax().text_range(),
345 ); 345 );
346 } 346 }
347 if let Some(block) = ast::Block::cast(node) { 347 if let Some(block) = ast::BlockExpr::cast(node) {
348 return Some( 348 return Some(
349 block.expr().map(|e| e.syntax().text_range()) 349 block.expr().map(|e| e.syntax().text_range())
350 == Some(name_ref.syntax().text_range()), 350 == Some(name_ref.syntax().text_range()),
diff --git a/crates/ra_ide/src/folding_ranges.rs b/crates/ra_ide/src/folding_ranges.rs
index 4379005aa..8657377de 100644
--- a/crates/ra_ide/src/folding_ranges.rs
+++ b/crates/ra_ide/src/folding_ranges.rs
@@ -88,7 +88,7 @@ fn fold_kind(kind: SyntaxKind) -> Option<FoldKind> {
88 | ITEM_LIST 88 | ITEM_LIST
89 | EXTERN_ITEM_LIST 89 | EXTERN_ITEM_LIST
90 | USE_TREE_LIST 90 | USE_TREE_LIST
91 | BLOCK 91 | BLOCK_EXPR
92 | MATCH_ARM_LIST 92 | MATCH_ARM_LIST
93 | ENUM_VARIANT_LIST 93 | ENUM_VARIANT_LIST
94 | TOKEN_TREE => Some(FoldKind::Block), 94 | TOKEN_TREE => Some(FoldKind::Block),
diff --git a/crates/ra_ide/src/join_lines.rs b/crates/ra_ide/src/join_lines.rs
index d0def7eaa..63fd6b3e4 100644
--- a/crates/ra_ide/src/join_lines.rs
+++ b/crates/ra_ide/src/join_lines.rs
@@ -129,8 +129,7 @@ fn has_comma_after(node: &SyntaxNode) -> bool {
129} 129}
130 130
131fn join_single_expr_block(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Option<()> { 131fn join_single_expr_block(edit: &mut TextEditBuilder, token: &SyntaxToken) -> Option<()> {
132 let block = ast::Block::cast(token.parent())?; 132 let block_expr = ast::BlockExpr::cast(token.parent())?;
133 let block_expr = ast::BlockExpr::cast(block.syntax().parent()?)?;
134 if !block_expr.is_standalone() { 133 if !block_expr.is_standalone() {
135 return None; 134 return None;
136 } 135 }
diff --git a/crates/ra_ide/src/syntax_tree.rs b/crates/ra_ide/src/syntax_tree.rs
index bf97f8c56..86c70ff83 100644
--- a/crates/ra_ide/src/syntax_tree.rs
+++ b/crates/ra_ide/src/syntax_tree.rs
@@ -120,9 +120,8 @@ [email protected]
120 [email protected] ")" 120 [email protected] ")"
121 [email protected] " " 121 [email protected] " "
122 [email protected] 122 [email protected]
123 [email protected] 123 [email protected] "{"
124 [email protected] "{" 124 [email protected] "}"
125 [email protected] "}"
126"# 125"#
127 .trim() 126 .trim()
128 ); 127 );
@@ -153,26 +152,25 @@ [email protected]
153 [email protected] ")" 152 [email protected] ")"
154 [email protected] " " 153 [email protected] " "
155 [email protected] 154 [email protected]
156 [email protected] 155 [email protected] "{"
157 [email protected] "{" 156 [email protected] "\n "
158 [email protected] "\n " 157 [email protected]
159 [email protected] 158 [email protected]
160 [email protected] 159 [email protected]
161 [email protected] 160 [email protected]
162 [email protected] 161 [email protected]
163 [email protected] 162 [email protected] "assert"
164 [email protected] "assert" 163 [email protected] "!"
165 [email protected] "!" 164 [email protected]
166 [email protected] 165 [email protected] "("
167 [email protected] "(" 166 [email protected] "\"\n fn foo() {\n ..."
168 [email protected] "\"\n fn foo() {\n ..." 167 [email protected] ","
169 [email protected] "," 168 [email protected] " "
170 [email protected] " " 169 [email protected] "\"\""
171 [email protected] "\"\"" 170 [email protected] ")"
172 [email protected] ")" 171 [email protected] ";"
173 [email protected] ";" 172 [email protected] "\n"
174 [email protected] "\n" 173 [email protected] "}"
175 [email protected] "}"
176"# 174"#
177 .trim() 175 .trim()
178 ); 176 );
@@ -196,9 +194,8 @@ [email protected]
196 [email protected] ")" 194 [email protected] ")"
197 [email protected] " " 195 [email protected] " "
198 [email protected] 196 [email protected]
199 [email protected] 197 [email protected] "{"
200 [email protected] "{" 198 [email protected] "}"
201 [email protected] "}"
202"# 199"#
203 .trim() 200 .trim()
204 ); 201 );
@@ -265,10 +262,9 @@ [email protected]
265 [email protected] ")" 262 [email protected] ")"
266 [email protected] " " 263 [email protected] " "
267 [email protected] 264 [email protected]
268 [email protected] 265 [email protected] "{"
269 [email protected] "{" 266 [email protected] "\n"
270 [email protected] "\n" 267 [email protected] "}"
271 [email protected] "}"
272"# 268"#
273 .trim() 269 .trim()
274 ); 270 );
@@ -300,10 +296,9 @@ [email protected]
300 [email protected] ")" 296 [email protected] ")"
301 [email protected] " " 297 [email protected] " "
302 [email protected] 298 [email protected]
303 [email protected] 299 [email protected] "{"
304 [email protected] "{" 300 [email protected] "\n"
305 [email protected] "\n" 301 [email protected] "}"
306 [email protected] "}"
307"# 302"#
308 .trim() 303 .trim()
309 ); 304 );
@@ -334,10 +329,9 @@ [email protected]
334 [email protected] ")" 329 [email protected] ")"
335 [email protected] " " 330 [email protected] " "
336 [email protected] 331 [email protected]
337 [email protected] 332 [email protected] "{"
338 [email protected] "{" 333 [email protected] "\n"
339 [email protected] "\n" 334 [email protected] "}"
340 [email protected] "}"
341 [email protected] "\n" 335 [email protected] "\n"
342 [email protected] 336 [email protected]
343 [email protected] "fn" 337 [email protected] "fn"
@@ -349,10 +343,9 @@ [email protected]
349 [email protected] ")" 343 [email protected] ")"
350 [email protected] " " 344 [email protected] " "
351 [email protected] 345 [email protected]
352 [email protected] 346 [email protected] "{"
353 [email protected] "{" 347 [email protected] "\n"
354 [email protected] "\n" 348 [email protected] "}"
355 [email protected] "}"
356"# 349"#
357 .trim() 350 .trim()
358 ); 351 );
diff --git a/crates/ra_mbe/src/tests.rs b/crates/ra_mbe/src/tests.rs
index 0d924ce58..c43003fd6 100644
--- a/crates/ra_mbe/src/tests.rs
+++ b/crates/ra_mbe/src/tests.rs
@@ -266,21 +266,20 @@ fn test_expr_order() {
266 [email protected] "(" 266 [email protected] "("
267 [email protected] ")" 267 [email protected] ")"
268 [email protected] 268 [email protected]
269 [email protected] 269 [email protected] "{"
270 [email protected] "{" 270 [email protected]
271 [email protected] 271 [email protected]
272 [email protected] 272 [email protected]
273 [email protected] 273 [email protected]
274 [email protected] 274 [email protected] "1"
275 [email protected] "1" 275 [email protected] "+"
276 [email protected] "+" 276 [email protected]
277 [email protected] 277 [email protected] "1"
278 [email protected] "1" 278 [email protected] "*"
279 [email protected] "*" 279 [email protected]
280 [email protected] 280 [email protected] "2"
281 [email protected] "2" 281 [email protected] ";"
282 [email protected] ";" 282 [email protected] "}""#,
283 [email protected] "}""#,
284 ); 283 );
285} 284}
286 285
@@ -1114,68 +1113,67 @@ fn test_vec() {
1114 assert_eq!( 1113 assert_eq!(
1115 format!("{:#?}", tree).trim(), 1114 format!("{:#?}", tree).trim(),
1116 r#"[email protected] 1115 r#"[email protected]
1117 [email protected] 1116 [email protected] "{"
1118 [email protected] "{" 1117 [email protected]
1119 [email protected] 1118 [email protected] "let"
1120 [email protected] "let" 1119 [email protected]
1121 [email protected] 1120 [email protected] "mut"
1122 [email protected] "mut" 1121 [email protected]
1123 [email protected] 1122 [email protected] "v"
1124 [email protected] "v" 1123 [email protected] "="
1125 [email protected] "=" 1124 [email protected]
1126 [email protected] 1125 [email protected]
1127 [email protected] 1126 [email protected]
1128 [email protected] 1127 [email protected]
1129 [email protected] 1128 [email protected]
1130 [email protected] 1129 [email protected]
1131 [email protected] 1130 [email protected] "Vec"
1132 [email protected] "Vec" 1131 [email protected] "::"
1133 [email protected] "::" 1132 [email protected]
1134 [email protected] 1133 [email protected]
1135 [email protected] 1134 [email protected] "new"
1136 [email protected] "new" 1135 [email protected]
1137 [email protected] 1136 [email protected] "("
1138 [email protected] "(" 1137 [email protected] ")"
1139 [email protected] ")" 1138 [email protected] ";"
1140 [email protected] ";" 1139 [email protected]
1141 [email protected] 1140 [email protected]
1142 [email protected] 1141 [email protected]
1143 [email protected] 1142 [email protected]
1144 [email protected] 1143 [email protected]
1145 [email protected] 1144 [email protected]
1146 [email protected] 1145 [email protected] "v"
1147 [email protected] "v" 1146 [email protected] "."
1148 [email protected] "." 1147 [email protected]
1149 [email protected] 1148 [email protected] "push"
1150 [email protected] "push" 1149 [email protected]
1151 [email protected] 1150 [email protected] "("
1152 [email protected] "(" 1151 [email protected]
1153 [email protected] 1152 [email protected] "1u32"
1154 [email protected] "1u32" 1153 [email protected] ")"
1155 [email protected] ")" 1154 [email protected] ";"
1156 [email protected] ";" 1155 [email protected]
1157 [email protected] 1156 [email protected]
1158 [email protected] 1157 [email protected]
1159 [email protected] 1158 [email protected]
1160 [email protected] 1159 [email protected]
1161 [email protected] 1160 [email protected]
1162 [email protected] 1161 [email protected] "v"
1163 [email protected] "v" 1162 [email protected] "."
1164 [email protected] "." 1163 [email protected]
1165 [email protected] 1164 [email protected] "push"
1166 [email protected] "push" 1165 [email protected]
1167 [email protected] 1166 [email protected] "("
1168 [email protected] "(" 1167 [email protected]
1169 [email protected] 1168 [email protected] "2"
1170 [email protected] "2" 1169 [email protected] ")"
1171 [email protected] ")" 1170 [email protected] ";"
1172 [email protected] ";" 1171 [email protected]
1173 [email protected] 1172 [email protected]
1174 [email protected] 1173 [email protected]
1175 [email protected] 1174 [email protected]
1176 [email protected] 1175 [email protected] "v"
1177 [email protected] "v" 1176 [email protected] "}""#
1178 [email protected] "}""#
1179 ); 1177 );
1180} 1178}
1181 1179
diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs
index c2a6e82e9..d9824ff9b 100644
--- a/crates/ra_parser/src/grammar.rs
+++ b/crates/ra_parser/src/grammar.rs
@@ -143,7 +143,7 @@ pub(crate) fn reparser(
143 parent: Option<SyntaxKind>, 143 parent: Option<SyntaxKind>,
144) -> Option<fn(&mut Parser)> { 144) -> Option<fn(&mut Parser)> {
145 let res = match node { 145 let res = match node {
146 BLOCK => expressions::naked_block, 146 BLOCK_EXPR => expressions::block,
147 RECORD_FIELD_DEF_LIST => items::record_field_def_list, 147 RECORD_FIELD_DEF_LIST => items::record_field_def_list,
148 RECORD_FIELD_LIST => items::record_field_list, 148 RECORD_FIELD_LIST => items::record_field_list,
149 ENUM_VARIANT_LIST => items::enum_variant_list, 149 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..a23dbcacf 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -59,16 +59,7 @@ pub(crate) fn block(p: &mut Parser) {
59 p.error("expected a block"); 59 p.error("expected a block");
60 return; 60 return;
61 } 61 }
62 atom::block_expr(p, None); 62 atom::block_expr(p);
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} 63}
73 64
74fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool { 65fn is_expr_stmt_attr_allowed(kind: SyntaxKind) -> bool {
@@ -197,7 +188,7 @@ pub(super) fn stmt(p: &mut Parser, with_semi: StmtWithSemi) {
197 } 188 }
198} 189}
199 190
200pub(crate) fn expr_block_contents(p: &mut Parser) { 191pub(super) fn expr_block_contents(p: &mut Parser) {
201 // This is checked by a validator 192 // This is checked by a validator
202 attributes::inner_attributes(p); 193 attributes::inner_attributes(p);
203 194
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs
index 166dfc472..c76b7330c 100644
--- a/crates/ra_parser/src/grammar/expressions/atom.rs
+++ b/crates/ra_parser/src/grammar/expressions/atom.rs
@@ -92,7 +92,10 @@ 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 T!['{'] => {
96 block_expr(p);
97 m.complete(p, EFFECT_EXPR)
98 }
96 _ => { 99 _ => {
97 // test_err misplaced_label_err 100 // test_err misplaced_label_err
98 // fn main() { 101 // fn main() {
@@ -108,13 +111,15 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
108 let m = p.start(); 111 let m = p.start();
109 p.bump(T![async]); 112 p.bump(T![async]);
110 p.eat(T![move]); 113 p.eat(T![move]);
111 block_expr(p, Some(m)) 114 block_expr(p);
115 m.complete(p, EFFECT_EXPR)
112 } 116 }
113 T![match] => match_expr(p), 117 T![match] => match_expr(p),
114 T![unsafe] if la == T!['{'] => { 118 T![unsafe] if la == T!['{'] => {
115 let m = p.start(); 119 let m = p.start();
116 p.bump(T![unsafe]); 120 p.bump(T![unsafe]);
117 block_expr(p, Some(m)) 121 block_expr(p);
122 m.complete(p, EFFECT_EXPR)
118 } 123 }
119 T!['{'] => { 124 T!['{'] => {
120 // test for_range_from 125 // test for_range_from
@@ -123,7 +128,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
123 // break; 128 // break;
124 // } 129 // }
125 // } 130 // }
126 block_expr(p, None) 131 block_expr(p)
127 } 132 }
128 T![return] => return_expr(p), 133 T![return] => return_expr(p),
129 T![continue] => continue_expr(p), 134 T![continue] => continue_expr(p),
@@ -134,7 +139,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
134 } 139 }
135 }; 140 };
136 let blocklike = match done.kind() { 141 let blocklike = match done.kind() {
137 IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | TRY_BLOCK_EXPR => { 142 IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | EFFECT_EXPR => {
138 BlockLike::Block 143 BlockLike::Block
139 } 144 }
140 _ => BlockLike::NotBlock, 145 _ => BlockLike::NotBlock,
@@ -234,7 +239,7 @@ fn lambda_expr(p: &mut Parser) -> CompletedMarker {
234 if p.at(T!['{']) { 239 if p.at(T!['{']) {
235 // test lambda_ret_block 240 // test lambda_ret_block
236 // fn main() { || -> i32 { 92 }(); } 241 // fn main() { || -> i32 { 92 }(); }
237 block_expr(p, None); 242 block_expr(p);
238 } else { 243 } else {
239 p.error("expected `{`"); 244 p.error("expected `{`");
240 } 245 }
@@ -464,10 +469,12 @@ fn match_guard(p: &mut Parser) -> CompletedMarker {
464// unsafe {}; 469// unsafe {};
465// 'label: {}; 470// 'label: {};
466// } 471// }
467pub(super) fn block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { 472pub(super) fn block_expr(p: &mut Parser) -> CompletedMarker {
468 assert!(p.at(T!['{'])); 473 assert!(p.at(T!['{']));
469 let m = m.unwrap_or_else(|| p.start()); 474 let m = p.start();
470 naked_block(p); 475 p.bump(T!['{']);
476 expr_block_contents(p);
477 p.expect(T!['}']);
471 m.complete(p, BLOCK_EXPR) 478 m.complete(p, BLOCK_EXPR)
472} 479}
473 480
@@ -552,8 +559,8 @@ fn try_block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
552 } 559 }
553 560
554 p.bump(T![try]); 561 p.bump(T![try]);
555 block(p); 562 block_expr(p);
556 m.complete(p, TRY_EXPR) 563 m.complete(p, EFFECT_EXPR)
557} 564}
558 565
559// test box_expr 566// test box_expr
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs
index 524e7d784..e7404492a 100644
--- a/crates/ra_parser/src/syntax_kind/generated.rs
+++ b/crates/ra_parser/src/syntax_kind/generated.rs
@@ -191,7 +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 TRY_BLOCK_EXPR, 194 EFFECT_EXPR,
195 BOX_EXPR, 195 BOX_EXPR,
196 CALL_EXPR, 196 CALL_EXPR,
197 INDEX_EXPR, 197 INDEX_EXPR,
@@ -204,7 +204,6 @@ pub enum SyntaxKind {
204 PREFIX_EXPR, 204 PREFIX_EXPR,
205 RANGE_EXPR, 205 RANGE_EXPR,
206 BIN_EXPR, 206 BIN_EXPR,
207 BLOCK,
208 EXTERN_BLOCK, 207 EXTERN_BLOCK,
209 EXTERN_ITEM_LIST, 208 EXTERN_ITEM_LIST,
210 ENUM_VARIANT, 209 ENUM_VARIANT,
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index a716e525b..1876afe95 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -16,7 +16,7 @@ use crate::{
16}; 16};
17 17
18pub use self::{ 18pub use self::{
19 expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp, RangeOp}, 19 expr_extensions::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind, PrefixOp, RangeOp},
20 extensions::{ 20 extensions::{
21 AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents, 21 AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents,
22 StructKind, TypeBoundKind, VisibilityKind, 22 StructKind, TypeBoundKind, VisibilityKind,
diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs
index 26e4576ff..c507dc683 100644
--- a/crates/ra_syntax/src/ast/edit.rs
+++ b/crates/ra_syntax/src/ast/edit.rs
@@ -28,7 +28,7 @@ impl ast::BinExpr {
28 28
29impl ast::FnDef { 29impl ast::FnDef {
30 #[must_use] 30 #[must_use]
31 pub fn with_body(&self, body: ast::Block) -> ast::FnDef { 31 pub fn with_body(&self, body: ast::BlockExpr) -> ast::FnDef {
32 let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new(); 32 let mut to_insert: ArrayVec<[SyntaxElement; 2]> = ArrayVec::new();
33 let old_body_or_semi: SyntaxElement = if let Some(old_body) = self.body() { 33 let old_body_or_semi: SyntaxElement = if let Some(old_body) = self.body() {
34 old_body.syntax().clone().into() 34 old_body.syntax().clone().into()
diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs
index ecf74fd36..7ee36e60c 100644
--- a/crates/ra_syntax/src/ast/expr_extensions.rs
+++ b/crates/ra_syntax/src/ast/expr_extensions.rs
@@ -16,7 +16,7 @@ impl ast::Expr {
16 | ast::Expr::WhileExpr(_) 16 | ast::Expr::WhileExpr(_)
17 | ast::Expr::BlockExpr(_) 17 | ast::Expr::BlockExpr(_)
18 | ast::Expr::MatchExpr(_) 18 | ast::Expr::MatchExpr(_)
19 | ast::Expr::TryBlockExpr(_) => true, 19 | ast::Expr::EffectExpr(_) => true,
20 _ => false, 20 _ => false,
21 } 21 }
22 } 22 }
@@ -359,6 +359,33 @@ impl ast::Literal {
359 } 359 }
360} 360}
361 361
362#[derive(Debug, Clone, PartialEq, Eq)]
363pub enum Effect {
364 Async(SyntaxToken),
365 Unsafe(SyntaxToken),
366 Try(SyntaxToken),
367 // Very much not an effect, but we stuff it into this node anyway
368 Label(ast::Label),
369}
370
371impl ast::EffectExpr {
372 pub fn effect(&self) -> Effect {
373 if let Some(token) = self.async_token() {
374 return Effect::Async(token);
375 }
376 if let Some(token) = self.unsafe_token() {
377 return Effect::Unsafe(token);
378 }
379 if let Some(token) = self.try_token() {
380 return Effect::Try(token);
381 }
382 if let Some(label) = self.label() {
383 return Effect::Label(label);
384 }
385 unreachable!("ast::EffectExpr without Effect")
386 }
387}
388
362impl ast::BlockExpr { 389impl ast::BlockExpr {
363 /// false if the block is an intrinsic part of the syntax and can't be 390 /// false if the block is an intrinsic part of the syntax and can't be
364 /// replaced with arbitrary expression. 391 /// replaced with arbitrary expression.
@@ -368,15 +395,12 @@ impl ast::BlockExpr {
368 /// const FOO: () = { stand_alone }; 395 /// const FOO: () = { stand_alone };
369 /// ``` 396 /// ```
370 pub fn is_standalone(&self) -> bool { 397 pub fn is_standalone(&self) -> bool {
371 if self.unsafe_token().is_some() || self.async_token().is_some() { 398 let parent = match self.syntax().parent() {
372 return false; 399 Some(it) => it,
373 }
374 let kind = match self.syntax().parent() {
375 None => return true, 400 None => return true,
376 Some(it) => it.kind(),
377 }; 401 };
378 match kind { 402 match parent.kind() {
379 FN_DEF | IF_EXPR | WHILE_EXPR | LOOP_EXPR | TRY_BLOCK_EXPR => false, 403 FN_DEF | IF_EXPR | WHILE_EXPR | LOOP_EXPR | EFFECT_EXPR => false,
380 _ => true, 404 _ => true,
381 } 405 }
382 } 406 }
diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs
index 2096f12f1..5e844d5ae 100644
--- a/crates/ra_syntax/src/ast/generated/nodes.rs
+++ b/crates/ra_syntax/src/ast/generated/nodes.rs
@@ -476,13 +476,16 @@ impl LoopExpr {
476} 476}
477 477
478#[derive(Debug, Clone, PartialEq, Eq, Hash)] 478#[derive(Debug, Clone, PartialEq, Eq, Hash)]
479pub struct TryBlockExpr { 479pub struct EffectExpr {
480 pub(crate) syntax: SyntaxNode, 480 pub(crate) syntax: SyntaxNode,
481} 481}
482impl ast::AttrsOwner for TryBlockExpr {} 482impl ast::AttrsOwner for EffectExpr {}
483impl TryBlockExpr { 483impl EffectExpr {
484 pub fn label(&self) -> Option<Label> { support::child(&self.syntax) }
484 pub fn try_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![try]) } 485 pub fn try_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![try]) }
485 pub fn body(&self) -> Option<BlockExpr> { support::child(&self.syntax) } 486 pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) }
487 pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) }
488 pub fn block_expr(&self) -> Option<BlockExpr> { support::child(&self.syntax) }
486} 489}
487 490
488#[derive(Debug, Clone, PartialEq, Eq, Hash)] 491#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -551,11 +554,12 @@ pub struct BlockExpr {
551 pub(crate) syntax: SyntaxNode, 554 pub(crate) syntax: SyntaxNode,
552} 555}
553impl ast::AttrsOwner for BlockExpr {} 556impl ast::AttrsOwner for BlockExpr {}
557impl ast::ModuleItemOwner for BlockExpr {}
554impl BlockExpr { 558impl BlockExpr {
555 pub fn label(&self) -> Option<Label> { support::child(&self.syntax) } 559 pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
556 pub fn unsafe_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![unsafe]) } 560 pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) }
557 pub fn async_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![async]) } 561 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
558 pub fn block(&self) -> Option<Block> { support::child(&self.syntax) } 562 pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
559} 563}
560 564
561#[derive(Debug, Clone, PartialEq, Eq, Hash)] 565#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -627,8 +631,8 @@ pub struct TryExpr {
627} 631}
628impl ast::AttrsOwner for TryExpr {} 632impl ast::AttrsOwner for TryExpr {}
629impl TryExpr { 633impl TryExpr {
630 pub fn try_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![try]) }
631 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } 634 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
635 pub fn question_mark_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![?]) }
632} 636}
633 637
634#[derive(Debug, Clone, PartialEq, Eq, Hash)] 638#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1122,19 +1126,6 @@ impl Condition {
1122} 1126}
1123 1127
1124#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1128#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1125pub struct Block {
1126 pub(crate) syntax: SyntaxNode,
1127}
1128impl ast::AttrsOwner for Block {}
1129impl ast::ModuleItemOwner for Block {}
1130impl Block {
1131 pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) }
1132 pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) }
1133 pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
1134 pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) }
1135}
1136
1137#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1138pub struct ParamList { 1129pub struct ParamList {
1139 pub(crate) syntax: SyntaxNode, 1130 pub(crate) syntax: SyntaxNode,
1140} 1131}
@@ -1477,7 +1468,7 @@ pub enum Expr {
1477 FieldExpr(FieldExpr), 1468 FieldExpr(FieldExpr),
1478 AwaitExpr(AwaitExpr), 1469 AwaitExpr(AwaitExpr),
1479 TryExpr(TryExpr), 1470 TryExpr(TryExpr),
1480 TryBlockExpr(TryBlockExpr), 1471 EffectExpr(EffectExpr),
1481 CastExpr(CastExpr), 1472 CastExpr(CastExpr),
1482 RefExpr(RefExpr), 1473 RefExpr(RefExpr),
1483 PrefixExpr(PrefixExpr), 1474 PrefixExpr(PrefixExpr),
@@ -1960,8 +1951,8 @@ impl AstNode for LoopExpr {
1960 } 1951 }
1961 fn syntax(&self) -> &SyntaxNode { &self.syntax } 1952 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1962} 1953}
1963impl AstNode for TryBlockExpr { 1954impl AstNode for EffectExpr {
1964 fn can_cast(kind: SyntaxKind) -> bool { kind == TRY_BLOCK_EXPR } 1955 fn can_cast(kind: SyntaxKind) -> bool { kind == EFFECT_EXPR }
1965 fn cast(syntax: SyntaxNode) -> Option<Self> { 1956 fn cast(syntax: SyntaxNode) -> Option<Self> {
1966 if Self::can_cast(syntax.kind()) { 1957 if Self::can_cast(syntax.kind()) {
1967 Some(Self { syntax }) 1958 Some(Self { syntax })
@@ -2653,17 +2644,6 @@ impl AstNode for Condition {
2653 } 2644 }
2654 fn syntax(&self) -> &SyntaxNode { &self.syntax } 2645 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2655} 2646}
2656impl AstNode for Block {
2657 fn can_cast(kind: SyntaxKind) -> bool { kind == BLOCK }
2658 fn cast(syntax: SyntaxNode) -> Option<Self> {
2659 if Self::can_cast(syntax.kind()) {
2660 Some(Self { syntax })
2661 } else {
2662 None
2663 }
2664 }
2665 fn syntax(&self) -> &SyntaxNode { &self.syntax }
2666}
2667impl AstNode for ParamList { 2647impl AstNode for ParamList {
2668 fn can_cast(kind: SyntaxKind) -> bool { kind == PARAM_LIST } 2648 fn can_cast(kind: SyntaxKind) -> bool { kind == PARAM_LIST }
2669 fn cast(syntax: SyntaxNode) -> Option<Self> { 2649 fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3312,8 +3292,8 @@ impl From<AwaitExpr> for Expr {
3312impl From<TryExpr> for Expr { 3292impl From<TryExpr> for Expr {
3313 fn from(node: TryExpr) -> Expr { Expr::TryExpr(node) } 3293 fn from(node: TryExpr) -> Expr { Expr::TryExpr(node) }
3314} 3294}
3315impl From<TryBlockExpr> for Expr { 3295impl From<EffectExpr> for Expr {
3316 fn from(node: TryBlockExpr) -> Expr { Expr::TryBlockExpr(node) } 3296 fn from(node: EffectExpr) -> Expr { Expr::EffectExpr(node) }
3317} 3297}
3318impl From<CastExpr> for Expr { 3298impl From<CastExpr> for Expr {
3319 fn from(node: CastExpr) -> Expr { Expr::CastExpr(node) } 3299 fn from(node: CastExpr) -> Expr { Expr::CastExpr(node) }
@@ -3345,9 +3325,10 @@ impl AstNode for Expr {
3345 TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR 3325 TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR
3346 | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL 3326 | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL
3347 | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | RECORD_LIT | CALL_EXPR | INDEX_EXPR 3327 | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | RECORD_LIT | CALL_EXPR | INDEX_EXPR
3348 | METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | TRY_BLOCK_EXPR 3328 | METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | EFFECT_EXPR | CAST_EXPR
3349 | CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL 3329 | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL | BOX_EXPR => {
3350 | BOX_EXPR => true, 3330 true
3331 }
3351 _ => false, 3332 _ => false,
3352 } 3333 }
3353 } 3334 }
@@ -3375,7 +3356,7 @@ impl AstNode for Expr {
3375 FIELD_EXPR => Expr::FieldExpr(FieldExpr { syntax }), 3356 FIELD_EXPR => Expr::FieldExpr(FieldExpr { syntax }),
3376 AWAIT_EXPR => Expr::AwaitExpr(AwaitExpr { syntax }), 3357 AWAIT_EXPR => Expr::AwaitExpr(AwaitExpr { syntax }),
3377 TRY_EXPR => Expr::TryExpr(TryExpr { syntax }), 3358 TRY_EXPR => Expr::TryExpr(TryExpr { syntax }),
3378 TRY_BLOCK_EXPR => Expr::TryBlockExpr(TryBlockExpr { syntax }), 3359 EFFECT_EXPR => Expr::EffectExpr(EffectExpr { syntax }),
3379 CAST_EXPR => Expr::CastExpr(CastExpr { syntax }), 3360 CAST_EXPR => Expr::CastExpr(CastExpr { syntax }),
3380 REF_EXPR => Expr::RefExpr(RefExpr { syntax }), 3361 REF_EXPR => Expr::RefExpr(RefExpr { syntax }),
3381 PREFIX_EXPR => Expr::PrefixExpr(PrefixExpr { syntax }), 3362 PREFIX_EXPR => Expr::PrefixExpr(PrefixExpr { syntax }),
@@ -3412,7 +3393,7 @@ impl AstNode for Expr {
3412 Expr::FieldExpr(it) => &it.syntax, 3393 Expr::FieldExpr(it) => &it.syntax,
3413 Expr::AwaitExpr(it) => &it.syntax, 3394 Expr::AwaitExpr(it) => &it.syntax,
3414 Expr::TryExpr(it) => &it.syntax, 3395 Expr::TryExpr(it) => &it.syntax,
3415 Expr::TryBlockExpr(it) => &it.syntax, 3396 Expr::EffectExpr(it) => &it.syntax,
3416 Expr::CastExpr(it) => &it.syntax, 3397 Expr::CastExpr(it) => &it.syntax,
3417 Expr::RefExpr(it) => &it.syntax, 3398 Expr::RefExpr(it) => &it.syntax,
3418 Expr::PrefixExpr(it) => &it.syntax, 3399 Expr::PrefixExpr(it) => &it.syntax,
@@ -3893,7 +3874,7 @@ impl std::fmt::Display for LoopExpr {
3893 std::fmt::Display::fmt(self.syntax(), f) 3874 std::fmt::Display::fmt(self.syntax(), f)
3894 } 3875 }
3895} 3876}
3896impl std::fmt::Display for TryBlockExpr { 3877impl std::fmt::Display for EffectExpr {
3897 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 3878 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
3898 std::fmt::Display::fmt(self.syntax(), f) 3879 std::fmt::Display::fmt(self.syntax(), f)
3899 } 3880 }
@@ -4208,11 +4189,6 @@ impl std::fmt::Display for Condition {
4208 std::fmt::Display::fmt(self.syntax(), f) 4189 std::fmt::Display::fmt(self.syntax(), f)
4209 } 4190 }
4210} 4191}
4211impl std::fmt::Display for Block {
4212 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
4213 std::fmt::Display::fmt(self.syntax(), f)
4214 }
4215}
4216impl std::fmt::Display for ParamList { 4192impl std::fmt::Display for ParamList {
4217 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 4193 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
4218 std::fmt::Display::fmt(self.syntax(), f) 4194 std::fmt::Display::fmt(self.syntax(), f)
diff --git a/crates/ra_syntax/src/ast/make.rs b/crates/ra_syntax/src/ast/make.rs
index 492088353..b9a396cad 100644
--- a/crates/ra_syntax/src/ast/make.rs
+++ b/crates/ra_syntax/src/ast/make.rs
@@ -82,10 +82,10 @@ pub fn block_expr(
82 ast_from_text(&format!("fn f() {}", buf)) 82 ast_from_text(&format!("fn f() {}", buf))
83} 83}
84 84
85pub fn block_from_expr(e: ast::Expr) -> ast::Block { 85pub fn block_from_expr(e: ast::Expr) -> ast::BlockExpr {
86 return from_text(&format!("{{ {} }}", e)); 86 return from_text(&format!("{{ {} }}", e));
87 87
88 fn from_text(text: &str) -> ast::Block { 88 fn from_text(text: &str) -> ast::BlockExpr {
89 ast_from_text(&format!("fn f() {}", text)) 89 ast_from_text(&format!("fn f() {}", text))
90 } 90 }
91} 91}
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index ceeb2bde9..d0234cada 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -237,8 +237,7 @@ fn api_walkthrough() {
237 237
238 // Let's get the `1 + 1` expression! 238 // Let's get the `1 + 1` expression!
239 let body: ast::BlockExpr = func.body().unwrap(); 239 let body: ast::BlockExpr = func.body().unwrap();
240 let block = body.block().unwrap(); 240 let expr: ast::Expr = body.expr().unwrap();
241 let expr: ast::Expr = block.expr().unwrap();
242 241
243 // Enums are used to group related ast nodes together, and can be used for 242 // Enums are used to group related ast nodes together, and can be used for
244 // matching. However, because there are no public fields, it's possible to 243 // matching. However, because there are no public fields, it's possible to
@@ -274,8 +273,8 @@ fn api_walkthrough() {
274 assert_eq!(text.to_string(), "1 + 1"); 273 assert_eq!(text.to_string(), "1 + 1");
275 274
276 // There's a bunch of traversal methods on `SyntaxNode`: 275 // There's a bunch of traversal methods on `SyntaxNode`:
277 assert_eq!(expr_syntax.parent().as_ref(), Some(block.syntax())); 276 assert_eq!(expr_syntax.parent().as_ref(), Some(body.syntax()));
278 assert_eq!(block.syntax().first_child_or_token().map(|it| it.kind()), Some(T!['{'])); 277 assert_eq!(body.syntax().first_child_or_token().map(|it| it.kind()), Some(T!['{']));
279 assert_eq!( 278 assert_eq!(
280 expr_syntax.next_sibling_or_token().map(|it| it.kind()), 279 expr_syntax.next_sibling_or_token().map(|it| it.kind()),
281 Some(SyntaxKind::WHITESPACE) 280 Some(SyntaxKind::WHITESPACE)
diff --git a/crates/ra_syntax/src/validation/block.rs b/crates/ra_syntax/src/validation/block.rs
index 8e962ab5b..2c08f7e6e 100644
--- a/crates/ra_syntax/src/validation/block.rs
+++ b/crates/ra_syntax/src/validation/block.rs
@@ -6,19 +6,17 @@ use crate::{
6 SyntaxKind::*, 6 SyntaxKind::*,
7}; 7};
8 8
9pub(crate) fn validate_block_expr(expr: ast::BlockExpr, errors: &mut Vec<SyntaxError>) { 9pub(crate) fn validate_block_expr(block: ast::BlockExpr, errors: &mut Vec<SyntaxError>) {
10 if let Some(parent) = expr.syntax().parent() { 10 if let Some(parent) = block.syntax().parent() {
11 match parent.kind() { 11 match parent.kind() {
12 FN_DEF | EXPR_STMT | BLOCK => return, 12 FN_DEF | EXPR_STMT | BLOCK_EXPR => return,
13 _ => {} 13 _ => {}
14 } 14 }
15 } 15 }
16 if let Some(block) = expr.block() { 16 errors.extend(block.attrs().map(|attr| {
17 errors.extend(block.attrs().map(|attr| { 17 SyntaxError::new(
18 SyntaxError::new( 18 "A block in this position cannot accept inner attributes",
19 "A block in this position cannot accept inner attributes", 19 attr.syntax().text_range(),
20 attr.syntax().text_range(), 20 )
21 ) 21 }))
22 }))
23 }
24} 22}
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index 1abb62f6f..028f7cbe1 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -162,7 +162,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
162 "RECORD_LIT", 162 "RECORD_LIT",
163 "RECORD_FIELD_LIST", 163 "RECORD_FIELD_LIST",
164 "RECORD_FIELD", 164 "RECORD_FIELD",
165 "TRY_BLOCK_EXPR", 165 "EFFECT_EXPR",
166 "BOX_EXPR", 166 "BOX_EXPR",
167 // postfix 167 // postfix
168 "CALL_EXPR", 168 "CALL_EXPR",
@@ -177,7 +177,6 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
177 "PREFIX_EXPR", 177 "PREFIX_EXPR",
178 "RANGE_EXPR", // just weird 178 "RANGE_EXPR", // just weird
179 "BIN_EXPR", 179 "BIN_EXPR",
180 "BLOCK",
181 "EXTERN_BLOCK", 180 "EXTERN_BLOCK",
182 "EXTERN_ITEM_LIST", 181 "EXTERN_ITEM_LIST",
183 "ENUM_VARIANT", 182 "ENUM_VARIANT",
@@ -440,7 +439,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
440 } 439 }
441 struct IfExpr: AttrsOwner { T![if], Condition } 440 struct IfExpr: AttrsOwner { T![if], Condition }
442 struct LoopExpr: AttrsOwner, LoopBodyOwner { T![loop] } 441 struct LoopExpr: AttrsOwner, LoopBodyOwner { T![loop] }
443 struct TryBlockExpr: AttrsOwner { T![try], body: BlockExpr } 442 struct EffectExpr: AttrsOwner { Label, T![try], T![unsafe], T![async], BlockExpr }
444 struct ForExpr: AttrsOwner, LoopBodyOwner { 443 struct ForExpr: AttrsOwner, LoopBodyOwner {
445 T![for], 444 T![for],
446 Pat, 445 Pat,
@@ -451,7 +450,9 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
451 struct ContinueExpr: AttrsOwner { T![continue], T![lifetime] } 450 struct ContinueExpr: AttrsOwner { T![continue], T![lifetime] }
452 struct BreakExpr: AttrsOwner { T![break], T![lifetime], Expr } 451 struct BreakExpr: AttrsOwner { T![break], T![lifetime], Expr }
453 struct Label { T![lifetime] } 452 struct Label { T![lifetime] }
454 struct BlockExpr: AttrsOwner { Label, T![unsafe], T![async], Block } 453 struct BlockExpr: AttrsOwner, ModuleItemOwner {
454 T!['{'], statements: [Stmt], Expr, T!['}'],
455 }
455 struct ReturnExpr: AttrsOwner { Expr } 456 struct ReturnExpr: AttrsOwner { Expr }
456 struct CallExpr: ArgListOwner { Expr } 457 struct CallExpr: ArgListOwner { Expr }
457 struct MethodCallExpr: AttrsOwner, ArgListOwner { 458 struct MethodCallExpr: AttrsOwner, ArgListOwner {
@@ -460,7 +461,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
460 struct IndexExpr: AttrsOwner { T!['['], T![']'] } 461 struct IndexExpr: AttrsOwner { T!['['], T![']'] }
461 struct FieldExpr: AttrsOwner { Expr, T![.], NameRef } 462 struct FieldExpr: AttrsOwner { Expr, T![.], NameRef }
462 struct AwaitExpr: AttrsOwner { Expr, T![.], T![await] } 463 struct AwaitExpr: AttrsOwner { Expr, T![.], T![await] }
463 struct TryExpr: AttrsOwner { T![try], Expr } 464 struct TryExpr: AttrsOwner { Expr, T![?] }
464 struct CastExpr: AttrsOwner { Expr, T![as], TypeRef } 465 struct CastExpr: AttrsOwner { Expr, T![as], TypeRef }
465 struct RefExpr: AttrsOwner { T![&], T![raw], T![mut], Expr } 466 struct RefExpr: AttrsOwner { T![&], T![raw], T![mut], Expr }
466 struct PrefixExpr: AttrsOwner { /*PrefixOp,*/ Expr } 467 struct PrefixExpr: AttrsOwner { /*PrefixOp,*/ Expr }
@@ -556,12 +557,6 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
556 T![;], 557 T![;],
557 } 558 }
558 struct Condition { T![let], Pat, T![=], Expr } 559 struct Condition { T![let], Pat, T![=], Expr }
559 struct Block: AttrsOwner, ModuleItemOwner {
560 T!['{'],
561 statements: [Stmt],
562 Expr,
563 T!['}'],
564 }
565 struct ParamList { 560 struct ParamList {
566 T!['('], 561 T!['('],
567 SelfParam, 562 SelfParam,
@@ -722,7 +717,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
722 FieldExpr, 717 FieldExpr,
723 AwaitExpr, 718 AwaitExpr,
724 TryExpr, 719 TryExpr,
725 TryBlockExpr, 720 EffectExpr,
726 CastExpr, 721 CastExpr,
727 RefExpr, 722 RefExpr,
728 PrefixExpr, 723 PrefixExpr,
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index e9dc09552..8028575c5 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -432,6 +432,7 @@ impl Field<'_> {
432 ":" => "colon", 432 ":" => "colon",
433 "::" => "coloncolon", 433 "::" => "coloncolon",
434 "#" => "pound", 434 "#" => "pound",
435 "?" => "question_mark",
435 _ => name, 436 _ => name,
436 }; 437 };
437 format_ident!("{}_token", name) 438 format_ident!("{}_token", name)