From d61b8bda9373d8b46759c94949c943ab17b468c6 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Tue, 17 Jun 2025 14:13:54 +0800 Subject: [PATCH 1/2] Add test suggest-compatible-variants-macro-issue-142359.rs Signed-off-by: xizheyin --- ...-compatible-variants-macro-issue-142359.rs | 11 +++++++++++ ...patible-variants-macro-issue-142359.stderr | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 tests/ui/typeck/suggestions/suggest-compatible-variants-macro-issue-142359.rs create mode 100644 tests/ui/typeck/suggestions/suggest-compatible-variants-macro-issue-142359.stderr diff --git a/tests/ui/typeck/suggestions/suggest-compatible-variants-macro-issue-142359.rs b/tests/ui/typeck/suggestions/suggest-compatible-variants-macro-issue-142359.rs new file mode 100644 index 0000000000000..36d0215686477 --- /dev/null +++ b/tests/ui/typeck/suggestions/suggest-compatible-variants-macro-issue-142359.rs @@ -0,0 +1,11 @@ +// Make sure we don't suggest compatible variants inside macro. (issue #142359) +use std::ops::ControlFlow; + +fn main(){ + let x: Result = Err(1); + + let v= match x { + Err(r) => ControlFlow::Break(r), + Ok(r) => { println!("A")} //~ ERROR `match` arms have incompatible types [E0308] + }; +} diff --git a/tests/ui/typeck/suggestions/suggest-compatible-variants-macro-issue-142359.stderr b/tests/ui/typeck/suggestions/suggest-compatible-variants-macro-issue-142359.stderr new file mode 100644 index 0000000000000..f81d961129a4b --- /dev/null +++ b/tests/ui/typeck/suggestions/suggest-compatible-variants-macro-issue-142359.stderr @@ -0,0 +1,19 @@ +error[E0308]: `match` arms have incompatible types + --> $DIR/suggest-compatible-variants-macro-issue-142359.rs:9:20 + | +LL | let v= match x { + | ____________- +LL | | Err(r) => ControlFlow::Break(r), + | | --------------------- this is found to be of type `ControlFlow` +LL | | Ok(r) => { println!("A")} + | | ^^^^^^^^^^^^^ expected `ControlFlow`, found `()` +LL | | }; + | |_____- `match` arms have incompatible types + | + = note: expected enum `ControlFlow` + found unit type `()` + = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0308`. From 6f33a8f62f51371db7daf1eb4cd9a5cf9683e82f Mon Sep 17 00:00:00 2001 From: xizheyin Date: Tue, 17 Jun 2025 14:19:36 +0800 Subject: [PATCH 2/2] Do not suggest compatible variants inside macro Signed-off-by: xizheyin --- .../rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 13 +++++++++---- ...st-compatible-variants-macro-issue-142359.stderr | 4 ++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index dd6eb73a3a0aa..1b987fd4bbf6f 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2409,16 +2409,21 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (open, close) = match ctor_kind { Some(CtorKind::Fn) => ("(".to_owned(), ")"), None => (format!(" {{ {field_name}: "), " }"), - Some(CtorKind::Const) => unreachable!("unit variants don't have fields"), }; - // Suggest constructor as deep into the block tree as possible. - // This fixes https://github.com/rust-lang/rust/issues/101065, - // and also just helps make the most minimal suggestions. + // Find the deepest expression in the block tree while staying within the same + // context. This ensures that suggestions point to user-visible code + // rather than macro-expanded internal code. + // + // For example, with `println!("A")`, we want to suggest wrapping the entire + // `println!("A")` call, not some internal macro-generated code. + // See #101065, #142359 let mut expr = expr; while let hir::ExprKind::Block(block, _) = &expr.kind && let Some(expr_) = &block.expr + // Only traverse blocks in same context + && expr_.span.eq_ctxt(expr.span) { expr = expr_ } diff --git a/tests/ui/typeck/suggestions/suggest-compatible-variants-macro-issue-142359.stderr b/tests/ui/typeck/suggestions/suggest-compatible-variants-macro-issue-142359.stderr index f81d961129a4b..3d1ed4bb39ee4 100644 --- a/tests/ui/typeck/suggestions/suggest-compatible-variants-macro-issue-142359.stderr +++ b/tests/ui/typeck/suggestions/suggest-compatible-variants-macro-issue-142359.stderr @@ -13,6 +13,10 @@ LL | | }; = note: expected enum `ControlFlow` found unit type `()` = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) +help: try wrapping the expression in `std::ops::ControlFlow::Continue` + | +LL | Ok(r) => std::ops::ControlFlow::Continue({ println!("A")}) + | ++++++++++++++++++++++++++++++++ + error: aborting due to 1 previous error