Skip to content

Commit 628b75c

Browse files
committed
fix "needless return" for trailing item declarations
1 parent db277c7 commit 628b75c

File tree

9 files changed

+51
-19
lines changed

9 files changed

+51
-19
lines changed

crates/hir-def/src/body/lower.rs

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ impl ExprCollector<'_> {
271271
ast::Expr::BlockExpr(e) => match e.modifier() {
272272
Some(ast::BlockModifier::Try(_)) => self.desugar_try_block(e),
273273
Some(ast::BlockModifier::Unsafe(_)) => {
274-
self.collect_block_(e, |id, statements, tail| Expr::Unsafe {
274+
self.collect_block_(e, |id, statements, tail, _| Expr::Unsafe {
275275
id,
276276
statements,
277277
tail,
@@ -280,17 +280,20 @@ impl ExprCollector<'_> {
280280
Some(ast::BlockModifier::Label(label)) => {
281281
let label = self.collect_label(label);
282282
self.with_labeled_rib(label, |this| {
283-
this.collect_block_(e, |id, statements, tail| Expr::Block {
284-
id,
285-
statements,
286-
tail,
287-
label: Some(label),
283+
this.collect_block_(e, |id, statements, tail, has_trailing_item_decl| {
284+
Expr::Block {
285+
id,
286+
statements,
287+
tail,
288+
label: Some(label),
289+
has_trailing_item_decl,
290+
}
288291
})
289292
})
290293
}
291294
Some(ast::BlockModifier::Async(_)) => {
292295
self.with_label_rib(RibKind::Closure, |this| {
293-
this.collect_block_(e, |id, statements, tail| Expr::Async {
296+
this.collect_block_(e, |id, statements, tail, _| Expr::Async {
294297
id,
295298
statements,
296299
tail,
@@ -710,9 +713,15 @@ impl ExprCollector<'_> {
710713

711714
let (btail, expr_id) = self.with_labeled_rib(label, |this| {
712715
let mut btail = None;
713-
let block = this.collect_block_(e, |id, statements, tail| {
716+
let block = this.collect_block_(e, |id, statements, tail, _| {
714717
btail = tail;
715-
Expr::Block { id, statements, tail, label: Some(label) }
718+
Expr::Block {
719+
id,
720+
statements,
721+
tail,
722+
label: Some(label),
723+
has_trailing_item_decl: false,
724+
}
716725
});
717726
(btail, block)
718727
});
@@ -1118,18 +1127,19 @@ impl ExprCollector<'_> {
11181127
}
11191128

11201129
fn collect_block(&mut self, block: ast::BlockExpr) -> ExprId {
1121-
self.collect_block_(block, |id, statements, tail| Expr::Block {
1130+
self.collect_block_(block, |id, statements, tail, has_trailing_item_decl| Expr::Block {
11221131
id,
11231132
statements,
11241133
tail,
11251134
label: None,
1135+
has_trailing_item_decl,
11261136
})
11271137
}
11281138

11291139
fn collect_block_(
11301140
&mut self,
11311141
block: ast::BlockExpr,
1132-
mk_block: impl FnOnce(Option<BlockId>, Box<[Statement]>, Option<ExprId>) -> Expr,
1142+
mk_block: impl FnOnce(Option<BlockId>, Box<[Statement]>, Option<ExprId>, bool) -> Expr,
11331143
) -> ExprId {
11341144
let block_has_items = {
11351145
let statement_has_item = block.statements().any(|stmt| match stmt {
@@ -1178,9 +1188,15 @@ impl ExprCollector<'_> {
11781188
None
11791189
});
11801190

1191+
let has_trailing_item_decl = block
1192+
.statements()
1193+
.last()
1194+
.map_or(false, |last_stmt| matches!(last_stmt, ast::Stmt::Item(_)));
11811195
let syntax_node_ptr = AstPtr::new(&block.into());
1182-
let expr_id = self
1183-
.alloc_expr(mk_block(block_id, statements.into_boxed_slice(), tail), syntax_node_ptr);
1196+
let expr_id = self.alloc_expr(
1197+
mk_block(block_id, statements.into_boxed_slice(), tail, has_trailing_item_decl),
1198+
syntax_node_ptr,
1199+
);
11841200

11851201
self.def_map = prev_def_map;
11861202
self.expander.module = prev_local_module;

crates/hir-def/src/body/pretty.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ impl Printer<'_> {
445445
w!(self, "]");
446446
}
447447
Expr::Literal(lit) => self.print_literal(lit),
448-
Expr::Block { id: _, statements, tail, label } => {
448+
Expr::Block { id: _, statements, tail, label, .. } => {
449449
let label =
450450
label.map(|lbl| format!("{}: ", self.body[lbl].name.display(self.db.upcast())));
451451
self.print_block(label.as_deref(), statements, tail);

crates/hir-def/src/body/scope.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ fn compute_expr_scopes(expr: ExprId, body: &Body, scopes: &mut ExprScopes, scope
210210

211211
scopes.set_scope(expr, *scope);
212212
match &body[expr] {
213-
Expr::Block { statements, tail, id, label } => {
213+
Expr::Block { statements, tail, id, label, .. } => {
214214
let mut scope = scopes.new_block_scope(*scope, *id, make_label(label));
215215
// Overwrite the old scope for the block expr, so that every block scope can be found
216216
// via the block itself (important for blocks that only contain items, no expressions).

crates/hir-def/src/hir.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ pub enum Expr {
175175
statements: Box<[Statement]>,
176176
tail: Option<ExprId>,
177177
label: Option<LabelId>,
178+
has_trailing_item_decl: bool,
178179
},
179180
Async {
180181
id: Option<BlockId>,

crates/hir-ty/src/diagnostics/expr.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,10 @@ impl ExprValidator {
258258

259259
fn check_for_trailing_return(&mut self, body_expr: ExprId, body: &Body) {
260260
match &body.exprs[body_expr] {
261-
Expr::Block { statements, tail, .. } => {
261+
Expr::Block { statements, tail, has_trailing_item_decl, .. } => {
262+
if *has_trailing_item_decl {
263+
return;
264+
}
262265
let last_stmt = tail.or_else(|| match statements.last()? {
263266
Statement::Expr { expr, .. } => Some(*expr),
264267
_ => None,

crates/hir-ty/src/infer/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ impl InferenceContext<'_> {
165165
self.infer_top_pat(pat, &input_ty);
166166
self.result.standard_types.bool_.clone()
167167
}
168-
Expr::Block { statements, tail, label, id } => {
168+
Expr::Block { statements, tail, label, id, .. } => {
169169
self.infer_block(tgt_expr, *id, statements, *tail, *label, expected)
170170
}
171171
Expr::Unsafe { id, statements, tail } => {

crates/hir-ty/src/infer/mutability.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ impl InferenceContext<'_> {
4949
self.infer_mut_expr(loc.root, Mutability::Not);
5050
}
5151
Expr::Let { pat, expr } => self.infer_mut_expr(*expr, self.pat_bound_mutability(*pat)),
52-
Expr::Block { id: _, statements, tail, label: _ }
52+
Expr::Block { id: _, statements, tail, .. }
5353
| Expr::Async { id: _, statements, tail }
5454
| Expr::Unsafe { id: _, statements, tail } => {
5555
for st in statements.iter() {

crates/hir-ty/src/mir/lower.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ impl<'ctx> MirLowerCtx<'ctx> {
558558
Expr::Unsafe { id: _, statements, tail } => {
559559
self.lower_block_to_place(statements, current, *tail, place, expr_id.into())
560560
}
561-
Expr::Block { id: _, statements, tail, label } => {
561+
Expr::Block { id: _, statements, tail, label, .. } => {
562562
if let Some(label) = label {
563563
self.lower_loop(current, place, Some(*label), expr_id.into(), |this, begin| {
564564
if let Some(current) = this.lower_block_to_place(

crates/ide-diagnostics/src/handlers/remove_trailing_return.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,18 @@ fn foo() -> u8 {
182182
);
183183
}
184184

185+
#[test]
186+
fn no_diagnostic_if_not_last_statement2() {
187+
check_diagnostics(
188+
r#"
189+
fn foo() -> u8 {
190+
return 2;
191+
fn bar() {}
192+
}
193+
"#,
194+
);
195+
}
196+
185197
#[test]
186198
fn replace_with_expr() {
187199
check_fix(

0 commit comments

Comments
 (0)