From 12d1665d1163d62de0dd2c2fcb2f508fea8123f1 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Wed, 13 Aug 2025 23:17:29 +0800 Subject: [PATCH 1/2] Add test suggest-add-wrapper-issue-145294 Signed-off-by: xizheyin --- .../suggest-add-wrapper-issue-145294.rs | 26 +++++++++++++++++ .../suggest-add-wrapper-issue-145294.stderr | 29 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 tests/ui/typeck/suggestions/suggest-add-wrapper-issue-145294.rs create mode 100644 tests/ui/typeck/suggestions/suggest-add-wrapper-issue-145294.stderr diff --git a/tests/ui/typeck/suggestions/suggest-add-wrapper-issue-145294.rs b/tests/ui/typeck/suggestions/suggest-add-wrapper-issue-145294.rs new file mode 100644 index 0000000000000..cfe167cf88d76 --- /dev/null +++ b/tests/ui/typeck/suggestions/suggest-add-wrapper-issue-145294.rs @@ -0,0 +1,26 @@ +// Suppress the suggestion that adding a wrapper. +// When expected_ty and expr_ty are the same ADT, +// we prefer to compare their internal generic params, +// so when the current variant corresponds to an unresolved infer, +// the suggestion is rejected. +// e.g. `Ok(Some("hi"))` is type of `Result, _>`, +// where `E` is still an unresolved inference variable. + +fn foo() -> Result, ()> { + todo!() +} + +#[derive(PartialEq, Debug)] +enum Bar { + A(T), + B(E), +} + +fn bar() -> Bar { + todo!() +} + +fn main() { + assert_eq!(Ok(Some("hi")), foo()); //~ ERROR mismatched types [E0308] + assert_eq!(Bar::A("hi"), bar()); //~ ERROR mismatched types [E0308] +} diff --git a/tests/ui/typeck/suggestions/suggest-add-wrapper-issue-145294.stderr b/tests/ui/typeck/suggestions/suggest-add-wrapper-issue-145294.stderr new file mode 100644 index 0000000000000..ef5eeb29cf504 --- /dev/null +++ b/tests/ui/typeck/suggestions/suggest-add-wrapper-issue-145294.stderr @@ -0,0 +1,29 @@ +error[E0308]: mismatched types + --> $DIR/suggest-add-wrapper-issue-145294.rs:24:32 + | +LL | assert_eq!(Ok(Some("hi")), foo()); + | ^^^^^ expected `Result, _>`, found `Result, ()>` + | + = note: expected enum `Result, _>` + found enum `Result, ()>` +help: try wrapping the expression in `Err` + | +LL | assert_eq!(Ok(Some("hi")), Err(foo())); + | ++++ + + +error[E0308]: mismatched types + --> $DIR/suggest-add-wrapper-issue-145294.rs:25:30 + | +LL | assert_eq!(Bar::A("hi"), bar()); + | ^^^^^ expected `Bar<&str, _>`, found `Bar` + | + = note: expected enum `Bar<&str, _>` + found enum `Bar` +help: try wrapping the expression in `Bar::B` + | +LL | assert_eq!(Bar::A("hi"), Bar::B(bar())); + | +++++++ + + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From e0cc2beea3d52ce34b16df9730b65a670c68c623 Mon Sep 17 00:00:00 2001 From: xizheyin Date: Wed, 13 Aug 2025 23:23:18 +0800 Subject: [PATCH 2/2] Suppress wrapper suggestion when expected and actual ty are the same adt and the variant is unresolved Signed-off-by: xizheyin --- compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs | 9 +++++++++ .../suggestions/suggest-add-wrapper-issue-145294.stderr | 8 -------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs index 2345cdab208e3..c44e007dbdb82 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs @@ -2378,6 +2378,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .filter_map(|variant| { let sole_field = &variant.single_field(); + // When expected_ty and expr_ty are the same ADT, we prefer to compare their internal generic params, + // When the current variant has a sole field whose type is still an unresolved inference variable, + // suggestions would be often wrong. So suppress the suggestion. See #145294. + if let (ty::Adt(exp_adt, _), ty::Adt(act_adt, _)) = (expected.kind(), expr_ty.kind()) + && exp_adt.did() == act_adt.did() + && sole_field.ty(self.tcx, args).is_ty_var() { + return None; + } + let field_is_local = sole_field.did.is_local(); let field_is_accessible = sole_field.vis.is_accessible_from(expr.hir_id.owner.def_id, self.tcx) diff --git a/tests/ui/typeck/suggestions/suggest-add-wrapper-issue-145294.stderr b/tests/ui/typeck/suggestions/suggest-add-wrapper-issue-145294.stderr index ef5eeb29cf504..5e4ad13221046 100644 --- a/tests/ui/typeck/suggestions/suggest-add-wrapper-issue-145294.stderr +++ b/tests/ui/typeck/suggestions/suggest-add-wrapper-issue-145294.stderr @@ -6,10 +6,6 @@ LL | assert_eq!(Ok(Some("hi")), foo()); | = note: expected enum `Result, _>` found enum `Result, ()>` -help: try wrapping the expression in `Err` - | -LL | assert_eq!(Ok(Some("hi")), Err(foo())); - | ++++ + error[E0308]: mismatched types --> $DIR/suggest-add-wrapper-issue-145294.rs:25:30 @@ -19,10 +15,6 @@ LL | assert_eq!(Bar::A("hi"), bar()); | = note: expected enum `Bar<&str, _>` found enum `Bar` -help: try wrapping the expression in `Bar::B` - | -LL | assert_eq!(Bar::A("hi"), Bar::B(bar())); - | +++++++ + error: aborting due to 2 previous errors