diff options
| author | Kevyn Grasso <kevgrasso@gmail.com> | 2019-10-20 21:30:43 -0400 |
|---|---|---|
| committer | Kevyn Grasso <kevgrasso@gmail.com> | 2019-10-25 10:20:09 -0400 |
| commit | 2337bbb8a4131645e4a98ad81524703d76196f82 (patch) | |
| tree | 37d75e1588c1c5e4cbd768638892d209278fa05d | |
| parent | fedefeca6d2c521307799da72e567751e92493c6 (diff) | |
| download | rust-2337bbb8a4131645e4a98ad81524703d76196f82.tar.gz rust-2337bbb8a4131645e4a98ad81524703d76196f82.zip | |
only relevant parts of type paths highlighted in E0308 type mismatch error message
| -rw-r--r-- | src/librustc/infer/error_reporting/mod.rs | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 36d8ed6dea9..01be2e5d6a5 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -867,7 +867,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// Compares two given types, eliding parts that are the same between them and highlighting /// relevant differences, and return two representation of those types for highlighted printing. fn cmp(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> (DiagnosticStyledString, DiagnosticStyledString) { - debug!("cmp(t1={}, t2={})", t1, t2); + debug!("cmp(t1={}, t1.kind={:?}, t2={}, t2.kind={:?})", t1, t1.kind, t2, t2.kind); // helper functions fn equals<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool { @@ -1056,12 +1056,47 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { return values; } - // We couldn't find anything in common, highlight everything. - // let x: Bar<Qux> = y::<Foo<Zar>>(); - ( - DiagnosticStyledString::highlighted(t1.to_string()), - DiagnosticStyledString::highlighted(t2.to_string()), - ) + // We can't find anything in common, highlight relevant part of type path. + // let x: foo::bar::Baz<Qux> = y:<foo::bar::Bar<Zar>>(); + // foo::bar::Baz<Qux> + // foo::bar::Bar<Zar> + // -------- this part of the path is different + + let t1_str = t1.to_string(); + let t2_str = t2.to_string(); + let min_len = t1_str.len().min(t2_str.len()); + + const SEPARATOR: &str = "::"; + let separator_len = SEPARATOR.len(); + let split_idx: usize = + t1_str.split(SEPARATOR) + .zip(t2_str.split(SEPARATOR)) + .take_while(|(mod1_str, mod2_str)| mod1_str == mod2_str) + .map(|(mod_str, _)| mod_str.len() + separator_len) + .sum(); + + debug!("cmp: separator_len={}, split_idx={}, min_len={}", + separator_len, split_idx, min_len + ); + + if split_idx >= min_len { + // paths are identical, highlight everything + ( + DiagnosticStyledString::highlighted(t1_str), + DiagnosticStyledString::highlighted(t2_str) + ) + } else { + let (common, uniq1) = t1_str.split_at(split_idx); + let (_, uniq2) = t2_str.split_at(split_idx); + debug!("cmp: common={}, uniq1={}, uniq2={}", common, uniq1, uniq2); + + values.0.push_normal(common); + values.0.push_highlighted(uniq1); + values.1.push_normal(common); + values.1.push_highlighted(uniq2); + + values + } } } |
