diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2017-11-28 11:25:40 -0800 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2017-11-28 11:25:40 -0800 |
| commit | 677381a0c1788d459c010b891fbf21e80b4a28a3 (patch) | |
| tree | 4a7682a8f270a05a07e2fb218316f463f83fa85b | |
| parent | ea51b19dc7587bac0011282506ad4678cca9c1eb (diff) | |
| download | rust-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.rs | 58 |
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. |
