diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 625c7f38fbb40..afa7175238c6b 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1883,17 +1883,16 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { fcx.err_ctxt().report_mismatched_types(cause, fcx.param_env, expected, found, ty_err); let due_to_block = matches!(fcx.tcx.hir_node(block_or_return_id), hir::Node::Block(..)); - - let parent_id = fcx.tcx.parent_hir_id(block_or_return_id); - let parent = fcx.tcx.hir_node(parent_id); + let parent = fcx.tcx.parent_hir_node(block_or_return_id); if let Some(expr) = expression && let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(&hir::Closure { body, .. }), .. }) = parent - && !matches!(fcx.tcx.hir_body(body).value.kind, hir::ExprKind::Block(..)) { - fcx.suggest_missing_semicolon(&mut err, expr, expected, true); + let needs_block = + !matches!(fcx.tcx.hir_body(body).value.kind, hir::ExprKind::Block(..)); + fcx.suggest_missing_semicolon(&mut err, expr, expected, needs_block, true); } // Verify that this is a tail expression of a function, otherwise the // label pointing out the cause for the type coercion will be wrong @@ -1901,7 +1900,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { if let Some(expr) = expression && due_to_block { - fcx.suggest_missing_semicolon(&mut err, expr, expected, false); + fcx.suggest_missing_semicolon(&mut err, expr, expected, false, false); let pointing_at_return_type = fcx.suggest_mismatched_types_on_tail( &mut err, expr, diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 277396da19c13..25b58c7fd9d44 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -921,7 +921,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self, &cause, |mut err| { - self.suggest_missing_semicolon(&mut err, expr, e_ty, false); + self.suggest_missing_semicolon(&mut err, expr, e_ty, false, false); self.suggest_mismatched_types_on_tail( &mut err, expr, ty, e_ty, target_id, ); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index f9fc121593637..8f2665212b86b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -754,6 +754,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { expression: &'tcx hir::Expr<'tcx>, expected: Ty<'tcx>, needs_block: bool, + parent_is_closure: bool, ) { if expected.is_unit() { // `BlockTailExpression` only relevant if the tail expr would be @@ -789,6 +790,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } } + ExprKind::Path(..) | ExprKind::Lit(_) + if parent_is_closure + && !expression.span.in_external_macro(self.tcx.sess.source_map()) => + { + err.span_suggestion_verbose( + expression.span.shrink_to_lo(), + "consider ignoring the value", + "_ = ", + Applicability::MachineApplicable, + ); + } _ => (), } } diff --git a/tests/ui/typeck/closure-ty-mismatch-issue-128561.rs b/tests/ui/typeck/closure-ty-mismatch-issue-128561.rs new file mode 100644 index 0000000000000..589a90e71d6ec --- /dev/null +++ b/tests/ui/typeck/closure-ty-mismatch-issue-128561.rs @@ -0,0 +1,10 @@ +fn main() { + b"abc".iter().for_each(|x| x); //~ ERROR: mismatched types + + b"abc".iter().for_each(|x| dbg!(x)); //~ ERROR: mismatched types + + b"abc".iter().for_each(|x| { + println!("{}", x); + x //~ ERROR: mismatched types + }) +} diff --git a/tests/ui/typeck/closure-ty-mismatch-issue-128561.stderr b/tests/ui/typeck/closure-ty-mismatch-issue-128561.stderr new file mode 100644 index 0000000000000..31acc5bb10ec0 --- /dev/null +++ b/tests/ui/typeck/closure-ty-mismatch-issue-128561.stderr @@ -0,0 +1,28 @@ +error[E0308]: mismatched types + --> $DIR/closure-ty-mismatch-issue-128561.rs:2:32 + | +LL | b"abc".iter().for_each(|x| x); + | ^ expected `()`, found `&u8` + | +help: consider ignoring the value + | +LL | b"abc".iter().for_each(|x| _ = x); + | +++ + +error[E0308]: mismatched types + --> $DIR/closure-ty-mismatch-issue-128561.rs:4:32 + | +LL | b"abc".iter().for_each(|x| dbg!(x)); + | ^^^^^^^ expected `()`, found `&u8` + | + = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0308]: mismatched types + --> $DIR/closure-ty-mismatch-issue-128561.rs:8:9 + | +LL | x + | ^ expected `()`, found `&u8` + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0308`.