From 3d50334314cb41f2334f201458d4be0aa15ae203 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 16 Jan 2025 10:25:59 +0800 Subject: [PATCH 1/4] Add ignore value suggestion in closure body --- compiler/rustc_hir_typeck/src/coercion.rs | 7 ++--- compiler/rustc_hir_typeck/src/expr.rs | 2 +- .../src/fn_ctxt/suggestions.rs | 13 ++++++++++ .../closure-ty-mismatch-issue-128561.rs | 10 +++++++ .../closure-ty-mismatch-issue-128561.stderr | 26 +++++++++++++++++++ 5 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 tests/ui/typeck/closure-ty-mismatch-issue-128561.rs create mode 100644 tests/ui/typeck/closure-ty-mismatch-issue-128561.stderr diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 625c7f38fbb40..2217eb33062d7 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1891,9 +1891,10 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { 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 +1902,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..f8d860cf7b7ac 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,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } } + ExprKind::Path(..) | ExprKind::Lit(_) if parent_is_closure => { + err.span_suggestion( + expression.span.shrink_to_lo(), + "consider ignore the value here", + "_ = ", + if in_external_macro(self.tcx.sess, expression.span) { + Applicability::MaybeIncorrect + } else { + 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..f9b606cd52da7 --- /dev/null +++ b/tests/ui/typeck/closure-ty-mismatch-issue-128561.stderr @@ -0,0 +1,26 @@ +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 ignore the value here: `_ =` + +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`. From 8cddffb74ef7fa75767c710e9f85bd4389159adb Mon Sep 17 00:00:00 2001 From: Yukang Date: Fri, 17 Jan 2025 08:19:17 +0800 Subject: [PATCH 2/4] Update compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs Co-authored-by: Esteban Kuber --- compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index f8d860cf7b7ac..a34f3d27fb6c5 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -793,7 +793,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ExprKind::Path(..) | ExprKind::Lit(_) if parent_is_closure => { err.span_suggestion( expression.span.shrink_to_lo(), - "consider ignore the value here", + "consider ignoring the value", "_ = ", if in_external_macro(self.tcx.sess, expression.span) { Applicability::MaybeIncorrect From d6d9c2e7516c687553480a4e171f89dfc22009dd Mon Sep 17 00:00:00 2001 From: Yukang Date: Fri, 17 Jan 2025 08:19:23 +0800 Subject: [PATCH 3/4] Update compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs Co-authored-by: Esteban Kuber --- compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 2 +- .../ui/typeck/closure-ty-mismatch-issue-128561.stderr | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index a34f3d27fb6c5..a31abef43757b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -791,7 +791,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } ExprKind::Path(..) | ExprKind::Lit(_) if parent_is_closure => { - err.span_suggestion( + err.span_suggestion_verbose( expression.span.shrink_to_lo(), "consider ignoring the value", "_ = ", diff --git a/tests/ui/typeck/closure-ty-mismatch-issue-128561.stderr b/tests/ui/typeck/closure-ty-mismatch-issue-128561.stderr index f9b606cd52da7..31acc5bb10ec0 100644 --- a/tests/ui/typeck/closure-ty-mismatch-issue-128561.stderr +++ b/tests/ui/typeck/closure-ty-mismatch-issue-128561.stderr @@ -2,10 +2,12 @@ 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 ignore the value here: `_ =` + | ^ 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 From 774ab462d692615d65dc79bb36685ac5cfebd7d4 Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 17 Jan 2025 12:15:25 +0800 Subject: [PATCH 4/4] code cleanup and do not suggest for external macro except we get better solution --- compiler/rustc_hir_typeck/src/coercion.rs | 4 +--- compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 11 +++++------ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs index 2217eb33062d7..afa7175238c6b 100644 --- a/compiler/rustc_hir_typeck/src/coercion.rs +++ b/compiler/rustc_hir_typeck/src/coercion.rs @@ -1883,9 +1883,7 @@ 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, .. }), diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index a31abef43757b..8f2665212b86b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -790,16 +790,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } } - ExprKind::Path(..) | ExprKind::Lit(_) if parent_is_closure => { + 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", "_ = ", - if in_external_macro(self.tcx.sess, expression.span) { - Applicability::MaybeIncorrect - } else { - Applicability::MachineApplicable - }, + Applicability::MachineApplicable, ); } _ => (),