]> git.lizzy.rs Git - rust.git/commitdiff
Implement `do yeet` expression
authorMaybe Waffle <waffle.lapkin@gmail.com>
Wed, 28 Dec 2022 23:17:13 +0000 (23:17 +0000)
committerMaybe Waffle <waffle.lapkin@gmail.com>
Wed, 28 Dec 2022 23:17:13 +0000 (23:17 +0000)
crates/hir-def/src/body/lower.rs
crates/hir-def/src/body/pretty.rs
crates/hir-def/src/expr.rs
crates/hir-ty/src/infer/expr.rs
crates/ide-db/src/syntax_helpers/node_ext.rs
crates/ide/src/syntax_highlighting/highlight.rs
crates/syntax/rust.ungram
crates/syntax/src/ast/generated/nodes.rs
crates/syntax/src/ast/prec.rs

index ccc01c3efca51468eb320a664128bba7d61473e7..e8da24e3addaa535748931aa642eda49cbe67e35 100644 (file)
@@ -371,6 +371,10 @@ fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
                 let expr = e.expr().map(|e| self.collect_expr(e));
                 self.alloc_expr(Expr::Yield { expr }, syntax_ptr)
             }
+            ast::Expr::YeetExpr(e) => {
+                let expr = e.expr().map(|e| self.collect_expr(e));
+                self.alloc_expr(Expr::Yeet { expr }, syntax_ptr)
+            }
             ast::Expr::RecordExpr(e) => {
                 let path =
                     e.path().and_then(|path| self.expander.parse_path(self.db, path)).map(Box::new);
index 04279751f0c89fe062e13d32b223adb52f56cb8d..10b9b26bbeaa1bb84dea58feb611034d0df9af2b 100644 (file)
@@ -247,6 +247,15 @@ fn print_expr(&mut self, expr: ExprId) {
                     self.print_expr(*expr);
                 }
             }
+            Expr::Yeet { expr } => {
+                w!(self, "do");
+                self.whitespace();
+                w!(self, "yeet");
+                if let Some(expr) = expr {
+                    self.whitespace();
+                    self.print_expr(*expr);
+                }
+            }
             Expr::RecordLit { path, fields, spread, ellipsis, is_assignee_expr: _ } => {
                 match path {
                     Some(path) => self.print_path(path),
index 16264655020712fe2caa3afcc1563c960cdbfc09..3066213ace8e71f196b49f4fdf70924d18c648d0 100644 (file)
@@ -137,6 +137,9 @@ pub enum Expr {
     Yield {
         expr: Option<ExprId>,
     },
+    Yeet {
+        expr: Option<ExprId>,
+    },
     RecordLit {
         path: Option<Box<Path>>,
         fields: Box<[RecordLitField]>,
@@ -313,7 +316,10 @@ pub fn walk_child_exprs(&self, mut f: impl FnMut(ExprId)) {
                 arms.iter().map(|arm| arm.expr).for_each(f);
             }
             Expr::Continue { .. } => {}
-            Expr::Break { expr, .. } | Expr::Return { expr } | Expr::Yield { expr } => {
+            Expr::Break { expr, .. }
+            | Expr::Return { expr }
+            | Expr::Yield { expr }
+            | Expr::Yeet { expr } => {
                 if let &Some(expr) = expr {
                     f(expr);
                 }
index b1f4de826077542ad5b54ceaa1d52fb16b99d992..8070655cab5c7a4b144636731be9eb8c7384917c 100644 (file)
@@ -465,6 +465,12 @@ fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty {
                     TyKind::Error.intern(Interner)
                 }
             }
+            Expr::Yeet { expr } => {
+                if let &Some(expr) = expr {
+                    self.infer_expr_inner(expr, &Expectation::None);
+                }
+                TyKind::Never.intern(Interner)
+            }
             Expr::RecordLit { path, fields, spread, .. } => {
                 let (ty, def_id) = self.resolve_variant(path.as_deref(), false);
                 if let Some(variant) = def_id {
index 39710b8f13eb5f7024b8fe2a385ead1badda3a21..347e87ce9720cafe9e1ab8693e8cf02c3a6ea9cd 100644 (file)
@@ -328,7 +328,8 @@ pub fn for_each_tail_expr(expr: &ast::Expr, cb: &mut dyn FnMut(&ast::Expr)) {
         | ast::Expr::WhileExpr(_)
         | ast::Expr::LetExpr(_)
         | ast::Expr::UnderscoreExpr(_)
-        | ast::Expr::YieldExpr(_) => cb(expr),
+        | ast::Expr::YieldExpr(_)
+        | ast::Expr::YeetExpr(_) => cb(expr),
     }
 }
 
index e7d0a8be7f57316f2ce92ade5164fc4c9e3f996a..a06c6abf286e2dfa14344b368055f2bcc9fd813e 100644 (file)
@@ -174,6 +174,7 @@ fn keyword(
         | T![return]
         | T![while]
         | T![yield] => h | HlMod::ControlFlow,
+        T![do] | T![yeet] if parent_matches::<ast::YeetExpr>(&token) => h | HlMod::ControlFlow,
         T![for] if parent_matches::<ast::ForExpr>(&token) => h | HlMod::ControlFlow,
         T![unsafe] => h | HlMod::Unsafe,
         T![true] | T![false] => HlTag::BoolLiteral.into(),
index 0a0cb0290d6cb5b0a55bc683a8fb8292f64fae63..2c67586a3905da43c02cdb4bea90cad620ae0680 100644 (file)
@@ -359,6 +359,7 @@ Expr =
 | TupleExpr
 | WhileExpr
 | YieldExpr
+| YeetExpr
 | LetExpr
 | UnderscoreExpr
 
@@ -503,6 +504,9 @@ ReturnExpr =
 YieldExpr =
   Attr* 'yield' Expr?
 
+YeetExpr =
+  Attr* 'do' 'yeet' Expr?
+
 LetExpr =
   Attr* 'let' Pat '=' Expr
 
index 2ea715f47fb23753089a3be6e96ac55425697d52..86d222723d50bdd40b7a0a4cf39c8f4326266e39 100644 (file)
@@ -1063,6 +1063,17 @@ pub fn yield_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax,
     pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
 }
 
+#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+pub struct YeetExpr {
+    pub(crate) syntax: SyntaxNode,
+}
+impl ast::HasAttrs for YeetExpr {}
+impl YeetExpr {
+    pub fn do_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![do]) }
+    pub fn yeet_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![yeet]) }
+    pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) }
+}
+
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub struct LetExpr {
     pub(crate) syntax: SyntaxNode,
@@ -1541,6 +1552,7 @@ pub enum Expr {
     TupleExpr(TupleExpr),
     WhileExpr(WhileExpr),
     YieldExpr(YieldExpr),
+    YeetExpr(YeetExpr),
     LetExpr(LetExpr),
     UnderscoreExpr(UnderscoreExpr),
 }
@@ -2694,6 +2706,17 @@ fn cast(syntax: SyntaxNode) -> Option<Self> {
     }
     fn syntax(&self) -> &SyntaxNode { &self.syntax }
 }
+impl AstNode for YeetExpr {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == YEET_EXPR }
+    fn cast(syntax: SyntaxNode) -> Option<Self> {
+        if Self::can_cast(syntax.kind()) {
+            Some(Self { syntax })
+        } else {
+            None
+        }
+    }
+    fn syntax(&self) -> &SyntaxNode { &self.syntax }
+}
 impl AstNode for LetExpr {
     fn can_cast(kind: SyntaxKind) -> bool { kind == LET_EXPR }
     fn cast(syntax: SyntaxNode) -> Option<Self> {
@@ -3382,6 +3405,9 @@ fn from(node: WhileExpr) -> Expr { Expr::WhileExpr(node) }
 impl From<YieldExpr> for Expr {
     fn from(node: YieldExpr) -> Expr { Expr::YieldExpr(node) }
 }
+impl From<YeetExpr> for Expr {
+    fn from(node: YeetExpr) -> Expr { Expr::YeetExpr(node) }
+}
 impl From<LetExpr> for Expr {
     fn from(node: LetExpr) -> Expr { Expr::LetExpr(node) }
 }
@@ -3422,6 +3448,7 @@ fn can_cast(kind: SyntaxKind) -> bool {
                 | TUPLE_EXPR
                 | WHILE_EXPR
                 | YIELD_EXPR
+                | YEET_EXPR
                 | LET_EXPR
                 | UNDERSCORE_EXPR
         )
@@ -3458,6 +3485,7 @@ fn cast(syntax: SyntaxNode) -> Option<Self> {
             TUPLE_EXPR => Expr::TupleExpr(TupleExpr { syntax }),
             WHILE_EXPR => Expr::WhileExpr(WhileExpr { syntax }),
             YIELD_EXPR => Expr::YieldExpr(YieldExpr { syntax }),
+            YEET_EXPR => Expr::YeetExpr(YeetExpr { syntax }),
             LET_EXPR => Expr::LetExpr(LetExpr { syntax }),
             UNDERSCORE_EXPR => Expr::UnderscoreExpr(UnderscoreExpr { syntax }),
             _ => return None,
@@ -3496,6 +3524,7 @@ fn syntax(&self) -> &SyntaxNode {
             Expr::TupleExpr(it) => &it.syntax,
             Expr::WhileExpr(it) => &it.syntax,
             Expr::YieldExpr(it) => &it.syntax,
+            Expr::YeetExpr(it) => &it.syntax,
             Expr::LetExpr(it) => &it.syntax,
             Expr::UnderscoreExpr(it) => &it.syntax,
         }
@@ -3963,6 +3992,7 @@ fn can_cast(kind: SyntaxKind) -> bool {
                 | TUPLE_EXPR
                 | WHILE_EXPR
                 | YIELD_EXPR
+                | YEET_EXPR
                 | LET_EXPR
                 | UNDERSCORE_EXPR
                 | STMT_LIST
@@ -4655,6 +4685,11 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
     }
 }
+impl std::fmt::Display for YeetExpr {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        std::fmt::Display::fmt(self.syntax(), f)
+    }
+}
 impl std::fmt::Display for LetExpr {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         std::fmt::Display::fmt(self.syntax(), f)
index c118ef063593edf93e6fca74409ea2d0007616ee..4ec388914e604d8aa4d71092557784681a3034a5 100644 (file)
@@ -130,7 +130,7 @@ fn binding_power(&self) -> (u8, u8) {
             //
             ContinueExpr(_) => (0, 0),
 
-            ClosureExpr(_) | ReturnExpr(_) | YieldExpr(_) | BreakExpr(_) => (0, 1),
+            ClosureExpr(_) | ReturnExpr(_) | YieldExpr(_) | YeetExpr(_) | BreakExpr(_) => (0, 1),
 
             RangeExpr(_) => (5, 5),
 
@@ -291,6 +291,7 @@ fn order(this: &Expr) -> rowan::TextSize {
                 ReturnExpr(e) => e.return_token(),
                 TryExpr(e) => e.question_mark_token(),
                 YieldExpr(e) => e.yield_token(),
+                YeetExpr(e) => e.do_token(),
                 LetExpr(e) => e.let_token(),
 
                 ArrayExpr(_) | TupleExpr(_) | Literal(_) | PathExpr(_) | ParenExpr(_)
@@ -313,7 +314,8 @@ fn child_is_followed_by_a_block(&self) -> bool {
 
             // For BinExpr and RangeExpr this is technically wrong -- the child can be on the left...
             BinExpr(_) | RangeExpr(_) | BoxExpr(_) | BreakExpr(_) | ContinueExpr(_)
-            | PrefixExpr(_) | RefExpr(_) | ReturnExpr(_) | YieldExpr(_) | LetExpr(_) => self
+            | PrefixExpr(_) | RefExpr(_) | ReturnExpr(_) | YieldExpr(_) | YeetExpr(_)
+            | LetExpr(_) => self
                 .syntax()
                 .parent()
                 .and_then(Expr::cast)