diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 744b521f15db2..6bfcedd992207 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -2342,6 +2342,17 @@ impl<'a, 'b, 'tcx> FnCallDiagCtxt<'a, 'b, 'tcx> { provided_span, format!("unexpected argument{idx}{provided_ty_name}"), )); + if self.provided_arg_tys.len() == 1 + && let Some(span) = self.maybe_suggest_expect_for_unwrap(provided_ty) + { + err.span_suggestion_verbose( + span, + "did you mean to use `expect`?", + "expect", + Applicability::MaybeIncorrect, + ); + continue; + } let mut span = provided_span; if span.can_be_used_for_suggestions() && self.call_metadata.error_span.can_be_used_for_suggestions() @@ -2772,6 +2783,22 @@ impl<'a, 'b, 'tcx> FnCallDiagCtxt<'a, 'b, 'tcx> { (suggestion_span, suggestion) } + + fn maybe_suggest_expect_for_unwrap(&self, provided_ty: Ty<'tcx>) -> Option { + let tcx = self.tcx(); + if let Some(call_ident) = self.call_metadata.call_ident + && call_ident.name == sym::unwrap + && let Some(callee_ty) = self.callee_ty + && let ty::Adt(adt, _) = callee_ty.peel_refs().kind() + && (tcx.is_diagnostic_item(sym::Option, adt.did()) + || tcx.is_diagnostic_item(sym::Result, adt.did())) + && self.may_coerce(provided_ty, Ty::new_static_str(tcx)) + { + Some(call_ident.span) + } else { + None + } + } } struct ArgMatchingCtxt<'a, 'b, 'tcx> { diff --git a/tests/ui/did_you_mean/expect-instead-of-unwrap.rs b/tests/ui/did_you_mean/expect-instead-of-unwrap.rs new file mode 100644 index 0000000000000..7ed11f94fc946 --- /dev/null +++ b/tests/ui/did_you_mean/expect-instead-of-unwrap.rs @@ -0,0 +1,6 @@ +fn main() { + Ok(42).unwrap("wow"); + //~^ ERROR this method takes 0 arguments but 1 argument was supplied + Some(42).unwrap("wow"); + //~^ ERROR this method takes 0 arguments but 1 argument was supplied +} diff --git a/tests/ui/did_you_mean/expect-instead-of-unwrap.stderr b/tests/ui/did_you_mean/expect-instead-of-unwrap.stderr new file mode 100644 index 0000000000000..e3ad416b6e9bb --- /dev/null +++ b/tests/ui/did_you_mean/expect-instead-of-unwrap.stderr @@ -0,0 +1,31 @@ +error[E0061]: this method takes 0 arguments but 1 argument was supplied + --> $DIR/expect-instead-of-unwrap.rs:2:12 + | +LL | Ok(42).unwrap("wow"); + | ^^^^^^ ----- unexpected argument of type `&'static str` + | +note: method defined here + --> $SRC_DIR/core/src/result.rs:LL:COL +help: did you mean to use `expect`? + | +LL - Ok(42).unwrap("wow"); +LL + Ok(42).expect("wow"); + | + +error[E0061]: this method takes 0 arguments but 1 argument was supplied + --> $DIR/expect-instead-of-unwrap.rs:4:14 + | +LL | Some(42).unwrap("wow"); + | ^^^^^^ ----- unexpected argument of type `&'static str` + | +note: method defined here + --> $SRC_DIR/core/src/option.rs:LL:COL +help: did you mean to use `expect`? + | +LL - Some(42).unwrap("wow"); +LL + Some(42).expect("wow"); + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0061`.