diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index c4add4dbdfb..e19b0664461 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -874,7 +874,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let found = self.resolve_vars_with_obligations(found); let in_loop = self.is_loop(id) - || self.tcx.hir().parent_iter(id).any(|(parent_id, _)| self.is_loop(parent_id)); + || self + .tcx + .hir() + .parent_iter(id) + .take_while(|(_, node)| { + // look at parents until we find the first body owner + node.body_id().is_none() + }) + .any(|(parent_id, _)| self.is_loop(parent_id)); let in_local_statement = self.is_local_statement(id) || self diff --git a/tests/ui/loops/dont-suggest-break-thru-item.rs b/tests/ui/loops/dont-suggest-break-thru-item.rs new file mode 100644 index 00000000000..b46ba89e81d --- /dev/null +++ b/tests/ui/loops/dont-suggest-break-thru-item.rs @@ -0,0 +1,55 @@ +// edition:2021 + +#![feature(inline_const)] + +fn closure() { + loop { + let closure = || { + if true { + Err(1) + //~^ ERROR mismatched types + } + + Ok(()) + }; + } +} + +fn async_block() { + loop { + let fut = async { + if true { + Err(1) + //~^ ERROR mismatched types + } + + Ok(()) + }; + } +} + +fn fn_item() { + let _ = loop { + fn foo() -> Result<(), ()> { + if true { + Err(1) + //~^ ERROR mismatched types + } + Err(()) + } + }; +} + +fn const_block() { + let _ = loop { + const { + if true { + Err(1) + //~^ ERROR mismatched types + } + Err(()) + }; + }; +} + +fn main() {} diff --git a/tests/ui/loops/dont-suggest-break-thru-item.stderr b/tests/ui/loops/dont-suggest-break-thru-item.stderr new file mode 100644 index 00000000000..4fce4715119 --- /dev/null +++ b/tests/ui/loops/dont-suggest-break-thru-item.stderr @@ -0,0 +1,55 @@ +error[E0308]: mismatched types + --> $DIR/dont-suggest-break-thru-item.rs:9:17 + | +LL | / if true { +LL | | Err(1) + | | ^^^^^^ expected `()`, found `Result<_, {integer}>` +LL | | +LL | | } + | |_____________- expected this to be `()` + | + = note: expected unit type `()` + found enum `Result<_, {integer}>` + +error[E0308]: mismatched types + --> $DIR/dont-suggest-break-thru-item.rs:22:17 + | +LL | / if true { +LL | | Err(1) + | | ^^^^^^ expected `()`, found `Result<_, {integer}>` +LL | | +LL | | } + | |_____________- expected this to be `()` + | + = note: expected unit type `()` + found enum `Result<_, {integer}>` + +error[E0308]: mismatched types + --> $DIR/dont-suggest-break-thru-item.rs:35:17 + | +LL | / if true { +LL | | Err(1) + | | ^^^^^^ expected `()`, found `Result<_, {integer}>` +LL | | +LL | | } + | |_____________- expected this to be `()` + | + = note: expected unit type `()` + found enum `Result<_, {integer}>` + +error[E0308]: mismatched types + --> $DIR/dont-suggest-break-thru-item.rs:47:17 + | +LL | / if true { +LL | | Err(1) + | | ^^^^^^ expected `()`, found `Result<_, {integer}>` +LL | | +LL | | } + | |_____________- expected this to be `()` + | + = note: expected unit type `()` + found enum `Result<_, {integer}>` + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`.