From c54301f114d6fab44e8305da328eece26f682456 Mon Sep 17 00:00:00 2001 From: cardigan1008 <211250058@smail.nju.edu.cn> Date: Thu, 9 May 2024 14:36:54 +0800 Subject: [PATCH 1/3] fix: Add if to check whether the previous node is Block --- compiler/rustc_middle/src/hir/map/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index c7aea137b6841..0deafb73d0ed9 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -563,6 +563,9 @@ impl<'hir> Map<'hir> { // We verify that indirectly by checking that the previous node is the // current node's body if node.body_id().map(|b| b.hir_id) == prev_hir_id => { + if let Node::Expr(Expr { kind: ExprKind::Block(_, _), ..}) = self.tcx.hir_node(prev_hir_id.unwrap()) { + return None; + } return Some(hir_id) } // Ignore `return`s on the first iteration From 62318b38ef591c70d9db875e88a04aa37c565828 Mon Sep 17 00:00:00 2001 From: cardigan1008 <211250058@smail.nju.edu.cn> Date: Thu, 9 May 2024 23:44:54 +0800 Subject: [PATCH 2/3] fix: Check whether next_node is else-less if in get_return_block Fix #124819, where a if-less block causes a wrong output. It is caused by get_return_block in get_fn_decl. In get_return_block, when a else-less if expression is the tail expression, the check for next_node will keep iterating. So it is necessary to make a early return in the check. --- compiler/rustc_middle/src/hir/map/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 0deafb73d0ed9..f4ecc0973ef29 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -549,6 +549,7 @@ impl<'hir> Map<'hir> { Node::Block(Block { expr: None, .. }) => return None, // The current node is not the tail expression of its parent. Node::Block(Block { expr: Some(e), .. }) if hir_id != e.hir_id => return None, + Node::Block(Block { expr: Some(e), ..}) if matches!(e.kind, ExprKind::If(_, _, None)) => return None, _ => {} } } @@ -563,9 +564,6 @@ impl<'hir> Map<'hir> { // We verify that indirectly by checking that the previous node is the // current node's body if node.body_id().map(|b| b.hir_id) == prev_hir_id => { - if let Node::Expr(Expr { kind: ExprKind::Block(_, _), ..}) = self.tcx.hir_node(prev_hir_id.unwrap()) { - return None; - } return Some(hir_id) } // Ignore `return`s on the first iteration From c811acb1f36cdeb45b46c490b7a308851347dc0d Mon Sep 17 00:00:00 2001 From: cardigan1008 <211250058@smail.nju.edu.cn> Date: Thu, 16 May 2024 21:10:07 +0800 Subject: [PATCH 3/3] feat: add unit test --- tests/ui/return/tail-expr-if-as-return.rs | 5 +++++ tests/ui/return/tail-expr-if-as-return.stderr | 12 ++++++++++++ 2 files changed, 17 insertions(+) create mode 100644 tests/ui/return/tail-expr-if-as-return.rs create mode 100644 tests/ui/return/tail-expr-if-as-return.stderr diff --git a/tests/ui/return/tail-expr-if-as-return.rs b/tests/ui/return/tail-expr-if-as-return.rs new file mode 100644 index 0000000000000..119ffccc6a945 --- /dev/null +++ b/tests/ui/return/tail-expr-if-as-return.rs @@ -0,0 +1,5 @@ +fn main() { + if true { + "" //~ ERROR mismatched types [E0308] + } +} diff --git a/tests/ui/return/tail-expr-if-as-return.stderr b/tests/ui/return/tail-expr-if-as-return.stderr new file mode 100644 index 0000000000000..2631f1e426ded --- /dev/null +++ b/tests/ui/return/tail-expr-if-as-return.stderr @@ -0,0 +1,12 @@ +error[E0308]: mismatched types + --> $DIR/tail-expr-if-as-return.rs:3:9 + | +LL | / if true { +LL | | "" + | | ^^ expected `()`, found `&str` +LL | | } + | |_____- expected this to be `()` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`.