Skip to content

Commit 6da1cc2

Browse files
authored
Rollup merge of #153887 - estebank:as_ref-suggestion, r=JohnTitor
Turn label into structured suggestion for `.as_ref()` and `.as_mut()` ``` error[E0382]: use of moved value: `foo` --> $DIR/as-ref-2.rs:10:14 | 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 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)); | +++++++++ ```
2 parents 81549a3 + 7551181 commit 6da1cc2

File tree

6 files changed

+50
-10
lines changed

6 files changed

+50
-10
lines changed

compiler/rustc_borrowck/src/diagnostics/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1377,7 +1377,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
13771377
matches!(tcx.get_diagnostic_name(def_id), Some(sym::Option | sym::Result))
13781378
});
13791379
if is_option_or_result && maybe_reinitialized_locations_is_empty {
1380-
err.subdiagnostic(CaptureReasonLabel::BorrowContent { var_span });
1380+
err.subdiagnostic(CaptureReasonLabel::BorrowContent {
1381+
var_span: var_span.shrink_to_hi(),
1382+
});
13811383
}
13821384
if let Some((CallDesugaringKind::ForLoopIntoIter, _)) = desugaring {
13831385
let ty = moved_place.ty(self.body, tcx).ty;

compiler/rustc_borrowck/src/session_diagnostics.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,18 @@ pub(crate) enum CaptureReasonLabel<'a> {
456456
is_move_msg: bool,
457457
is_loop_message: bool,
458458
},
459-
#[label("help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents")]
459+
#[suggestion(
460+
"consider calling `.as_ref()` to borrow the value's contents",
461+
applicability = "maybe-incorrect",
462+
code = ".as_ref()",
463+
style = "verbose"
464+
)]
465+
#[suggestion(
466+
"consider calling `.as_mut()` to mutably borrow the value's contents",
467+
applicability = "maybe-incorrect",
468+
code = ".as_mut()",
469+
style = "verbose"
470+
)]
460471
BorrowContent {
461472
#[primary_span]
462473
var_span: Span,

tests/ui/borrowck/suggest-as-ref-on-mut-closure.stderr

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,18 @@ error[E0507]: cannot move out of `*cb` which is behind a mutable reference
44
LL | cb.map(|cb| cb());
55
| ^^ -------------- `*cb` moved due to this method call
66
| |
7-
| help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
87
| move occurs because `*cb` has type `Option<&mut dyn FnMut()>`, which does not implement the `Copy` trait
98
|
109
note: `Option::<T>::map` takes ownership of the receiver `self`, which moves `*cb`
1110
--> $SRC_DIR/core/src/option.rs:LL:COL
11+
help: consider calling `.as_ref()` to borrow the value's contents
12+
|
13+
LL | cb.as_ref().map(|cb| cb());
14+
| +++++++++
15+
help: consider calling `.as_mut()` to mutably borrow the value's contents
16+
|
17+
LL | cb.as_mut().map(|cb| cb());
18+
| +++++++++
1219
help: you could `clone` the value and consume it, if the `&mut dyn FnMut(): Clone` trait bound could be satisfied
1320
|
1421
LL | <Option<&mut dyn FnMut()> as Clone>::clone(&cb).map(|cb| cb());

tests/ui/suggestions/as-ref-2.stderr

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@ error[E0382]: use of moved value: `foo`
44
LL | let foo = Some(Struct);
55
| --- move occurs because `foo` has type `Option<Struct>`, which does not implement the `Copy` trait
66
LL | let _x: Option<Struct> = foo.map(|s| bar(&s));
7-
| --- ---------------- `foo` moved due to this method call
8-
| |
9-
| help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
7+
| ---------------- `foo` moved due to this method call
108
LL | let _y = foo;
119
| ^^^ value used here after move
1210
|
1311
note: `Option::<T>::map` takes ownership of the receiver `self`, which moves `foo`
1412
--> $SRC_DIR/core/src/option.rs:LL:COL
13+
help: consider calling `.as_ref()` to borrow the value's contents
14+
|
15+
LL | let _x: Option<Struct> = foo.as_ref().map(|s| bar(&s));
16+
| +++++++++
17+
help: consider calling `.as_mut()` to mutably borrow the value's contents
18+
|
19+
LL | let _x: Option<Struct> = foo.as_mut().map(|s| bar(&s));
20+
| +++++++++
1521
help: you could `clone` the value and consume it, if the `Struct: Clone` trait bound could be satisfied
1622
|
1723
LL | let _x: Option<Struct> = foo.clone().map(|s| bar(&s));

tests/ui/suggestions/option-content-move.fixed

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ impl LipogramCorpora {
77
pub fn validate_all(&mut self) -> Result<(), char> {
88
for selection in &self.selections {
99
if selection.1.is_some() {
10-
if <Option<String> as Clone>::clone(&selection.1.clone()).unwrap().contains(selection.0) {
10+
if <Option<String> as Clone>::clone(&selection.1.clone()).as_mut().as_ref().unwrap().contains(selection.0) {
1111
//~^ ERROR cannot move out of `selection.1`
1212
return Err(selection.0);
1313
}
@@ -25,7 +25,7 @@ impl LipogramCorpora2 {
2525
pub fn validate_all(&mut self) -> Result<(), char> {
2626
for selection in &self.selections {
2727
if selection.1.is_ok() {
28-
if <Result<String, String> as Clone>::clone(&selection.1.clone()).unwrap().contains(selection.0) {
28+
if <Result<String, String> as Clone>::clone(&selection.1.clone()).as_mut().as_ref().unwrap().contains(selection.0) {
2929
//~^ ERROR cannot move out of `selection.1`
3030
return Err(selection.0);
3131
}

tests/ui/suggestions/option-content-move.stderr

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,18 @@ error[E0507]: cannot move out of `selection.1` which is behind a shared referenc
44
LL | if selection.1.unwrap().contains(selection.0) {
55
| ^^^^^^^^^^^ -------- `selection.1` moved due to this method call
66
| |
7-
| help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
87
| move occurs because `selection.1` has type `Option<String>`, which does not implement the `Copy` trait
98
|
109
note: `Option::<T>::unwrap` takes ownership of the receiver `self`, which moves `selection.1`
1110
--> $SRC_DIR/core/src/option.rs:LL:COL
11+
help: consider calling `.as_ref()` to borrow the value's contents
12+
|
13+
LL | if selection.1.as_ref().unwrap().contains(selection.0) {
14+
| +++++++++
15+
help: consider calling `.as_mut()` to mutably borrow the value's contents
16+
|
17+
LL | if selection.1.as_mut().unwrap().contains(selection.0) {
18+
| +++++++++
1219
help: you can `clone` the value and consume it, but this might not be your desired behavior
1320
|
1421
LL | if <Option<String> as Clone>::clone(&selection.1).unwrap().contains(selection.0) {
@@ -24,11 +31,18 @@ error[E0507]: cannot move out of `selection.1` which is behind a shared referenc
2431
LL | if selection.1.unwrap().contains(selection.0) {
2532
| ^^^^^^^^^^^ -------- `selection.1` moved due to this method call
2633
| |
27-
| help: consider calling `.as_ref()` or `.as_mut()` to borrow the type's contents
2834
| move occurs because `selection.1` has type `Result<String, String>`, which does not implement the `Copy` trait
2935
|
3036
note: `Result::<T, E>::unwrap` takes ownership of the receiver `self`, which moves `selection.1`
3137
--> $SRC_DIR/core/src/result.rs:LL:COL
38+
help: consider calling `.as_ref()` to borrow the value's contents
39+
|
40+
LL | if selection.1.as_ref().unwrap().contains(selection.0) {
41+
| +++++++++
42+
help: consider calling `.as_mut()` to mutably borrow the value's contents
43+
|
44+
LL | if selection.1.as_mut().unwrap().contains(selection.0) {
45+
| +++++++++
3246
help: you can `clone` the value and consume it, but this might not be your desired behavior
3347
|
3448
LL | if <Result<String, String> as Clone>::clone(&selection.1).unwrap().contains(selection.0) {

0 commit comments

Comments
 (0)