aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/expr.rs10
-rw-r--r--crates/ra_hir/src/ty/infer.rs5
-rw-r--r--crates/ra_parser/src/grammar/expressions/atom.rs18
-rw-r--r--crates/ra_parser/src/syntax_kind/generated.rs7
-rw-r--r--crates/ra_syntax/src/ast/generated.rs37
-rw-r--r--crates/ra_syntax/src/ast/traits.rs6
-rw-r--r--crates/ra_syntax/src/grammar.ron6
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0130_try_block_expr.rs3
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0130_try_block_expr.txt31
9 files changed, 121 insertions, 2 deletions
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs
index 51913d37b..9d9769859 100644
--- a/crates/ra_hir/src/expr.rs
+++ b/crates/ra_hir/src/expr.rs
@@ -6,7 +6,7 @@ use rustc_hash::FxHashMap;
6use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; 6use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap};
7use ra_syntax::{ 7use ra_syntax::{
8 SyntaxNodePtr, AstPtr, AstNode, 8 SyntaxNodePtr, AstPtr, AstNode,
9 ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralKind,ArrayExprKind, TypeAscriptionOwner}, 9 ast::{self, TryBlockBodyOwner, LoopBodyOwner, ArgListOwner, NameOwner, LiteralKind,ArrayExprKind, TypeAscriptionOwner},
10}; 10};
11 11
12use crate::{ 12use crate::{
@@ -216,6 +216,9 @@ pub enum Expr {
216 Try { 216 Try {
217 expr: ExprId, 217 expr: ExprId,
218 }, 218 },
219 TryBlock {
220 body: ExprId,
221 },
219 Cast { 222 Cast {
220 expr: ExprId, 223 expr: ExprId,
221 type_ref: TypeRef, 224 type_ref: TypeRef,
@@ -299,6 +302,7 @@ impl Expr {
299 f(*expr); 302 f(*expr);
300 } 303 }
301 } 304 }
305 Expr::TryBlock { body } => f(*body),
302 Expr::Loop { body } => f(*body), 306 Expr::Loop { body } => f(*body),
303 Expr::While { condition, body } => { 307 Expr::While { condition, body } => {
304 f(*condition); 308 f(*condition);
@@ -578,6 +582,10 @@ where
578 self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) 582 self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr)
579 } 583 }
580 } 584 }
585 ast::ExprKind::TryBlockExpr(e) => {
586 let body = self.collect_block_opt(e.try_body());
587 self.alloc_expr(Expr::TryBlock { body }, syntax_ptr)
588 }
581 ast::ExprKind::BlockExpr(e) => self.collect_block_opt(e.block()), 589 ast::ExprKind::BlockExpr(e) => self.collect_block_opt(e.block()),
582 ast::ExprKind::LoopExpr(e) => { 590 ast::ExprKind::LoopExpr(e) => {
583 let body = self.collect_block_opt(e.loop_body()); 591 let body = self.collect_block_opt(e.loop_body());
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs
index 905fe9f0e..6cc5dbc6f 100644
--- a/crates/ra_hir/src/ty/infer.rs
+++ b/crates/ra_hir/src/ty/infer.rs
@@ -946,6 +946,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
946 then_ty 946 then_ty
947 } 947 }
948 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), 948 Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected),
949 Expr::TryBlock { body } => {
950 let _inner = self.infer_expr(*body, expected);
951 // FIXME should be std::result::Result<{inner}, _>
952 Ty::Unknown
953 }
949 Expr::Loop { body } => { 954 Expr::Loop { body } => {
950 self.infer_expr(*body, &Expectation::has_type(Ty::unit())); 955 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
951 // FIXME handle break with value 956 // 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 8b1a1de49..725fb99f6 100644
--- a/crates/ra_parser/src/grammar/expressions/atom.rs
+++ b/crates/ra_parser/src/grammar/expressions/atom.rs
@@ -52,6 +52,7 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet =
52 CONTINUE_KW, 52 CONTINUE_KW,
53 LIFETIME, 53 LIFETIME,
54 ASYNC_KW, 54 ASYNC_KW,
55 TRY_KW,
55 ]); 56 ]);
56 57
57const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW]; 58const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW];
@@ -75,6 +76,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
75 T![loop] => loop_expr(p, None), 76 T![loop] => loop_expr(p, None),
76 T![for] => for_expr(p, None), 77 T![for] => for_expr(p, None),
77 T![while] => while_expr(p, None), 78 T![while] => while_expr(p, None),
79 T![try] => try_block_expr(p, None),
78 LIFETIME if la == T![:] => { 80 LIFETIME if la == T![:] => {
79 let m = p.start(); 81 let m = p.start();
80 label(p); 82 label(p);
@@ -116,7 +118,9 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar
116 } 118 }
117 }; 119 };
118 let blocklike = match done.kind() { 120 let blocklike = match done.kind() {
119 IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR => BlockLike::Block, 121 IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | TRY_BLOCK_EXPR => {
122 BlockLike::Block
123 }
120 _ => BlockLike::NotBlock, 124 _ => BlockLike::NotBlock,
121 }; 125 };
122 Some((done, blocklike)) 126 Some((done, blocklike))
@@ -491,3 +495,15 @@ fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker {
491 } 495 }
492 m.complete(p, BREAK_EXPR) 496 m.complete(p, BREAK_EXPR)
493} 497}
498
499// test try_block_expr
500// fn foo() {
501// let _ = try {};
502// }
503fn try_block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
504 assert!(p.at(T![try]));
505 let m = m.unwrap_or_else(|| p.start());
506 p.bump();
507 block(p);
508 m.complete(p, TRY_EXPR)
509}
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs
index d7926bd91..2c021f3e9 100644
--- a/crates/ra_parser/src/syntax_kind/generated.rs
+++ b/crates/ra_parser/src/syntax_kind/generated.rs
@@ -103,6 +103,7 @@ pub enum SyntaxKind {
103 LET_KW, 103 LET_KW,
104 MOVE_KW, 104 MOVE_KW,
105 RETURN_KW, 105 RETURN_KW,
106 TRY_KW,
106 AUTO_KW, 107 AUTO_KW,
107 DEFAULT_KW, 108 DEFAULT_KW,
108 UNION_KW, 109 UNION_KW,
@@ -184,6 +185,7 @@ pub enum SyntaxKind {
184 STRUCT_LIT, 185 STRUCT_LIT,
185 NAMED_FIELD_LIST, 186 NAMED_FIELD_LIST,
186 NAMED_FIELD, 187 NAMED_FIELD,
188 TRY_BLOCK_EXPR,
187 CALL_EXPR, 189 CALL_EXPR,
188 INDEX_EXPR, 190 INDEX_EXPR,
189 METHOD_CALL_EXPR, 191 METHOD_CALL_EXPR,
@@ -331,6 +333,7 @@ macro_rules! T {
331 (let) => { $crate::SyntaxKind::LET_KW }; 333 (let) => { $crate::SyntaxKind::LET_KW };
332 (move) => { $crate::SyntaxKind::MOVE_KW }; 334 (move) => { $crate::SyntaxKind::MOVE_KW };
333 (return) => { $crate::SyntaxKind::RETURN_KW }; 335 (return) => { $crate::SyntaxKind::RETURN_KW };
336 (try) => { $crate::SyntaxKind::TRY_KW };
334 (auto) => { $crate::SyntaxKind::AUTO_KW }; 337 (auto) => { $crate::SyntaxKind::AUTO_KW };
335 (default) => { $crate::SyntaxKind::DEFAULT_KW }; 338 (default) => { $crate::SyntaxKind::DEFAULT_KW };
336 (union) => { $crate::SyntaxKind::UNION_KW }; 339 (union) => { $crate::SyntaxKind::UNION_KW };
@@ -388,6 +391,7 @@ impl SyntaxKind {
388 | LET_KW 391 | LET_KW
389 | MOVE_KW 392 | MOVE_KW
390 | RETURN_KW 393 | RETURN_KW
394 | TRY_KW
391 | AUTO_KW 395 | AUTO_KW
392 | DEFAULT_KW 396 | DEFAULT_KW
393 | UNION_KW 397 | UNION_KW
@@ -559,6 +563,7 @@ impl SyntaxKind {
559 LET_KW => &SyntaxInfo { name: "LET_KW" }, 563 LET_KW => &SyntaxInfo { name: "LET_KW" },
560 MOVE_KW => &SyntaxInfo { name: "MOVE_KW" }, 564 MOVE_KW => &SyntaxInfo { name: "MOVE_KW" },
561 RETURN_KW => &SyntaxInfo { name: "RETURN_KW" }, 565 RETURN_KW => &SyntaxInfo { name: "RETURN_KW" },
566 TRY_KW => &SyntaxInfo { name: "TRY_KW" },
562 AUTO_KW => &SyntaxInfo { name: "AUTO_KW" }, 567 AUTO_KW => &SyntaxInfo { name: "AUTO_KW" },
563 DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" }, 568 DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" },
564 UNION_KW => &SyntaxInfo { name: "UNION_KW" }, 569 UNION_KW => &SyntaxInfo { name: "UNION_KW" },
@@ -640,6 +645,7 @@ impl SyntaxKind {
640 STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" }, 645 STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" },
641 NAMED_FIELD_LIST => &SyntaxInfo { name: "NAMED_FIELD_LIST" }, 646 NAMED_FIELD_LIST => &SyntaxInfo { name: "NAMED_FIELD_LIST" },
642 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, 647 NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },
648 TRY_BLOCK_EXPR => &SyntaxInfo { name: "TRY_BLOCK_EXPR" },
643 CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" }, 649 CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" },
644 INDEX_EXPR => &SyntaxInfo { name: "INDEX_EXPR" }, 650 INDEX_EXPR => &SyntaxInfo { name: "INDEX_EXPR" },
645 METHOD_CALL_EXPR => &SyntaxInfo { name: "METHOD_CALL_EXPR" }, 651 METHOD_CALL_EXPR => &SyntaxInfo { name: "METHOD_CALL_EXPR" },
@@ -734,6 +740,7 @@ impl SyntaxKind {
734 "let" => LET_KW, 740 "let" => LET_KW,
735 "move" => MOVE_KW, 741 "move" => MOVE_KW,
736 "return" => RETURN_KW, 742 "return" => RETURN_KW,
743 "try" => TRY_KW,
737 _ => return None, 744 _ => return None,
738 }; 745 };
739 Some(kw) 746 Some(kw)
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index e73fe22e9..1d888e709 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -713,6 +713,7 @@ pub enum ExprKind<'a> {
713 MethodCallExpr(&'a MethodCallExpr), 713 MethodCallExpr(&'a MethodCallExpr),
714 FieldExpr(&'a FieldExpr), 714 FieldExpr(&'a FieldExpr),
715 TryExpr(&'a TryExpr), 715 TryExpr(&'a TryExpr),
716 TryBlockExpr(&'a TryBlockExpr),
716 CastExpr(&'a CastExpr), 717 CastExpr(&'a CastExpr),
717 RefExpr(&'a RefExpr), 718 RefExpr(&'a RefExpr),
718 PrefixExpr(&'a PrefixExpr), 719 PrefixExpr(&'a PrefixExpr),
@@ -826,6 +827,11 @@ impl<'a> From<&'a TryExpr> for &'a Expr {
826 Expr::cast(&n.syntax).unwrap() 827 Expr::cast(&n.syntax).unwrap()
827 } 828 }
828} 829}
830impl<'a> From<&'a TryBlockExpr> for &'a Expr {
831 fn from(n: &'a TryBlockExpr) -> &'a Expr {
832 Expr::cast(&n.syntax).unwrap()
833 }
834}
829impl<'a> From<&'a CastExpr> for &'a Expr { 835impl<'a> From<&'a CastExpr> for &'a Expr {
830 fn from(n: &'a CastExpr) -> &'a Expr { 836 fn from(n: &'a CastExpr) -> &'a Expr {
831 Expr::cast(&n.syntax).unwrap() 837 Expr::cast(&n.syntax).unwrap()
@@ -887,6 +893,7 @@ impl AstNode for Expr {
887 | METHOD_CALL_EXPR 893 | METHOD_CALL_EXPR
888 | FIELD_EXPR 894 | FIELD_EXPR
889 | TRY_EXPR 895 | TRY_EXPR
896 | TRY_BLOCK_EXPR
890 | CAST_EXPR 897 | CAST_EXPR
891 | REF_EXPR 898 | REF_EXPR
892 | PREFIX_EXPR 899 | PREFIX_EXPR
@@ -929,6 +936,7 @@ impl Expr {
929 METHOD_CALL_EXPR => ExprKind::MethodCallExpr(MethodCallExpr::cast(&self.syntax).unwrap()), 936 METHOD_CALL_EXPR => ExprKind::MethodCallExpr(MethodCallExpr::cast(&self.syntax).unwrap()),
930 FIELD_EXPR => ExprKind::FieldExpr(FieldExpr::cast(&self.syntax).unwrap()), 937 FIELD_EXPR => ExprKind::FieldExpr(FieldExpr::cast(&self.syntax).unwrap()),
931 TRY_EXPR => ExprKind::TryExpr(TryExpr::cast(&self.syntax).unwrap()), 938 TRY_EXPR => ExprKind::TryExpr(TryExpr::cast(&self.syntax).unwrap()),
939 TRY_BLOCK_EXPR => ExprKind::TryBlockExpr(TryBlockExpr::cast(&self.syntax).unwrap()),
932 CAST_EXPR => ExprKind::CastExpr(CastExpr::cast(&self.syntax).unwrap()), 940 CAST_EXPR => ExprKind::CastExpr(CastExpr::cast(&self.syntax).unwrap()),
933 REF_EXPR => ExprKind::RefExpr(RefExpr::cast(&self.syntax).unwrap()), 941 REF_EXPR => ExprKind::RefExpr(RefExpr::cast(&self.syntax).unwrap()),
934 PREFIX_EXPR => ExprKind::PrefixExpr(PrefixExpr::cast(&self.syntax).unwrap()), 942 PREFIX_EXPR => ExprKind::PrefixExpr(PrefixExpr::cast(&self.syntax).unwrap()),
@@ -3672,6 +3680,35 @@ impl TraitDef {
3672 } 3680 }
3673} 3681}
3674 3682
3683// TryBlockExpr
3684#[derive(Debug, PartialEq, Eq, Hash)]
3685#[repr(transparent)]
3686pub struct TryBlockExpr {
3687 pub(crate) syntax: SyntaxNode,
3688}
3689unsafe impl TransparentNewType for TryBlockExpr {
3690 type Repr = rowan::SyntaxNode;
3691}
3692
3693impl AstNode for TryBlockExpr {
3694 fn cast(syntax: &SyntaxNode) -> Option<&Self> {
3695 match syntax.kind() {
3696 TRY_BLOCK_EXPR => Some(TryBlockExpr::from_repr(syntax.into_repr())),
3697 _ => None,
3698 }
3699 }
3700 fn syntax(&self) -> &SyntaxNode { &self.syntax }
3701}
3702
3703impl ToOwned for TryBlockExpr {
3704 type Owned = TreeArc<TryBlockExpr>;
3705 fn to_owned(&self) -> TreeArc<TryBlockExpr> { TreeArc::cast(self.syntax.to_owned()) }
3706}
3707
3708
3709impl ast::TryBlockBodyOwner for TryBlockExpr {}
3710impl TryBlockExpr {}
3711
3675// TryExpr 3712// TryExpr
3676#[derive(Debug, PartialEq, Eq, Hash)] 3713#[derive(Debug, PartialEq, Eq, Hash)]
3677#[repr(transparent)] 3714#[repr(transparent)]
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs
index 1c90cf148..433485400 100644
--- a/crates/ra_syntax/src/ast/traits.rs
+++ b/crates/ra_syntax/src/ast/traits.rs
@@ -33,6 +33,12 @@ pub trait LoopBodyOwner: AstNode {
33 } 33 }
34} 34}
35 35
36pub trait TryBlockBodyOwner: AstNode {
37 fn try_body(&self) -> Option<&ast::Block> {
38 child_opt(self)
39 }
40}
41
36pub trait ArgListOwner: AstNode { 42pub trait ArgListOwner: AstNode {
37 fn arg_list(&self) -> Option<&ast::ArgList> { 43 fn arg_list(&self) -> Option<&ast::ArgList> {
38 child_opt(self) 44 child_opt(self)
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index b8665bbc8..1c2714307 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -95,6 +95,7 @@ Grammar(
95 "let", 95 "let",
96 "move", 96 "move",
97 "return", 97 "return",
98 "try",
98 ], 99 ],
99 contextual_keywords: [ 100 contextual_keywords: [
100 "auto", 101 "auto",
@@ -189,6 +190,7 @@ Grammar(
189 "STRUCT_LIT", 190 "STRUCT_LIT",
190 "NAMED_FIELD_LIST", 191 "NAMED_FIELD_LIST",
191 "NAMED_FIELD", 192 "NAMED_FIELD",
193 "TRY_BLOCK_EXPR",
192 194
193 // postfix 195 // postfix
194 "CALL_EXPR", 196 "CALL_EXPR",
@@ -417,6 +419,9 @@ Grammar(
417 "LoopExpr": ( 419 "LoopExpr": (
418 traits: ["LoopBodyOwner"], 420 traits: ["LoopBodyOwner"],
419 ), 421 ),
422 "TryBlockExpr": (
423 traits: ["TryBlockBodyOwner"],
424 ),
420 "ForExpr": ( 425 "ForExpr": (
421 traits: ["LoopBodyOwner"], 426 traits: ["LoopBodyOwner"],
422 options: [ 427 options: [
@@ -499,6 +504,7 @@ Grammar(
499 "MethodCallExpr", 504 "MethodCallExpr",
500 "FieldExpr", 505 "FieldExpr",
501 "TryExpr", 506 "TryExpr",
507 "TryBlockExpr",
502 "CastExpr", 508 "CastExpr",
503 "RefExpr", 509 "RefExpr",
504 "PrefixExpr", 510 "PrefixExpr",
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0130_try_block_expr.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0130_try_block_expr.rs
new file mode 100644
index 000000000..0f1b41eb6
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0130_try_block_expr.rs
@@ -0,0 +1,3 @@
1fn foo() {
2 let _ = try {};
3}
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0130_try_block_expr.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0130_try_block_expr.txt
new file mode 100644
index 000000000..53f49b9b5
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0130_try_block_expr.txt
@@ -0,0 +1,31 @@
1SOURCE_FILE@[0; 33)
2 FN_DEF@[0; 32)
3 FN_KW@[0; 2) "fn"
4 WHITESPACE@[2; 3) " "
5 NAME@[3; 6)
6 IDENT@[3; 6) "foo"
7 PARAM_LIST@[6; 8)
8 L_PAREN@[6; 7) "("
9 R_PAREN@[7; 8) ")"
10 WHITESPACE@[8; 9) " "
11 BLOCK@[9; 32)
12 L_CURLY@[9; 10) "{"
13 WHITESPACE@[10; 15) "\n "
14 LET_STMT@[15; 30)
15 LET_KW@[15; 18) "let"
16 WHITESPACE@[18; 19) " "
17 PLACEHOLDER_PAT@[19; 20)
18 UNDERSCORE@[19; 20) "_"
19 WHITESPACE@[20; 21) " "
20 EQ@[21; 22) "="
21 WHITESPACE@[22; 23) " "
22 TRY_EXPR@[23; 29)
23 TRY_KW@[23; 26) "try"
24 WHITESPACE@[26; 27) " "
25 BLOCK@[27; 29)
26 L_CURLY@[27; 28) "{"
27 R_CURLY@[28; 29) "}"
28 SEMI@[29; 30) ";"
29 WHITESPACE@[30; 31) "\n"
30 R_CURLY@[31; 32) "}"
31 WHITESPACE@[32; 33) "\n"