Skip to content

Commit aa51f04

Browse files
committed
Auto merge of #65779 - kevgrasso:E0308highlight, r=estebank
Highlight only relevant parts of type path in type errors Resolves #57413. Unfortunately the current Rust UI testing setup can't test that the correct colors are being used in a given output, so here's a screenshot of a small test program I wrote: ![image](https://user-images.githubusercontent.com/480789/67530063-f272af00-f68b-11e9-9f96-a211fc7666d4.png)
2 parents 6c1b220 + 2337bbb commit aa51f04

File tree

2 files changed

+52
-8
lines changed

2 files changed

+52
-8
lines changed

src/librustc/infer/error_reporting/mod.rs

+50-6
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
867867
/// Compares two given types, eliding parts that are the same between them and highlighting
868868
/// relevant differences, and return two representation of those types for highlighted printing.
869869
fn cmp(&self, t1: Ty<'tcx>, t2: Ty<'tcx>) -> (DiagnosticStyledString, DiagnosticStyledString) {
870+
debug!("cmp(t1={}, t1.kind={:?}, t2={}, t2.kind={:?})", t1, t1.kind, t2, t2.kind);
871+
872+
// helper functions
870873
fn equals<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool {
871874
match (&a.kind, &b.kind) {
872875
(a, b) if *a == *b => true,
@@ -902,6 +905,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
902905
s.push_normal(ty.to_string());
903906
}
904907

908+
// process starts here
905909
match (&t1.kind, &t2.kind) {
906910
(&ty::Adt(def1, sub1), &ty::Adt(def2, sub2)) => {
907911
let sub_no_defaults_1 = self.strip_generic_default_params(def1.did, sub1);
@@ -1052,12 +1056,47 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
10521056
return values;
10531057
}
10541058

1055-
// We couldn't find anything in common, highlight everything.
1056-
// let x: Bar<Qux> = y::<Foo<Zar>>();
1057-
(
1058-
DiagnosticStyledString::highlighted(t1.to_string()),
1059-
DiagnosticStyledString::highlighted(t2.to_string()),
1060-
)
1059+
// We can't find anything in common, highlight relevant part of type path.
1060+
// let x: foo::bar::Baz<Qux> = y:<foo::bar::Bar<Zar>>();
1061+
// foo::bar::Baz<Qux>
1062+
// foo::bar::Bar<Zar>
1063+
// -------- this part of the path is different
1064+
1065+
let t1_str = t1.to_string();
1066+
let t2_str = t2.to_string();
1067+
let min_len = t1_str.len().min(t2_str.len());
1068+
1069+
const SEPARATOR: &str = "::";
1070+
let separator_len = SEPARATOR.len();
1071+
let split_idx: usize =
1072+
t1_str.split(SEPARATOR)
1073+
.zip(t2_str.split(SEPARATOR))
1074+
.take_while(|(mod1_str, mod2_str)| mod1_str == mod2_str)
1075+
.map(|(mod_str, _)| mod_str.len() + separator_len)
1076+
.sum();
1077+
1078+
debug!("cmp: separator_len={}, split_idx={}, min_len={}",
1079+
separator_len, split_idx, min_len
1080+
);
1081+
1082+
if split_idx >= min_len {
1083+
// paths are identical, highlight everything
1084+
(
1085+
DiagnosticStyledString::highlighted(t1_str),
1086+
DiagnosticStyledString::highlighted(t2_str)
1087+
)
1088+
} else {
1089+
let (common, uniq1) = t1_str.split_at(split_idx);
1090+
let (_, uniq2) = t2_str.split_at(split_idx);
1091+
debug!("cmp: common={}, uniq1={}, uniq2={}", common, uniq1, uniq2);
1092+
1093+
values.0.push_normal(common);
1094+
values.0.push_highlighted(uniq1);
1095+
values.1.push_normal(common);
1096+
values.1.push_highlighted(uniq2);
1097+
1098+
values
1099+
}
10611100
}
10621101
}
10631102

@@ -1120,6 +1159,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
11201159
_ => {}
11211160
}
11221161

1162+
debug!("note_type_err(diag={:?})", diag);
11231163
let (expected_found, exp_found, is_simple_error) = match values {
11241164
None => (None, None, false),
11251165
Some(values) => {
@@ -1180,6 +1220,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
11801220
diag.note_unsuccessfull_coercion(found, expected);
11811221
}
11821222
(_, false, _) => {
1223+
debug!(
1224+
"note_type_err: exp_found={:?}, expected={:?} found={:?}",
1225+
exp_found, expected, found
1226+
);
11831227
if let Some(exp_found) = exp_found {
11841228
self.suggest_as_ref_where_appropriate(span, &exp_found, diag);
11851229
}

src/librustc_errors/diagnostic.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub struct SubDiagnostic {
3434
pub render_span: Option<MultiSpan>,
3535
}
3636

37-
#[derive(PartialEq, Eq)]
37+
#[derive(Debug, PartialEq, Eq)]
3838
pub struct DiagnosticStyledString(pub Vec<StringPart>);
3939

4040
impl DiagnosticStyledString {
@@ -60,7 +60,7 @@ impl DiagnosticStyledString {
6060
}
6161
}
6262

63-
#[derive(PartialEq, Eq)]
63+
#[derive(Debug, PartialEq, Eq)]
6464
pub enum StringPart {
6565
Normal(String),
6666
Highlighted(String),

0 commit comments

Comments
 (0)