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);
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),
Yield {
expr: Option<ExprId>,
},
+ Yeet {
+ expr: Option<ExprId>,
+ },
RecordLit {
path: Option<Box<Path>>,
fields: Box<[RecordLitField]>,
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);
}
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 {
| ast::Expr::WhileExpr(_)
| ast::Expr::LetExpr(_)
| ast::Expr::UnderscoreExpr(_)
- | ast::Expr::YieldExpr(_) => cb(expr),
+ | ast::Expr::YieldExpr(_)
+ | ast::Expr::YeetExpr(_) => cb(expr),
}
}
| 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(),
| TupleExpr
| WhileExpr
| YieldExpr
+| YeetExpr
| LetExpr
| UnderscoreExpr
YieldExpr =
Attr* 'yield' Expr?
+YeetExpr =
+ Attr* 'do' 'yeet' Expr?
+
LetExpr =
Attr* 'let' Pat '=' Expr
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,
TupleExpr(TupleExpr),
WhileExpr(WhileExpr),
YieldExpr(YieldExpr),
+ YeetExpr(YeetExpr),
LetExpr(LetExpr),
UnderscoreExpr(UnderscoreExpr),
}
}
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> {
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) }
}
| TUPLE_EXPR
| WHILE_EXPR
| YIELD_EXPR
+ | YEET_EXPR
| LET_EXPR
| UNDERSCORE_EXPR
)
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,
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,
}
| TUPLE_EXPR
| WHILE_EXPR
| YIELD_EXPR
+ | YEET_EXPR
| LET_EXPR
| UNDERSCORE_EXPR
| STMT_LIST
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)
//
ContinueExpr(_) => (0, 0),
- ClosureExpr(_) | ReturnExpr(_) | YieldExpr(_) | BreakExpr(_) => (0, 1),
+ ClosureExpr(_) | ReturnExpr(_) | YieldExpr(_) | YeetExpr(_) | BreakExpr(_) => (0, 1),
RangeExpr(_) => (5, 5),
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(_)
// 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)