From 677381a0c1788d459c010b891fbf21e80b4a28a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 28 Nov 2017 11:25:40 -0800 Subject: [PATCH 1/2] 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`). --- src/librustc/infer/error_reporting/mod.rs | 58 +++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 6fadafc7b97ae..5ef1c37135b4c 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. From 02808f1e9e5315addbc3c3fa3f12116d366323b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 29 Nov 2017 08:55:45 -0800 Subject: [PATCH 2/2] Include lifetime on highlighted ref type mismatch --- src/librustc/infer/error_reporting/mod.rs | 54 +++++++++++------------ 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 5ef1c37135b4c..514b29120a96a 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -569,6 +569,25 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } } + 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()); @@ -688,45 +707,24 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { } // When finding T != &T, hightlight only the borrow - (&ty::TyRef(_, ref tnm1), _) if equals(&tnm1.ty, &t2) => { + (&ty::TyRef(r1, 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)); + push_ty_ref(&r1, tnm1, &mut values.0); values.1.push_normal(format!("{}", t2)); values } - (_, &ty::TyRef(_, ref tnm2)) if equals(&t1, &tnm2.ty) => { + (_, &ty::TyRef(r2, 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)); + push_ty_ref(&r2, tnm2, &mut values.1); values } // When encountering &T != &mut T, highlight only the borrow - (&ty::TyRef(_, ref tnm1), &ty::TyRef(_, ref tnm2)) if equals(&tnm1.ty, &tnm2.ty) => { + (&ty::TyRef(r1, ref tnm1), &ty::TyRef(r2, 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)); + push_ty_ref(&r1, tnm1, &mut values.0); + push_ty_ref(&r2, tnm2, &mut values.1); values }