diff --git a/crates/ra_assists/src/handlers/change_return_type_to_result.rs b/crates/ra_assists/src/handlers/change_return_type_to_result.rs index 167e162d80..4b73c41dac 100644 --- a/crates/ra_assists/src/handlers/change_return_type_to_result.rs +++ b/crates/ra_assists/src/handlers/change_return_type_to_result.rs @@ -74,6 +74,7 @@ impl TailReturnCollector { let expr = match &stmt { ast::Stmt::ExprStmt(stmt) => stmt.expr(), ast::Stmt::LetStmt(stmt) => stmt.initializer(), + ast::Stmt::Item(_) => continue, }; if let Some(expr) = &expr { self.handle_exprs(expr, collect_break); @@ -94,6 +95,7 @@ impl TailReturnCollector { let expr_stmt = match &expr_stmt { ast::Stmt::ExprStmt(stmt) => stmt.expr(), ast::Stmt::LetStmt(stmt) => stmt.initializer(), + ast::Stmt::Item(_) => None, }; if let Some(expr) = &expr_stmt { self.handle_exprs(expr, collect_break); diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 827ced4ad2..5816bf5664 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -10,7 +10,7 @@ use hir_expand::{ use ra_arena::Arena; use ra_syntax::{ ast::{ - self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, ModuleItemOwner, NameOwner, + self, ArgListOwner, ArrayExprKind, LiteralKind, LoopBodyOwner, NameOwner, SlicePatComponents, }, AstNode, AstPtr, @@ -601,14 +601,20 @@ impl ExprCollector<'_> { self.collect_block_items(&block); let statements = block .statements() - .map(|s| match s { - ast::Stmt::LetStmt(stmt) => { - let pat = self.collect_pat_opt(stmt.pat()); - let type_ref = stmt.ty().map(|it| TypeRef::from_ast(&self.ctx(), it)); - let initializer = stmt.initializer().map(|e| self.collect_expr(e)); - Statement::Let { pat, type_ref, initializer } - } - ast::Stmt::ExprStmt(stmt) => Statement::Expr(self.collect_expr_opt(stmt.expr())), + .filter_map(|s| { + let stmt = match s { + ast::Stmt::LetStmt(stmt) => { + let pat = self.collect_pat_opt(stmt.pat()); + let type_ref = stmt.ty().map(|it| TypeRef::from_ast(&self.ctx(), it)); + let initializer = stmt.initializer().map(|e| self.collect_expr(e)); + Statement::Let { pat, type_ref, initializer } + } + ast::Stmt::ExprStmt(stmt) => { + Statement::Expr(self.collect_expr_opt(stmt.expr())) + } + ast::Stmt::Item(_) => return None, + }; + Some(stmt) }) .collect(); let tail = block.expr().map(|e| self.collect_expr(e)); @@ -620,7 +626,11 @@ impl ExprCollector<'_> { let container = ContainerId::DefWithBodyId(self.def); let items = block - .items() + .statements() + .filter_map(|stmt| match stmt { + ast::Stmt::Item(it) => Some(it), + ast::Stmt::LetStmt(_) | ast::Stmt::ExprStmt(_) => None, + }) .filter_map(|item| { let (def, name): (ModuleDefId, Option) = match item { ast::Item::Fn(def) => { diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 8a0e3d27b2..d536bb1e7d 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -17,7 +17,7 @@ use crate::{ pub use self::{ expr_ext::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind, PrefixOp, RangeOp}, - generated::{nodes::*, tokens::*}, + generated::*, node_ext::{ AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents, StructKind, TypeBoundKind, VisibilityKind, diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index f5199e09f2..4a6f41ee71 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -1,6 +1,41 @@ //! This file is actually hand-written, but the submodules are indeed generated. +#[rustfmt::skip] +mod nodes; +#[rustfmt::skip] +mod tokens; -#[rustfmt::skip] -pub(super) mod nodes; -#[rustfmt::skip] -pub(super) mod tokens; +use crate::{ + AstNode, + SyntaxKind::{self, *}, + SyntaxNode, +}; + +pub use {nodes::*, tokens::*}; + +// Stmt is the only nested enum, so it's easier to just hand-write it +impl AstNode for Stmt { + fn can_cast(kind: SyntaxKind) -> bool { + match kind { + LET_STMT | EXPR_STMT => true, + _ => Item::can_cast(kind), + } + } + fn cast(syntax: SyntaxNode) -> Option { + let res = match syntax.kind() { + LET_STMT => Stmt::LetStmt(LetStmt { syntax }), + EXPR_STMT => Stmt::ExprStmt(ExprStmt { syntax }), + _ => { + let item = Item::cast(syntax)?; + Stmt::Item(item) + } + }; + Some(res) + } + fn syntax(&self) -> &SyntaxNode { + match self { + Stmt::LetStmt(it) => &it.syntax, + Stmt::ExprStmt(it) => &it.syntax, + Stmt::Item(it) => it.syntax(), + } + } +} diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs index 286be1032b..763fd20f40 100644 --- a/crates/ra_syntax/src/ast/generated/nodes.rs +++ b/crates/ra_syntax/src/ast/generated/nodes.rs @@ -348,7 +348,6 @@ pub struct BlockExpr { pub(crate) syntax: SyntaxNode, } impl ast::AttrsOwner for BlockExpr {} -impl ast::ModuleItemOwner for BlockExpr {} impl BlockExpr { pub fn label(&self) -> Option