/// 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() {
} 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,
--- /dev/null
+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() {}
--- /dev/null
+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`.