Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
26 changes: 26 additions & 0 deletions tests/ui/typeck/suggestions/suggest-add-wrapper-issue-145294.rs
Original file line number Diff line number Diff line change
@@ -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<Option<&str>, _>`,
// where `E` is still an unresolved inference variable.

fn foo() -> Result<Option<String>, ()> {
todo!()
}

#[derive(PartialEq, Debug)]
enum Bar<T, E> {
A(T),
B(E),
}

fn bar() -> Bar<String, ()> {
todo!()
}

fn main() {
assert_eq!(Ok(Some("hi")), foo()); //~ ERROR mismatched types [E0308]
assert_eq!(Bar::A("hi"), bar()); //~ ERROR mismatched types [E0308]
}
Original file line number Diff line number Diff line change
@@ -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<Option<&str>, _>`, found `Result<Option<String>, ()>`
|
= note: expected enum `Result<Option<&str>, _>`
found enum `Result<Option<String>, ()>`

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<String, ()>`
|
= note: expected enum `Bar<&str, _>`
found enum `Bar<String, ()>`

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0308`.
Loading