diff --git a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs index e7fd89c140fc7..bc288b161f3b8 100644 --- a/compiler/rustc_borrowck/src/diagnostics/move_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/move_errors.rs @@ -4,7 +4,7 @@ use rustc_middle::ty; use rustc_mir_dataflow::move_paths::{ IllegalMoveOrigin, IllegalMoveOriginKind, LookupResult, MoveError, MovePathIndex, }; -use rustc_span::{sym, Span}; +use rustc_span::{sym, BytePos, Span}; use crate::diagnostics::UseSpans; use crate::prefixes::PrefixSet; @@ -414,11 +414,23 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> { && use_spans.map_or(true, |v| !v.for_closure()) && !has_complex_bindings { - err.span_suggestion_verbose( + let span = match use_spans { + Some(UseSpans::FnSelfUse { var_span, fn_call_span, .. }) => { + // `fn_call_span` is the span of `unwrap()` + // This gets the 'variable' span excluding the unwrap + let span = var_span.until(fn_call_span); + + // Unfortunately the new span has a "." on the end which makes + // the suggestion format strangely, so we adjust the hi bound manually + span.with_hi(span.hi() - BytePos(1)) + } + _ => span, + }; + err.span_suggestions( span.shrink_to_hi(), &format!("consider borrowing the `{}`'s content", diag_name.unwrap()), - ".as_ref()".to_string(), - Applicability::MaybeIncorrect, + vec![".as_ref()".to_string(), ".as_mut()".to_string()].into_iter(), + Applicability::MachineApplicable, ); } else if let Some(use_spans) = use_spans { self.explain_captures( diff --git a/src/test/ui/borrowck/issue-96438.rs b/src/test/ui/borrowck/issue-96438.rs new file mode 100644 index 0000000000000..a180f86ceeb63 --- /dev/null +++ b/src/test/ui/borrowck/issue-96438.rs @@ -0,0 +1,13 @@ +use std::cell::RefCell; + +fn foo(cell: &RefCell>>) { + cell.borrow_mut().unwrap().pop().unwrap(); + //~^ ERROR cannot move out of dereference of `RefMut<'_, Option>>` [E0507] + //~| NOTE move occurs because value has type `Option>`, which does not implement the `Copy` trait + //~| HELP consider borrowing the `Option`'s content +} + +fn main() { + let cell = RefCell::new(None); + foo(&cell); +} diff --git a/src/test/ui/borrowck/issue-96438.stderr b/src/test/ui/borrowck/issue-96438.stderr new file mode 100644 index 0000000000000..5294b5767ca1c --- /dev/null +++ b/src/test/ui/borrowck/issue-96438.stderr @@ -0,0 +1,16 @@ +error[E0507]: cannot move out of dereference of `RefMut<'_, Option>>` + --> $DIR/issue-96438.rs:4:5 + | +LL | cell.borrow_mut().unwrap().pop().unwrap(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `Option>`, which does not implement the `Copy` trait + | +help: consider borrowing the `Option`'s content + | +LL | cell.borrow_mut().as_mut().unwrap().pop().unwrap(); + | +++++++++ +LL | cell.borrow_mut().as_ref().unwrap().pop().unwrap(); + | +++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0507`. diff --git a/src/test/ui/suggestions/option-content-move.fixed b/src/test/ui/suggestions/option-content-move.fixed index ba16bcc8a336d..710a6172b0e87 100644 --- a/src/test/ui/suggestions/option-content-move.fixed +++ b/src/test/ui/suggestions/option-content-move.fixed @@ -8,7 +8,7 @@ impl LipogramCorpora { pub fn validate_all(&mut self) -> Result<(), char> { for selection in &self.selections { if selection.1.is_some() { - if selection.1.as_ref().unwrap().contains(selection.0) { + if selection.1.as_ref().as_mut().unwrap().contains(selection.0) { //~^ ERROR cannot move out of `selection.1` return Err(selection.0); } @@ -26,7 +26,7 @@ impl LipogramCorpora2 { pub fn validate_all(&mut self) -> Result<(), char> { for selection in &self.selections { if selection.1.is_ok() { - if selection.1.as_ref().unwrap().contains(selection.0) { + if selection.1.as_ref().as_mut().unwrap().contains(selection.0) { //~^ ERROR cannot move out of `selection.1` return Err(selection.0); } diff --git a/src/test/ui/suggestions/option-content-move.stderr b/src/test/ui/suggestions/option-content-move.stderr index a9e540084e590..950af8c4f2779 100644 --- a/src/test/ui/suggestions/option-content-move.stderr +++ b/src/test/ui/suggestions/option-content-move.stderr @@ -6,6 +6,8 @@ LL | if selection.1.unwrap().contains(selection.0) { | help: consider borrowing the `Option`'s content | +LL | if selection.1.as_mut().unwrap().contains(selection.0) { + | +++++++++ LL | if selection.1.as_ref().unwrap().contains(selection.0) { | +++++++++ @@ -17,6 +19,8 @@ LL | if selection.1.unwrap().contains(selection.0) { | help: consider borrowing the `Result`'s content | +LL | if selection.1.as_mut().unwrap().contains(selection.0) { + | +++++++++ LL | if selection.1.as_ref().unwrap().contains(selection.0) { | +++++++++