diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 991c996dffbf7..2e62c2c43f46b 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -2346,6 +2346,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() @@ -2776,6 +2787,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/library/alloc/src/lib.rs b/library/alloc/src/lib.rs index 344b46f01b756..d85a63999fe03 100644 --- a/library/alloc/src/lib.rs +++ b/library/alloc/src/lib.rs @@ -106,6 +106,7 @@ #![feature(const_destruct)] #![feature(const_eval_select)] #![feature(const_heap)] +#![feature(const_index)] #![feature(const_option_ops)] #![feature(const_try)] #![feature(copied_into_inner)] diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 5a0f6d3dc571c..b633beae89136 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -3747,7 +3747,8 @@ impl ExtendFromWithinSpec for Vec { //////////////////////////////////////////////////////////////////////////////// #[stable(feature = "rust1", since = "1.0.0")] -impl ops::Deref for Vec { +#[rustc_const_unstable(feature = "const_convert", issue = "143773")] +impl const ops::Deref for Vec { type Target = [T]; #[inline] @@ -3757,7 +3758,8 @@ impl ops::Deref for Vec { } #[stable(feature = "rust1", since = "1.0.0")] -impl ops::DerefMut for Vec { +#[rustc_const_unstable(feature = "const_convert", issue = "143773")] +impl const ops::DerefMut for Vec { #[inline] fn deref_mut(&mut self) -> &mut [T] { self.as_mut_slice() @@ -3822,7 +3824,8 @@ impl Hash for Vec { } #[stable(feature = "rust1", since = "1.0.0")] -impl, A: Allocator> Index for Vec { +#[rustc_const_unstable(feature = "const_index", issue = "143775")] +impl, A: Allocator> const Index for Vec { type Output = I::Output; #[inline] @@ -3832,7 +3835,8 @@ impl, A: Allocator> Index for Vec { } #[stable(feature = "rust1", since = "1.0.0")] -impl, A: Allocator> IndexMut for Vec { +#[rustc_const_unstable(feature = "const_index", issue = "143775")] +impl, A: Allocator> const IndexMut for Vec { #[inline] fn index_mut(&mut self, index: I) -> &mut Self::Output { IndexMut::index_mut(&mut **self, index) diff --git a/library/core/src/num/error.rs b/library/core/src/num/error.rs index f01c0f92567ae..8cd065630cd88 100644 --- a/library/core/src/num/error.rs +++ b/library/core/src/num/error.rs @@ -122,7 +122,7 @@ pub enum IntErrorKind { /// This variant will be emitted when converting an integer that is not a power of /// two. This is required in some cases such as constructing an [`Alignment`]. /// - /// [`Alignment`]: core::ptr::Alignment "ptr::Alignment" + /// [`Alignment`]: core::mem::Alignment "mem::Alignment" #[unstable(feature = "try_from_int_error_kind", issue = "153978")] // Also, #[unstable(feature = "ptr_alignment_type", issue = "102070")] NotAPowerOfTwo, diff --git a/tests/ui/consts/issue-94675.rs b/tests/ui/consts/issue-94675.rs index 0553b676bc3e9..73ab2c7655800 100644 --- a/tests/ui/consts/issue-94675.rs +++ b/tests/ui/consts/issue-94675.rs @@ -9,8 +9,7 @@ struct Foo<'a> { impl<'a> Foo<'a> { const fn spam(&mut self, baz: &mut Vec) { self.bar[0] = baz.len(); - //~^ ERROR: `Vec: [const] Index<_>` is not satisfied - //~| ERROR: `Vec: [const] IndexMut` is not satisfied + //~^ ERROR: `IndexMut` is not yet stable as a const trait } } diff --git a/tests/ui/consts/issue-94675.stderr b/tests/ui/consts/issue-94675.stderr index ab7a76a90e02c..3e89e37814fad 100644 --- a/tests/ui/consts/issue-94675.stderr +++ b/tests/ui/consts/issue-94675.stderr @@ -1,21 +1,13 @@ -error[E0277]: the trait bound `Vec: [const] Index<_>` is not satisfied - --> $DIR/issue-94675.rs:11:9 +error: `IndexMut` is not yet stable as a const trait + --> $DIR/issue-94675.rs:11:17 | LL | self.bar[0] = baz.len(); - | ^^^^^^^^^^^ + | ^^^ | -note: trait `Index` is implemented but not `const` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL - -error[E0277]: the trait bound `Vec: [const] IndexMut` is not satisfied - --> $DIR/issue-94675.rs:11:9 +help: add `#![feature(const_index)]` to the crate attributes to enable | -LL | self.bar[0] = baz.len(); - | ^^^^^^^^^^^ +LL + #![feature(const_index)] | -note: trait `IndexMut` is implemented but not `const` - --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0277`. 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`.