about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-12-02 15:08:08 +0000
committerbors <bors@rust-lang.org>2017-12-02 15:08:08 +0000
commit9053fdd411e81910a86b68f0a1c3b3ca084bff62 (patch)
tree6fa8b0cbbcdad9c8c4bd5bf5bdbcdb05153318c2 /src
parent7a649872a917068951228192b7e14626bd7bd540 (diff)
parent02808f1e9e5315addbc3c3fa3f12116d366323b9 (diff)
downloadrust-9053fdd411e81910a86b68f0a1c3b3ca084bff62.tar.gz
rust-9053fdd411e81910a86b68f0a1c3b3ca084bff62.zip
Auto merge of #46349 - estebank:highlight-ref, r=arielb1
On type mismatch error highlight `&` when type matches

When the only difference between the two types in a type error is that
one is a reference to the other type (`T` vs `&T`) or both are
references differing only in their mutability (`&T` vs `&mut T`), don't
highlight the type (`T`).
Diffstat (limited to 'src')
-rw-r--r--src/librustc/infer/error_reporting/mod.rs56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 6fadafc7b97..514b29120a9 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -555,6 +555,39 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     fn cmp(&self, t1: Ty<'tcx>, t2: Ty<'tcx>)
         -> (DiagnosticStyledString, DiagnosticStyledString)
     {
+        fn equals<'tcx>(a: &Ty<'tcx>, b: &Ty<'tcx>) -> bool {
+            match (&a.sty, &b.sty) {
+                (a, b) if *a == *b => true,
+                (&ty::TyInt(_), &ty::TyInfer(ty::InferTy::IntVar(_))) |
+                (&ty::TyInfer(ty::InferTy::IntVar(_)), &ty::TyInt(_)) |
+                (&ty::TyInfer(ty::InferTy::IntVar(_)), &ty::TyInfer(ty::InferTy::IntVar(_))) |
+                (&ty::TyFloat(_), &ty::TyInfer(ty::InferTy::FloatVar(_))) |
+                (&ty::TyInfer(ty::InferTy::FloatVar(_)), &ty::TyFloat(_)) |
+                (&ty::TyInfer(ty::InferTy::FloatVar(_)),
+                 &ty::TyInfer(ty::InferTy::FloatVar(_))) => true,
+                _ => false,
+            }
+        }
+
+        fn push_ty_ref<'tcx>(r: &ty::Region<'tcx>,
+                             tnm: &ty::TypeAndMut<'tcx>,
+                             s: &mut DiagnosticStyledString) {
+            let r = &format!("{}", r);
+            s.push_highlighted(format!("&{}{}{}",
+                                       r,
+                                       if r == "" {
+                                           ""
+                                       } else {
+                                           " "
+                                       },
+                                       if tnm.mutbl == hir::MutMutable {
+                                          "mut "
+                                       } else {
+                                           ""
+                                       }));
+            s.push_normal(format!("{}", tnm.ty));
+        }
+
         match (&t1.sty, &t2.sty) {
             (&ty::TyAdt(def1, sub1), &ty::TyAdt(def2, sub2)) => {
                 let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
@@ -672,6 +705,29 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                      DiagnosticStyledString::highlighted(format!("{}", t2)))
                 }
             }
+
+            // When finding T != &T, hightlight only the borrow
+            (&ty::TyRef(r1, ref tnm1), _) if equals(&tnm1.ty, &t2) => {
+                let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
+                push_ty_ref(&r1, tnm1, &mut values.0);
+                values.1.push_normal(format!("{}", t2));
+                values
+            }
+            (_, &ty::TyRef(r2, ref tnm2)) if equals(&t1, &tnm2.ty) => {
+                let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
+                values.0.push_normal(format!("{}", t1));
+                push_ty_ref(&r2, tnm2, &mut values.1);
+                values
+            }
+
+            // When encountering &T != &mut T, highlight only the borrow
+            (&ty::TyRef(r1, ref tnm1), &ty::TyRef(r2, ref tnm2)) if equals(&tnm1.ty, &tnm2.ty) => {
+                let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
+                push_ty_ref(&r1, tnm1, &mut values.0);
+                push_ty_ref(&r2, tnm2, &mut values.1);
+                values
+            }
+
             _ => {
                 if t1 == t2 {
                     // The two types are the same, elide and don't highlight.