From 4b15959218a4e856d95329d7752b1c55d5922de5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 26 Sep 2023 23:46:10 +0000 Subject: [PATCH] Add context to `let: Ty = loop { break };` We weren't accounting for the case where `break` was immediately within the `loop` block. --- compiler/rustc_hir_typeck/src/demand.rs | 1 + tests/ui/issues/issue-27042.stderr | 7 ++++++- tests/ui/loops/loop-labeled-break-value.stderr | 15 ++++++++++++--- tests/ui/loops/loop-properly-diverging-2.stderr | 5 ++++- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index 31e773585d196..256a4bf944910 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -545,6 +545,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Climb the HIR tree to see if the current `Expr` is part of a `break;` statement. let Some( hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Semi(&ref p), .. }) + | hir::Node::Block(hir::Block { expr: Some(&ref p), .. }) | hir::Node::Expr(&ref p), ) = self.tcx.hir().find(parent_id) else { diff --git a/tests/ui/issues/issue-27042.stderr b/tests/ui/issues/issue-27042.stderr index 69eedeb8025a6..01532de999e3b 100644 --- a/tests/ui/issues/issue-27042.stderr +++ b/tests/ui/issues/issue-27042.stderr @@ -11,8 +11,13 @@ LL | | while true { break }; // but here we cite the whole loop error[E0308]: mismatched types --> $DIR/issue-27042.rs:6:16 | +LL | let _: i32 = + | - expected because of this assignment +LL | 'a: // in this case, the citation is just the `break`: LL | loop { break }; - | ^^^^^ expected `i32`, found `()` + | ---- ^^^^^ expected `i32`, found `()` + | | + | this loop is expected to be of type `i32` | help: give it a value of the expected type | diff --git a/tests/ui/loops/loop-labeled-break-value.stderr b/tests/ui/loops/loop-labeled-break-value.stderr index f233670e8c4c1..694d6c306f645 100644 --- a/tests/ui/loops/loop-labeled-break-value.stderr +++ b/tests/ui/loops/loop-labeled-break-value.stderr @@ -2,7 +2,10 @@ error[E0308]: mismatched types --> $DIR/loop-labeled-break-value.rs:3:29 | LL | let _: i32 = loop { break }; - | ^^^^^ expected `i32`, found `()` + | - ---- ^^^^^ expected `i32`, found `()` + | | | + | | this loop is expected to be of type `i32` + | expected because of this assignment | help: give it a value of the expected type | @@ -13,7 +16,10 @@ error[E0308]: mismatched types --> $DIR/loop-labeled-break-value.rs:6:37 | LL | let _: i32 = 'inner: loop { break 'inner }; - | ^^^^^^^^^^^^ expected `i32`, found `()` + | - ---- ^^^^^^^^^^^^ expected `i32`, found `()` + | | | + | | this loop is expected to be of type `i32` + | expected because of this assignment | help: give it a value of the expected type | @@ -24,7 +30,10 @@ error[E0308]: mismatched types --> $DIR/loop-labeled-break-value.rs:9:45 | LL | let _: i32 = 'inner2: loop { loop { break 'inner2 } }; - | ^^^^^^^^^^^^^ expected `i32`, found `()` + | - ---- ^^^^^^^^^^^^^ expected `i32`, found `()` + | | | + | | this loop is expected to be of type `i32` + | expected because of this assignment | help: give it a value of the expected type | diff --git a/tests/ui/loops/loop-properly-diverging-2.stderr b/tests/ui/loops/loop-properly-diverging-2.stderr index dc60657ee142b..1d1ae60cda174 100644 --- a/tests/ui/loops/loop-properly-diverging-2.stderr +++ b/tests/ui/loops/loop-properly-diverging-2.stderr @@ -2,7 +2,10 @@ error[E0308]: mismatched types --> $DIR/loop-properly-diverging-2.rs:2:23 | LL | let x: i32 = loop { break }; - | ^^^^^ expected `i32`, found `()` + | - ---- ^^^^^ expected `i32`, found `()` + | | | + | | this loop is expected to be of type `i32` + | expected because of this assignment | help: give it a value of the expected type |