Auto merge of #61147 - estebank:suggest-as-ref, r=oli-obk

When encountering move error on an `Option`, suggest using `as_ref`

Fix #61109, cc #15457.
This commit is contained in:
bors 2019-05-27 01:10:22 +00:00
commit ed2a5115da
4 changed files with 188 additions and 76 deletions

View File

@ -242,12 +242,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
let (mut err, err_span) = {
let (span, original_path, kind): (Span, &Place<'tcx>, &IllegalMoveOriginKind<'_>) =
match error {
GroupedMoveError::MovesFromPlace {
span,
ref original_path,
ref kind,
..
} |
GroupedMoveError::MovesFromPlace { span, ref original_path, ref kind, .. } |
GroupedMoveError::MovesFromValue { span, ref original_path, ref kind, .. } |
GroupedMoveError::OtherIllegalMove { span, ref original_path, ref kind } => {
(span, original_path, kind)
@ -257,8 +252,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
debug!("report: original_path={:?} span={:?}, kind={:?} \
original_path.is_upvar_field_projection={:?}", original_path, span, kind,
self.is_upvar_field_projection(original_path));
(
match kind {
let err = match kind {
IllegalMoveOriginKind::Static => {
self.infcx.tcx.cannot_move_out_of(span, "static item", origin)
}
@ -271,7 +265,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
self.prefixes(&original_path, PrefixSet::All)
.any(|p| self.is_upvar_field_projection(p).is_some());
debug!("report: ty={:?}", ty);
match ty.sty {
let mut err = match ty.sty {
ty::Array(..) | ty::Slice(..) =>
self.infcx.tcx.cannot_move_out_of_interior_noncopy(
span, ty, None, origin
@ -319,7 +313,27 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
span, &source.to_string(), origin
)
},
};
let orig_path_ty = format!(
"{:?}",
original_path.ty(self.mir, self.infcx.tcx).ty,
);
let snippet = self.infcx.tcx.sess.source_map().span_to_snippet(span).unwrap();
let is_option = orig_path_ty.starts_with("std::option::Option");
let is_result = orig_path_ty.starts_with("std::result::Result");
if is_option || is_result {
err.span_suggestion(
span,
&format!("consider borrowing the `{}`'s content", if is_option {
"Option"
} else {
"Result"
}),
format!("{}.as_ref()", snippet),
Applicability::MaybeIncorrect,
);
}
err
}
IllegalMoveOriginKind::InteriorOfTypeWithDestructor { container_ty: ty } => {
self.infcx.tcx
@ -329,9 +343,8 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
self.infcx.tcx.cannot_move_out_of_interior_noncopy(
span, ty, Some(*is_index), origin
),
},
span,
)
};
(err, span)
};
self.add_move_hints(error, &mut err, err_span);

View File

@ -0,0 +1,39 @@
//run-rustfix
pub struct LipogramCorpora {
selections: Vec<(char, Option<String>)>,
}
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) {
//~^ ERROR cannot move out of borrowed content
return Err(selection.0);
}
}
}
Ok(())
}
}
pub struct LipogramCorpora2 {
selections: Vec<(char, Result<String, String>)>,
}
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) {
//~^ ERROR cannot move out of borrowed content
return Err(selection.0);
}
}
}
Ok(())
}
}
fn main() {}

View File

@ -0,0 +1,39 @@
//run-rustfix
pub struct LipogramCorpora {
selections: Vec<(char, Option<String>)>,
}
impl LipogramCorpora {
pub fn validate_all(&mut self) -> Result<(), char> {
for selection in &self.selections {
if selection.1.is_some() {
if selection.1.unwrap().contains(selection.0) {
//~^ ERROR cannot move out of borrowed content
return Err(selection.0);
}
}
}
Ok(())
}
}
pub struct LipogramCorpora2 {
selections: Vec<(char, Result<String, String>)>,
}
impl LipogramCorpora2 {
pub fn validate_all(&mut self) -> Result<(), char> {
for selection in &self.selections {
if selection.1.is_ok() {
if selection.1.unwrap().contains(selection.0) {
//~^ ERROR cannot move out of borrowed content
return Err(selection.0);
}
}
}
Ok(())
}
}
fn main() {}

View File

@ -0,0 +1,21 @@
error[E0507]: cannot move out of borrowed content
--> $DIR/option-content-move.rs:11:20
|
LL | if selection.1.unwrap().contains(selection.0) {
| ^^^^^^^^^^^
| |
| cannot move out of borrowed content
| help: consider borrowing the `Option`'s content: `selection.1.as_ref()`
error[E0507]: cannot move out of borrowed content
--> $DIR/option-content-move.rs:29:20
|
LL | if selection.1.unwrap().contains(selection.0) {
| ^^^^^^^^^^^
| |
| cannot move out of borrowed content
| help: consider borrowing the `Result`'s content: `selection.1.as_ref()`
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0507`.