Skip to content

Commit 3eef023

Browse files
Address more nits
1 parent cd89978 commit 3eef023

File tree

3 files changed

+34
-40
lines changed

3 files changed

+34
-40
lines changed

compiler/rustc_hir/src/hir.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -955,7 +955,7 @@ pub struct Block<'hir> {
955955
}
956956

957957
impl<'hir> Block<'hir> {
958-
pub fn peel_blocks(&self) -> &Block<'hir> {
958+
pub fn innermost_block(&self) -> &Block<'hir> {
959959
let mut block = self;
960960
while let Some(Expr { kind: ExprKind::Block(inner_block, _), .. }) = block.expr {
961961
block = inner_block;

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+31-37
Original file line numberDiff line numberDiff line change
@@ -758,22 +758,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
758758
second_ty: Ty<'tcx>,
759759
second_span: Span,
760760
) {
761-
let semicolon =
762-
if let Some(first_id) = first_id
763-
&& let hir::Node::Block(blk) = self.tcx.hir().get(first_id)
764-
&& let Some(remove_semicolon) = self.could_remove_semicolon(blk, second_ty)
765-
{
766-
Some(remove_semicolon)
767-
} else if let Some(second_id) = second_id
768-
&& let hir::Node::Block(blk) = self.tcx.hir().get(second_id)
769-
&& let Some(remove_semicolon) = self.could_remove_semicolon(blk, first_ty)
770-
{
771-
Some(remove_semicolon)
772-
} else {
773-
None
774-
};
775-
if let Some((sp, boxed)) = semicolon {
776-
if matches!(boxed, StatementAsExpression::NeedsBoxing) {
761+
let remove_semicolon =
762+
[(first_id, second_ty), (second_id, first_ty)].into_iter().find_map(|(id, ty)| {
763+
let hir::Node::Block(blk) = self.tcx.hir().get(id?) else { return None };
764+
self.could_remove_semicolon(blk, ty)
765+
});
766+
match remove_semicolon {
767+
Some((sp, StatementAsExpression::NeedsBoxing)) => {
777768
err.multipart_suggestion(
778769
"consider removing this semicolon and boxing the expressions",
779770
vec![
@@ -785,28 +776,24 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
785776
],
786777
Applicability::MachineApplicable,
787778
);
788-
} else {
779+
}
780+
Some((sp, StatementAsExpression::CorrectType)) => {
789781
err.span_suggestion_short(
790782
sp,
791783
"consider removing this semicolon",
792784
"",
793785
Applicability::MachineApplicable,
794786
);
795787
}
796-
} else {
797-
let suggested =
798-
if let Some(first_id) = first_id
799-
&& let hir::Node::Block(blk) = self.tcx.hir().get(first_id)
800-
{
801-
self.consider_returning_binding(blk, second_ty, err)
802-
} else {
803-
false
804-
};
805-
if !suggested
806-
&& let Some(second_id) = second_id
807-
&& let hir::Node::Block(blk) = self.tcx.hir().get(second_id)
808-
{
809-
self.consider_returning_binding(blk, first_ty, err);
788+
None => {
789+
for (id, ty) in [(first_id, second_ty), (second_id, first_ty)] {
790+
if let Some(id) = id
791+
&& let hir::Node::Block(blk) = self.tcx.hir().get(id)
792+
&& self.consider_returning_binding(blk, ty, err)
793+
{
794+
break;
795+
}
796+
}
810797
}
811798
}
812799
}
@@ -2884,8 +2871,10 @@ impl TyCategory {
28842871
}
28852872

28862873
impl<'tcx> InferCtxt<'_, 'tcx> {
2874+
/// Given a [`hir::Block`], get the span of its last expression or
2875+
/// statement, peeling off any inner blocks.
28872876
pub fn find_block_span(&self, block: &'tcx hir::Block<'tcx>) -> Span {
2888-
let block = block.peel_blocks();
2877+
let block = block.innermost_block();
28892878
if let Some(expr) = &block.expr {
28902879
expr.span
28912880
} else if let Some(stmt) = block.stmts.last() {
@@ -2897,27 +2886,30 @@ impl<'tcx> InferCtxt<'_, 'tcx> {
28972886
}
28982887
}
28992888

2889+
/// Given a [`hir::HirId`] for a block, get the span of its last expression
2890+
/// or statement, peeling off any inner blocks.
29002891
pub fn find_block_span_from_hir_id(&self, hir_id: hir::HirId) -> Span {
29012892
match self.tcx.hir().get(hir_id) {
29022893
hir::Node::Block(blk) => self.find_block_span(blk),
2903-
// The parser was in a weird state if either of these happen...
2894+
// The parser was in a weird state if either of these happen, but
2895+
// it's better not to panic.
29042896
hir::Node::Expr(e) => e.span,
29052897
_ => rustc_span::DUMMY_SP,
29062898
}
29072899
}
29082900

2901+
/// Be helpful when the user wrote `{... expr; }` and taking the `;` off
2902+
/// is enough to fix the error.
29092903
pub fn could_remove_semicolon(
29102904
&self,
29112905
blk: &'tcx hir::Block<'tcx>,
29122906
expected_ty: Ty<'tcx>,
29132907
) -> Option<(Span, StatementAsExpression)> {
2914-
let blk = blk.peel_blocks();
2908+
let blk = blk.innermost_block();
29152909
// Do not suggest if we have a tail expr.
29162910
if blk.expr.is_some() {
29172911
return None;
29182912
}
2919-
// Be helpful when the user wrote `{... expr;}` and
2920-
// taking the `;` off is enough to fix the error.
29212913
let last_stmt = blk.stmts.last()?;
29222914
let hir::StmtKind::Semi(ref last_expr) = last_stmt.kind else {
29232915
return None;
@@ -2987,13 +2979,15 @@ impl<'tcx> InferCtxt<'_, 'tcx> {
29872979
Some((span, needs_box))
29882980
}
29892981

2982+
/// Suggest returning a local binding with a compatible type if the block
2983+
/// has no return expression.
29902984
pub fn consider_returning_binding(
29912985
&self,
29922986
blk: &'tcx hir::Block<'tcx>,
29932987
expected_ty: Ty<'tcx>,
29942988
err: &mut Diagnostic,
29952989
) -> bool {
2996-
let blk = blk.peel_blocks();
2990+
let blk = blk.innermost_block();
29972991
// Do not suggest if we have a tail expr.
29982992
if blk.expr.is_some() {
29992993
return false;

compiler/rustc_typeck/src/check/_match.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
325325
};
326326

327327
let (error_sp, else_id) = if let ExprKind::Block(block, _) = &else_expr.kind {
328-
let block = block.peel_blocks();
328+
let block = block.innermost_block();
329329

330330
// Avoid overlapping spans that aren't as readable:
331331
// ```
@@ -366,7 +366,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
366366
};
367367

368368
let then_id = if let ExprKind::Block(block, _) = &then_expr.kind {
369-
let block = block.peel_blocks();
369+
let block = block.innermost_block();
370370
// Exclude overlapping spans
371371
if block.expr.is_none() && block.stmts.is_empty() {
372372
outer_span = None;

0 commit comments

Comments
 (0)