]> git.lizzy.rs Git - rust.git/commitdiff
Add help message for missing `IndexMut` impl
authorLukas Kalbertodt <lukas.kalbertodt@gmail.com>
Fri, 27 Jul 2018 18:44:09 +0000 (20:44 +0200)
committerLukas Kalbertodt <lukas.kalbertodt@gmail.com>
Sat, 28 Jul 2018 12:00:56 +0000 (14:00 +0200)
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.

src/librustc_borrowck/borrowck/mod.rs

index 3ae1e5aac507611938bc57855c1d5f18200720db..97348c168de8c128243742b914320a35d76c39e4 100644 (file)
@@ -881,6 +881,29 @@ fn report_bckerr(&self, err: &BckError<'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(_)) => {