about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Kalbertodt <lukas.kalbertodt@gmail.com>2018-07-27 20:44:09 +0200
committerLukas Kalbertodt <lukas.kalbertodt@gmail.com>2018-07-28 14:00:56 +0200
commit9d59c6b76e96005201d3b66dae946cc01dc5e565 (patch)
tree0dcf88cfde8af43cf8cf90ec1b20f864debd1b65
parent45b48b9b6d70065a16cc119fe934ed342c664c78 (diff)
Add help message for missing `IndexMut` impl
Before this change it simply says "cannot assign to immutable indexed
content". This might be confusing for Rust beginners, as implementing
two traits for "one operator" is not intuitive.
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 3ae1e5aac50..97348c168de 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -881,6 +881,29 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                                 }
                             }
                         }
+
+                        // We add a special note about `IndexMut`, if the source of this error
+                        // is the fact that `Index` is implemented, but `IndexMut` is not. Needing
+                        // to implement two traits for "one operator" is not very intuitive for
+                        // many programmers.
+                        if err.cmt.note == mc::NoteIndex {
+                            let node_id = self.tcx.hir.hir_to_node_id(err.cmt.hir_id);
+                            let node =  self.tcx.hir.get(node_id);
+
+                            // This pattern probably always matches.
+                            if let hir_map::NodeExpr(
+                                hir::Expr { node: hir::ExprKind::Index(lhs, _), ..}
+                            ) = node {
+                                let ty = self.tables.expr_ty(lhs);
+
+                                db.help(&format!(
+                                    "trait `IndexMut` is required to modify indexed content, but \
+                                     it is not implemented for {}",
+                                    ty
+                                ));
+                            }
+                        }
+
                         db
                     }
                     BorrowViolation(euv::ClosureCapture(_)) => {