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.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..5e4ad13221046 --- /dev/null +++ b/tests/ui/typeck/suggestions/suggest-add-wrapper-issue-145294.stderr @@ -0,0 +1,21 @@ +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, ()>` + +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` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`.