Rollup merge of #61054 - estebank:mut-ref-reassign, r=zackmdavis
Suggest dereferencing on assignment to mutable borrow Fix #33570
This commit is contained in:
commit
b9459e7e4d
@ -306,11 +306,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
/// In addition of this check, it also checks between references mutability state. If the
|
||||
/// expected is mutable but the provided isn't, maybe we could just say "Hey, try with
|
||||
/// `&mut`!".
|
||||
pub fn check_ref(&self,
|
||||
expr: &hir::Expr,
|
||||
checked_ty: Ty<'tcx>,
|
||||
expected: Ty<'tcx>)
|
||||
-> Option<(Span, &'static str, String)> {
|
||||
pub fn check_ref(
|
||||
&self,
|
||||
expr: &hir::Expr,
|
||||
checked_ty: Ty<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
) -> Option<(Span, &'static str, String)> {
|
||||
let cm = self.sess().source_map();
|
||||
let sp = expr.span;
|
||||
if !cm.span_to_filename(sp).is_real() {
|
||||
@ -397,6 +398,29 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
} else {
|
||||
String::new()
|
||||
};
|
||||
if let Some(hir::Node::Expr(hir::Expr {
|
||||
node: hir::ExprKind::Assign(left_expr, _),
|
||||
..
|
||||
})) = self.tcx.hir().find_by_hir_id(
|
||||
self.tcx.hir().get_parent_node_by_hir_id(expr.hir_id),
|
||||
) {
|
||||
if mutability == hir::Mutability::MutMutable {
|
||||
// Found the following case:
|
||||
// fn foo(opt: &mut Option<String>){ opt = None }
|
||||
// --- ^^^^
|
||||
// | |
|
||||
// consider dereferencing here: `*opt` |
|
||||
// expected mutable reference, found enum `Option`
|
||||
if let Ok(src) = cm.span_to_snippet(left_expr.span) {
|
||||
return Some((
|
||||
left_expr.span,
|
||||
"consider dereferencing here to assign to the mutable \
|
||||
borrowed piece of memory",
|
||||
format!("*{}", src),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
return Some(match mutability {
|
||||
hir::Mutability::MutMutable => (
|
||||
sp,
|
||||
|
17
src/test/ui/suggestions/mut-ref-reassignment.rs
Normal file
17
src/test/ui/suggestions/mut-ref-reassignment.rs
Normal file
@ -0,0 +1,17 @@
|
||||
fn suggestion(opt: &mut Option<String>) {
|
||||
opt = None; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn no_suggestion(opt: &mut Result<String, ()>) {
|
||||
opt = None //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn suggestion2(opt: &mut Option<String>) {
|
||||
opt = Some(String::new())//~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn no_suggestion2(opt: &mut Option<String>) {
|
||||
opt = Some(42)//~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn main() {}
|
47
src/test/ui/suggestions/mut-ref-reassignment.stderr
Normal file
47
src/test/ui/suggestions/mut-ref-reassignment.stderr
Normal file
@ -0,0 +1,47 @@
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mut-ref-reassignment.rs:2:11
|
||||
|
|
||||
LL | opt = None;
|
||||
| ^^^^ expected mutable reference, found enum `std::option::Option`
|
||||
|
|
||||
= note: expected type `&mut std::option::Option<std::string::String>`
|
||||
found type `std::option::Option<_>`
|
||||
help: consider dereferencing here to assign to the mutable borrowed piece of memory
|
||||
|
|
||||
LL | *opt = None;
|
||||
| ^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mut-ref-reassignment.rs:6:11
|
||||
|
|
||||
LL | opt = None
|
||||
| ^^^^ expected mutable reference, found enum `std::option::Option`
|
||||
|
|
||||
= note: expected type `&mut std::result::Result<std::string::String, ()>`
|
||||
found type `std::option::Option<_>`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mut-ref-reassignment.rs:10:11
|
||||
|
|
||||
LL | opt = Some(String::new())
|
||||
| ^^^^^^^^^^^^^^^^^^^ expected mutable reference, found enum `std::option::Option`
|
||||
|
|
||||
= note: expected type `&mut std::option::Option<std::string::String>`
|
||||
found type `std::option::Option<std::string::String>`
|
||||
help: consider dereferencing here to assign to the mutable borrowed piece of memory
|
||||
|
|
||||
LL | *opt = Some(String::new())
|
||||
| ^^^^
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/mut-ref-reassignment.rs:14:11
|
||||
|
|
||||
LL | opt = Some(42)
|
||||
| ^^^^^^^^ expected mutable reference, found enum `std::option::Option`
|
||||
|
|
||||
= note: expected type `&mut std::option::Option<std::string::String>`
|
||||
found type `std::option::Option<{integer}>`
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
Loading…
Reference in New Issue
Block a user