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
4 changes: 3 additions & 1 deletion compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1377,7 +1377,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
});
if is_option_or_result && maybe_reinitialized_locations_is_empty {
err.subdiagnostic(CaptureReasonLabel::BorrowContent { var_span });
err.subdiagnostic(CaptureReasonLabel::BorrowContent {
var_span: var_span.shrink_to_hi(),
});
}
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
let ty = moved_place.ty(self.body, tcx).ty;
Expand Down
13 changes: 12 additions & 1 deletion compiler/rustc_borrowck/src/session_diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,18 @@ pub(crate) enum CaptureReasonLabel<'a> {
is_move_msg: bool,
is_loop_message: bool,
},
#[label("help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents")]
#[suggestion(
"consider calling `.as_ref()` to borrow the value's contents",
applicability = "maybe-incorrect",
code = ".as_ref()",
style = "verbose"
)]
#[suggestion(
"consider calling `.as_mut()` to mutably borrow the value's contents",
applicability = "maybe-incorrect",
code = ".as_mut()",
style = "verbose"
)]
BorrowContent {
#[primary_span]
var_span: Span,
Expand Down
9 changes: 8 additions & 1 deletion tests/ui/borrowck/suggest-as-ref-on-mut-closure.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@ error[E0507]: cannot move out of `*cb` which is behind a mutable reference
LL | cb.map(|cb| cb());
| ^^ -------------- `*cb` moved due to this method call
| |
| help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
| move occurs because `*cb` has type `Option<&mut dyn FnMut()>`, which does not implement the `Copy` trait
|
note: `Option::<T>::map` takes ownership of the receiver `self`, which moves `*cb`
--> $SRC_DIR/core/src/option.rs:LL:COL
help: consider calling `.as_ref()` to borrow the value's contents
|
LL | cb.as_ref().map(|cb| cb());
| +++++++++
help: consider calling `.as_mut()` to mutably borrow the value's contents
|
LL | cb.as_mut().map(|cb| cb());
| +++++++++
help: you could `clone` the value and consume it, if the `&mut dyn FnMut(): Clone` trait bound could be satisfied
|
LL | <Option<&mut dyn FnMut()> as Clone>::clone(&cb).map(|cb| cb());
Expand Down
12 changes: 9 additions & 3 deletions tests/ui/suggestions/as-ref-2.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@ error[E0382]: use of moved value: `foo`
LL | let foo = Some(Struct);
| --- move occurs because `foo` has type `Option<Struct>`, which does not implement the `Copy` trait
LL | let _x: Option<Struct> = foo.map(|s| bar(&s));
| --- ---------------- `foo` moved due to this method call
| |
| help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
| ---------------- `foo` moved due to this method call
LL | let _y = foo;
| ^^^ value used here after move
|
note: `Option::<T>::map` takes ownership of the receiver `self`, which moves `foo`
--> $SRC_DIR/core/src/option.rs:LL:COL
help: consider calling `.as_ref()` to borrow the value's contents
|
LL | let _x: Option<Struct> = foo.as_ref().map(|s| bar(&s));
| +++++++++
help: consider calling `.as_mut()` to mutably borrow the value's contents
|
LL | let _x: Option<Struct> = foo.as_mut().map(|s| bar(&s));
| +++++++++
help: you could `clone` the value and consume it, if the `Struct: Clone` trait bound could be satisfied
|
LL | let _x: Option<Struct> = foo.clone().map(|s| bar(&s));
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/suggestions/option-content-move.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ impl LipogramCorpora {
pub fn validate_all(&mut self) -> Result<(), char> {
for selection in &self.selections {
if selection.1.is_some() {
if <Option<String> as Clone>::clone(&selection.1.clone()).unwrap().contains(selection.0) {
if <Option<String> as Clone>::clone(&selection.1.clone()).as_mut().as_ref().unwrap().contains(selection.0) {
//~^ ERROR cannot move out of `selection.1`
return Err(selection.0);
}
Expand All @@ -25,7 +25,7 @@ impl LipogramCorpora2 {
pub fn validate_all(&mut self) -> Result<(), char> {
for selection in &self.selections {
if selection.1.is_ok() {
if <Result<String, String> as Clone>::clone(&selection.1.clone()).unwrap().contains(selection.0) {
if <Result<String, String> as Clone>::clone(&selection.1.clone()).as_mut().as_ref().unwrap().contains(selection.0) {
//~^ ERROR cannot move out of `selection.1`
return Err(selection.0);
}
Expand Down
18 changes: 16 additions & 2 deletions tests/ui/suggestions/option-content-move.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,18 @@ error[E0507]: cannot move out of `selection.1` which is behind a shared referenc
LL | if selection.1.unwrap().contains(selection.0) {
| ^^^^^^^^^^^ -------- `selection.1` moved due to this method call
| |
| help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
| move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait
|
note: `Option::<T>::unwrap` takes ownership of the receiver `self`, which moves `selection.1`
--> $SRC_DIR/core/src/option.rs:LL:COL
help: consider calling `.as_ref()` to borrow the value's contents
|
LL | if selection.1.as_ref().unwrap().contains(selection.0) {
| +++++++++
help: consider calling `.as_mut()` to mutably borrow the value's contents
|
LL | if selection.1.as_mut().unwrap().contains(selection.0) {
| +++++++++
help: you can `clone` the value and consume it, but this might not be your desired behavior
|
LL | if <Option<String> as Clone>::clone(&selection.1).unwrap().contains(selection.0) {
Expand All @@ -24,11 +31,18 @@ error[E0507]: cannot move out of `selection.1` which is behind a shared referenc
LL | if selection.1.unwrap().contains(selection.0) {
| ^^^^^^^^^^^ -------- `selection.1` moved due to this method call
| |
| help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
| move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait
|
note: `Result::<T, E>::unwrap` takes ownership of the receiver `self`, which moves `selection.1`
--> $SRC_DIR/core/src/result.rs:LL:COL
help: consider calling `.as_ref()` to borrow the value's contents
|
LL | if selection.1.as_ref().unwrap().contains(selection.0) {
| +++++++++
help: consider calling `.as_mut()` to mutably borrow the value's contents
|
LL | if selection.1.as_mut().unwrap().contains(selection.0) {
| +++++++++
help: you can `clone` the value and consume it, but this might not be your desired behavior
|
LL | if <Result<String, String> as Clone>::clone(&selection.1).unwrap().contains(selection.0) {
Expand Down
Loading