about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2017-11-28 11:25:40 -0800
committerEsteban Küber <esteban@kuber.com.ar>2017-11-28 11:25:40 -0800
commit677381a0c1788d459c010b891fbf21e80b4a28a3 (patch)
tree4a7682a8f270a05a07e2fb218316f463f83fa85b
parentea51b19dc7587bac0011282506ad4678cca9c1eb (diff)
downloadrust-677381a0c1788d459c010b891fbf21e80b4a28a3.tar.gz
rust-677381a0c1788d459c010b891fbf21e80b4a28a3.zip
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`).
-rw-r--r--src/librustc/infer/error_reporting/mod.rs58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index 6fadafc7b97..5ef1c37135b 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -555,6 +555,20 @@ 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,
+            }
+        }
+
         match (&t1.sty, &t2.sty) {
             (&ty::TyAdt(def1, sub1), &ty::TyAdt(def2, sub2)) => {
                 let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
@@ -672,6 +686,50 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                      DiagnosticStyledString::highlighted(format!("{}", t2)))
                 }
             }
+
+            // When finding T != &T, hightlight only the borrow
+            (&ty::TyRef(_, ref tnm1), _) if equals(&tnm1.ty, &t2) => {
+                let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
+                values.0.push_highlighted(format!("&{}", if tnm1.mutbl == hir::MutMutable {
+                    "mut "
+                 } else {
+                     ""
+                 }));
+                values.0.push_normal(format!("{}", tnm1.ty));
+                values.1.push_normal(format!("{}", t2));
+                values
+            }
+            (_, &ty::TyRef(_, ref tnm2)) if equals(&t1, &tnm2.ty) => {
+                let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
+                values.1.push_highlighted(format!("&{}", if tnm2.mutbl == hir::MutMutable {
+                    "mut "
+                 } else {
+                     ""
+                 }));
+                values.0.push_normal(format!("{}", t1));
+                values.1.push_normal(format!("{}", tnm2.ty));
+                values
+            }
+
+            // When encountering &T != &mut T, highlight only the borrow
+            (&ty::TyRef(_, ref tnm1), &ty::TyRef(_, ref tnm2)) if equals(&tnm1.ty, &tnm2.ty) => {
+                let mut values = (DiagnosticStyledString::new(), DiagnosticStyledString::new());
+                values.0.push_highlighted(format!("&{}", if tnm1.mutbl == hir::MutMutable {
+                    "mut "
+                 } else {
+                     ""
+                 }));
+                values.1.push_highlighted(format!("&{}", if tnm2.mutbl == hir::MutMutable {
+                    "mut "
+                 } else {
+                     ""
+                 }));
+
+                values.0.push_normal(format!("{}", tnm1.ty));
+                values.1.push_normal(format!("{}", tnm2.ty));
+                values
+            }
+
             _ => {
                 if t1 == t2 {
                     // The two types are the same, elide and don't highlight.