aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir_def/src/body/lower.rs4
-rw-r--r--crates/ra_hir_def/src/expr.rs4
-rw-r--r--crates/ra_hir_ty/src/infer/expr.rs5
-rw-r--r--crates/ra_parser/src/grammar/expressions/atom.rs6
-rw-r--r--crates/ra_parser/src/syntax_kind/generated.rs1
-rw-r--r--crates/ra_syntax/src/ast.rs4
-rw-r--r--crates/ra_syntax/src/ast/expr_extensions.rs27
-rw-r--r--crates/ra_syntax/src/ast/generated/nodes.rs37
-rw-r--r--xtask/src/ast_src.rs5
9 files changed, 63 insertions, 30 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index e9dd65b0a..f06cc115b 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -203,6 +203,10 @@ 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) => {
207 let body = self.collect_block_opt(e.body());
208 self.alloc_expr(Expr::TryBlock { body }, syntax_ptr)
209 }
206 ast::Expr::BlockExpr(e) => self.collect_block(e), 210 ast::Expr::BlockExpr(e) => self.collect_block(e),
207 ast::Expr::LoopExpr(e) => { 211 ast::Expr::LoopExpr(e) => {
208 let body = self.collect_block_opt(e.loop_body()); 212 let body = self.collect_block_opt(e.loop_body());
diff --git a/crates/ra_hir_def/src/expr.rs b/crates/ra_hir_def/src/expr.rs
index aad12e123..a0cdad529 100644
--- a/crates/ra_hir_def/src/expr.rs
+++ b/crates/ra_hir_def/src/expr.rs
@@ -101,6 +101,9 @@ pub enum Expr {
101 Try { 101 Try {
102 expr: ExprId, 102 expr: ExprId,
103 }, 103 },
104 TryBlock {
105 body: ExprId,
106 },
104 Cast { 107 Cast {
105 expr: ExprId, 108 expr: ExprId,
106 type_ref: TypeRef, 109 type_ref: TypeRef,
@@ -236,6 +239,7 @@ impl Expr {
236 f(*expr); 239 f(*expr);
237 } 240 }
238 } 241 }
242 Expr::TryBlock { body } => f(*body),
239 Expr::Loop { body } => f(*body), 243 Expr::Loop { body } => f(*body),
240 Expr::While { condition, body } => { 244 Expr::While { condition, body } => {
241 f(*condition); 245 f(*condition);
diff --git a/crates/ra_hir_ty/src/infer/expr.rs b/crates/ra_hir_ty/src/infer/expr.rs
index efc60986b..83f946eee 100644
--- a/crates/ra_hir_ty/src/infer/expr.rs
+++ b/crates/ra_hir_ty/src/infer/expr.rs
@@ -73,6 +73,11 @@ impl<'a> InferenceContext<'a> {
73 self.coerce_merge_branch(&then_ty, &else_ty) 73 self.coerce_merge_branch(&then_ty, &else_ty)
74 } 74 }
75 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), 75 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected),
76 Expr::TryBlock { body } => {
77 let _inner = self.infer_expr(*body, expected);
78 // FIXME should be std::result::Result<{inner}, _>
79 Ty::Unknown
80 }
76 Expr::Loop { body } => { 81 Expr::Loop { body } => {
77 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 82 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
78 // FIXME handle break with value 83 // FIXME handle break with value
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs
index 76aa601cb..166dfc472 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);
@@ -134,7 +134,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
134 } 134 }
135 }; 135 };
136 let blocklike = match done.kind() { 136 let blocklike = match done.kind() {
137 IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | TRY_EXPR => { 137 IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | TRY_BLOCK_EXPR => {
138 BlockLike::Block 138 BlockLike::Block
139 } 139 }
140 _ => BlockLike::NotBlock, 140 _ => BlockLike::NotBlock,
@@ -532,7 +532,7 @@ fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
532// fn foo() { 532// fn foo() {
533// let _ = try {}; 533// let _ = try {};
534// } 534// }
535fn try_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { 535fn try_block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
536 assert!(p.at(T![try])); 536 assert!(p.at(T![try]));
537 let m = m.unwrap_or_else(|| p.start()); 537 let m = m.unwrap_or_else(|| p.start());
538 // Special-case `try!` as macro. 538 // Special-case `try!` as macro.
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs
index ab727ed7e..524e7d784 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 TRY_BLOCK_EXPR,
194 BOX_EXPR, 195 BOX_EXPR,
195 CALL_EXPR, 196 CALL_EXPR,
196 INDEX_EXPR, 197 INDEX_EXPR,
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 521ca8ab8..a716e525b 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -16,9 +16,7 @@ use crate::{
16}; 16};
17 17
18pub use self::{ 18pub use self::{
19 expr_extensions::{ 19 expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp, RangeOp},
20 ArrayExprKind, BinOp, BlockModifier, ElseBranch, LiteralKind, PrefixOp, RangeOp,
21 },
22 extensions::{ 20 extensions::{
23 AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents, 21 AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents,
24 StructKind, TypeBoundKind, VisibilityKind, 22 StructKind, TypeBoundKind, VisibilityKind,
diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs
index 352c0d2c5..ecf74fd36 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::TryExpr(_) => true, 19 | ast::Expr::TryBlockExpr(_) => true,
20 _ => false, 20 _ => false,
21 } 21 }
22 } 22 }
@@ -359,22 +359,7 @@ impl ast::Literal {
359 } 359 }
360} 360}
361 361
362pub enum BlockModifier {
363 Async(SyntaxToken),
364 Unsafe(SyntaxToken),
365}
366
367impl ast::BlockExpr { 362impl ast::BlockExpr {
368 pub fn modifier(&self) -> Option<BlockModifier> {
369 if let Some(token) = self.async_token() {
370 return Some(BlockModifier::Async(token));
371 }
372 if let Some(token) = self.unsafe_token() {
373 return Some(BlockModifier::Unsafe(token));
374 }
375 None
376 }
377
378 /// false if the block is an intrinsic part of the syntax and can't be 363 /// false if the block is an intrinsic part of the syntax and can't be
379 /// replaced with arbitrary expression. 364 /// replaced with arbitrary expression.
380 /// 365 ///
@@ -383,15 +368,15 @@ impl ast::BlockExpr {
383 /// const FOO: () = { stand_alone }; 368 /// const FOO: () = { stand_alone };
384 /// ``` 369 /// ```
385 pub fn is_standalone(&self) -> bool { 370 pub fn is_standalone(&self) -> bool {
386 if self.modifier().is_some() { 371 if self.unsafe_token().is_some() || self.async_token().is_some() {
387 return false; 372 return false;
388 } 373 }
389 let parent = match self.syntax().parent() { 374 let kind = match self.syntax().parent() {
390 Some(it) => it,
391 None => return true, 375 None => return true,
376 Some(it) => it.kind(),
392 }; 377 };
393 match parent.kind() { 378 match kind {
394 FN_DEF | IF_EXPR | WHILE_EXPR | LOOP_EXPR => false, 379 FN_DEF | IF_EXPR | WHILE_EXPR | LOOP_EXPR | TRY_BLOCK_EXPR => false,
395 _ => true, 380 _ => true,
396 } 381 }
397 } 382 }
diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs
index 3f16592b6..2096f12f1 100644
--- a/crates/ra_syntax/src/ast/generated/nodes.rs
+++ b/crates/ra_syntax/src/ast/generated/nodes.rs
@@ -476,6 +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 {
480 pub(crate) syntax: SyntaxNode,
481}
482impl ast::AttrsOwner for TryBlockExpr {}
483impl TryBlockExpr {
484 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}
487
488#[derive(Debug, Clone, PartialEq, Eq, Hash)]
479pub struct ForExpr { 489pub struct ForExpr {
480 pub(crate) syntax: SyntaxNode, 490 pub(crate) syntax: SyntaxNode,
481} 491}
@@ -1467,6 +1477,7 @@ pub enum Expr {
1467 FieldExpr(FieldExpr), 1477 FieldExpr(FieldExpr),
1468 AwaitExpr(AwaitExpr), 1478 AwaitExpr(AwaitExpr),
1469 TryExpr(TryExpr), 1479 TryExpr(TryExpr),
1480 TryBlockExpr(TryBlockExpr),
1470 CastExpr(CastExpr), 1481 CastExpr(CastExpr),
1471 RefExpr(RefExpr), 1482 RefExpr(RefExpr),
1472 PrefixExpr(PrefixExpr), 1483 PrefixExpr(PrefixExpr),
@@ -1949,6 +1960,17 @@ impl AstNode for LoopExpr {
1949 } 1960 }
1950 fn syntax(&self) -> &SyntaxNode { &self.syntax } 1961 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1951} 1962}
1963impl AstNode for TryBlockExpr {
1964 fn can_cast(kind: SyntaxKind) -> bool { kind == TRY_BLOCK_EXPR }
1965 fn cast(syntax: SyntaxNode) -> Option<Self> {
1966 if Self::can_cast(syntax.kind()) {
1967 Some(Self { syntax })
1968 } else {
1969 None
1970 }
1971 }
1972 fn syntax(&self) -> &SyntaxNode { &self.syntax }
1973}
1952impl AstNode for ForExpr { 1974impl AstNode for ForExpr {
1953 fn can_cast(kind: SyntaxKind) -> bool { kind == FOR_EXPR } 1975 fn can_cast(kind: SyntaxKind) -> bool { kind == FOR_EXPR }
1954 fn cast(syntax: SyntaxNode) -> Option<Self> { 1976 fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3290,6 +3312,9 @@ impl From<AwaitExpr> for Expr {
3290impl From<TryExpr> for Expr { 3312impl From<TryExpr> for Expr {
3291 fn from(node: TryExpr) -> Expr { Expr::TryExpr(node) } 3313 fn from(node: TryExpr) -> Expr { Expr::TryExpr(node) }
3292} 3314}
3315impl From<TryBlockExpr> for Expr {
3316 fn from(node: TryBlockExpr) -> Expr { Expr::TryBlockExpr(node) }
3317}
3293impl From<CastExpr> for Expr { 3318impl From<CastExpr> for Expr {
3294 fn from(node: CastExpr) -> Expr { Expr::CastExpr(node) } 3319 fn from(node: CastExpr) -> Expr { Expr::CastExpr(node) }
3295} 3320}
@@ -3320,8 +3345,9 @@ impl AstNode for Expr {
3320 TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR 3345 TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR
3321 | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL 3346 | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL
3322 | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | RECORD_LIT | CALL_EXPR | INDEX_EXPR 3347 | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | RECORD_LIT | CALL_EXPR | INDEX_EXPR
3323 | METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | CAST_EXPR | REF_EXPR 3348 | METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | TRY_BLOCK_EXPR
3324 | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL | BOX_EXPR => true, 3349 | CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL
3350 | BOX_EXPR => true,
3325 _ => false, 3351 _ => false,
3326 } 3352 }
3327 } 3353 }
@@ -3349,6 +3375,7 @@ impl AstNode for Expr {
3349 FIELD_EXPR => Expr::FieldExpr(FieldExpr { syntax }), 3375 FIELD_EXPR => Expr::FieldExpr(FieldExpr { syntax }),
3350 AWAIT_EXPR => Expr::AwaitExpr(AwaitExpr { syntax }), 3376 AWAIT_EXPR => Expr::AwaitExpr(AwaitExpr { syntax }),
3351 TRY_EXPR => Expr::TryExpr(TryExpr { syntax }), 3377 TRY_EXPR => Expr::TryExpr(TryExpr { syntax }),
3378 TRY_BLOCK_EXPR => Expr::TryBlockExpr(TryBlockExpr { syntax }),
3352 CAST_EXPR => Expr::CastExpr(CastExpr { syntax }), 3379 CAST_EXPR => Expr::CastExpr(CastExpr { syntax }),
3353 REF_EXPR => Expr::RefExpr(RefExpr { syntax }), 3380 REF_EXPR => Expr::RefExpr(RefExpr { syntax }),
3354 PREFIX_EXPR => Expr::PrefixExpr(PrefixExpr { syntax }), 3381 PREFIX_EXPR => Expr::PrefixExpr(PrefixExpr { syntax }),
@@ -3385,6 +3412,7 @@ impl AstNode for Expr {
3385 Expr::FieldExpr(it) => &it.syntax, 3412 Expr::FieldExpr(it) => &it.syntax,
3386 Expr::AwaitExpr(it) => &it.syntax, 3413 Expr::AwaitExpr(it) => &it.syntax,
3387 Expr::TryExpr(it) => &it.syntax, 3414 Expr::TryExpr(it) => &it.syntax,
3415 Expr::TryBlockExpr(it) => &it.syntax,
3388 Expr::CastExpr(it) => &it.syntax, 3416 Expr::CastExpr(it) => &it.syntax,
3389 Expr::RefExpr(it) => &it.syntax, 3417 Expr::RefExpr(it) => &it.syntax,
3390 Expr::PrefixExpr(it) => &it.syntax, 3418 Expr::PrefixExpr(it) => &it.syntax,
@@ -3865,6 +3893,11 @@ impl std::fmt::Display for LoopExpr {
3865 std::fmt::Display::fmt(self.syntax(), f) 3893 std::fmt::Display::fmt(self.syntax(), f)
3866 } 3894 }
3867} 3895}
3896impl std::fmt::Display for TryBlockExpr {
3897 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
3898 std::fmt::Display::fmt(self.syntax(), f)
3899 }
3900}
3868impl std::fmt::Display for ForExpr { 3901impl std::fmt::Display for ForExpr {
3869 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 3902 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
3870 std::fmt::Display::fmt(self.syntax(), f) 3903 std::fmt::Display::fmt(self.syntax(), f)
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index 703fb9be9..1abb62f6f 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -162,6 +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 "BOX_EXPR", 166 "BOX_EXPR",
166 // postfix 167 // postfix
167 "CALL_EXPR", 168 "CALL_EXPR",
@@ -439,6 +440,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
439 } 440 }
440 struct IfExpr: AttrsOwner { T![if], Condition } 441 struct IfExpr: AttrsOwner { T![if], Condition }
441 struct LoopExpr: AttrsOwner, LoopBodyOwner { T![loop] } 442 struct LoopExpr: AttrsOwner, LoopBodyOwner { T![loop] }
443 struct TryBlockExpr: AttrsOwner { T![try], body: BlockExpr }
442 struct ForExpr: AttrsOwner, LoopBodyOwner { 444 struct ForExpr: AttrsOwner, LoopBodyOwner {
443 T![for], 445 T![for],
444 Pat, 446 Pat,
@@ -449,7 +451,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
449 struct ContinueExpr: AttrsOwner { T![continue], T![lifetime] } 451 struct ContinueExpr: AttrsOwner { T![continue], T![lifetime] }
450 struct BreakExpr: AttrsOwner { T![break], T![lifetime], Expr } 452 struct BreakExpr: AttrsOwner { T![break], T![lifetime], Expr }
451 struct Label { T![lifetime] } 453 struct Label { T![lifetime] }
452 struct BlockExpr: AttrsOwner { Label, T![unsafe], T![async], Block } 454 struct BlockExpr: AttrsOwner { Label, T![unsafe], T![async], Block }
453 struct ReturnExpr: AttrsOwner { Expr } 455 struct ReturnExpr: AttrsOwner { Expr }
454 struct CallExpr: ArgListOwner { Expr } 456 struct CallExpr: ArgListOwner { Expr }
455 struct MethodCallExpr: AttrsOwner, ArgListOwner { 457 struct MethodCallExpr: AttrsOwner, ArgListOwner {
@@ -720,6 +722,7 @@ pub(crate) const AST_SRC: AstSrc = AstSrc {
720 FieldExpr, 722 FieldExpr,
721 AwaitExpr, 723 AwaitExpr,
722 TryExpr, 724 TryExpr,
725 TryBlockExpr,
723 CastExpr, 726 CastExpr,
724 RefExpr, 727 RefExpr,
725 PrefixExpr, 728 PrefixExpr,