diff options
| author | Esteban Küber <esteban@kuber.com.ar> | 2019-08-13 19:09:28 -0700 |
|---|---|---|
| committer | Esteban Küber <esteban@kuber.com.ar> | 2019-08-21 11:52:38 -0700 |
| commit | 266b878334cecce3a0636ddbb95318f7a5669f45 (patch) | |
| tree | a054efeba86505a5aded83093e392a4fbcfacde4 /src/librustc_errors | |
| parent | 0e668e0496fcc13fa042be416b64ba6823669cca (diff) | |
| download | rust-266b878334cecce3a0636ddbb95318f7a5669f45.tar.gz rust-266b878334cecce3a0636ddbb95318f7a5669f45.zip | |
clean up
Diffstat (limited to 'src/librustc_errors')
| -rw-r--r-- | src/librustc_errors/emitter.rs | 220 |
1 files changed, 157 insertions, 63 deletions
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 007c6369c7b..b7615fef049 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -57,6 +57,80 @@ impl HumanReadableErrorType { } } +#[derive(Clone, Copy, Debug)] +struct Margin { + pub whitespace_left: usize, + pub span_left: usize, + pub span_right: usize, + pub line_len: usize, + pub computed_left: usize, + pub computed_right: usize, + pub column_width: usize, + pub label_right: usize, +} + +impl Margin { + fn new( + whitespace_left: usize, + span_left: usize, + span_right: usize, + label_right: usize, + ) -> Self { + Margin { + whitespace_left, + span_left, + span_right, + line_len: 0, + computed_left: 0, + computed_right: 0, + column_width: 140, + label_right, + } + } + + fn was_cut_left(&self) -> bool { + self.computed_left > 0 + } + + fn was_cut_right(&self) -> bool { + self.computed_right < self.line_len + } + + fn compute(&mut self) { + self.computed_left = if self.whitespace_left > 20 { + self.whitespace_left - 16 // We want some padding. + } else { + 0 + }; + self.computed_right = self.column_width + self.computed_left; + + if self.computed_right - self.computed_left > self.column_width { + // Trimming only whitespace isn't enough, let's get craftier. + if self.label_right - self.whitespace_left <= self.column_width { + self.computed_left = self.whitespace_left; + self.computed_right = self.computed_left + self.column_width; + } else if self.label_right - self.span_left - 20 <= self.column_width { + self.computed_left = self.span_left - 20; + self.computed_right = self.computed_left + self.column_width; + } else if self.label_right - self.span_left <= self.column_width { + self.computed_left = self.span_left; + self.computed_right = self.computed_left + self.column_width; + } else if self.span_right - self.span_left <= self.column_width { + self.computed_left = self.span_left; + self.computed_right = self.computed_left + self.column_width; + } else { // mostly give up but still don't show the full line + self.computed_left = self.span_left; + self.computed_right = self.span_right; + } + } + self.computed_left = std::cmp::min(self.computed_left, self.line_len); + if self.computed_right > self.line_len { + self.computed_right = self.line_len; + } + self.computed_right = std::cmp::min(self.computed_right, self.line_len); + } +} + const ANONYMIZED_LINE_NUM: &str = "LL"; /// Emitter trait for emitting errors. @@ -179,7 +253,6 @@ pub struct EmitterWriter { sm: Option<Lrc<SourceMapperDyn>>, short_message: bool, teach: bool, - strip_margin: bool, ui_testing: bool, } @@ -202,7 +275,6 @@ impl EmitterWriter { sm: source_map, short_message, teach, - strip_margin: false, ui_testing: false, } } @@ -219,7 +291,6 @@ impl EmitterWriter { sm: source_map, short_message, teach, - strip_margin: false, ui_testing: false, } } @@ -244,8 +315,7 @@ impl EmitterWriter { line: &Line, width_offset: usize, code_offset: usize, - margin: usize, - right_span_margin: usize + mut margin: Margin, ) -> Vec<(usize, Style)> { // Draw: // @@ -260,6 +330,7 @@ impl EmitterWriter { // | | when there's too much wasted space to the left, we trim it to focus where it matters // | vertical divider between the column number and the code // column number + if line.line_index == 0 { return Vec::new(); } @@ -271,26 +342,27 @@ impl EmitterWriter { let line_offset = buffer.num_lines(); - let left_margin = std::cmp::min(margin, source_string.len()); - let right_margin = if source_string.len() > right_span_margin + 120 { - right_span_margin + 120 - } else { - source_string.len() - }; + margin.line_len = source_string.len(); + margin.compute(); // Create the source line we will highlight. buffer.puts( line_offset, code_offset, - &source_string[left_margin..right_margin], // On long lines, we strip the source line + // On long lines, we strip the source line + &source_string[margin.computed_left..margin.computed_right], Style::Quotation, ); - if margin > 0 { // We have stripped some code/whitespace from the beginning, make it clear. + if margin.was_cut_left() { // We have stripped some code/whitespace from the beginning, make it clear. buffer.puts(line_offset, code_offset, "...", Style::LineNumber); } - if right_margin != source_string.len() { + if margin.was_cut_right() { // We have stripped some code after the right-most span end, make it clear we did so. - let offset = code_offset + right_margin - left_margin; - buffer.puts(line_offset, offset, "...", Style::LineNumber); + buffer.puts( + line_offset, + margin.computed_right - margin.computed_left + code_offset, + "...", + Style::LineNumber, + ); } buffer.puts(line_offset, 0, &self.maybe_anonymized(line.line_index), Style::LineNumber); @@ -546,13 +618,13 @@ impl EmitterWriter { '_', line_offset + pos, width_offset + depth, - code_offset + annotation.start_col - margin, + code_offset + annotation.start_col - margin.computed_left, style); } _ if self.teach => { buffer.set_style_range(line_offset, - code_offset + annotation.start_col - margin, - code_offset + annotation.end_col - margin, + code_offset + annotation.start_col - margin.computed_left, + code_offset + annotation.end_col - margin.computed_left, style, annotation.is_primary); } @@ -582,7 +654,7 @@ impl EmitterWriter { if pos > 1 && (annotation.has_label() || annotation.takes_space()) { for p in line_offset + 1..=line_offset + pos { buffer.putc(p, - code_offset + annotation.start_col - margin, + code_offset + annotation.start_col - margin.computed_left, '|', style); } @@ -626,9 +698,9 @@ impl EmitterWriter { Style::LabelSecondary }; let (pos, col) = if pos == 0 { - (pos + 1, annotation.end_col + 1 - margin) + (pos + 1, annotation.end_col + 1 - margin.computed_left) } else { - (pos + 2, annotation.start_col - margin) + (pos + 2, annotation.start_col - margin.computed_left) }; if let Some(ref label) = annotation.label { buffer.puts(line_offset + pos, @@ -670,7 +742,7 @@ impl EmitterWriter { }; for p in annotation.start_col..annotation.end_col { buffer.putc(line_offset + 1, - code_offset + p - margin, + code_offset + p - margin.computed_left, underline, style); } @@ -1010,22 +1082,30 @@ impl EmitterWriter { let buffer_msg_line_offset = buffer.num_lines(); buffer.prepend(buffer_msg_line_offset, "--> ", Style::LineNumber); - buffer.append(buffer_msg_line_offset, - &format!("{}:{}:{}", - loc.file.name, - sm.doctest_offset_line(&loc.file.name, loc.line), - loc.col.0 + 1), - Style::LineAndColumn); + buffer.append( + buffer_msg_line_offset, + &format!( + "{}:{}:{}", + loc.file.name, + sm.doctest_offset_line(&loc.file.name, loc.line), + loc.col.0 + 1, + ), + Style::LineAndColumn, + ); for _ in 0..max_line_num_len { buffer.prepend(buffer_msg_line_offset, " ", Style::NoStyle); } } else { - buffer.prepend(0, - &format!("{}:{}:{}: ", - loc.file.name, - sm.doctest_offset_line(&loc.file.name, loc.line), - loc.col.0 + 1), - Style::LineAndColumn); + buffer.prepend( + 0, + &format!( + "{}:{}:{}: ", + loc.file.name, + sm.doctest_offset_line(&loc.file.name, loc.line), + loc.col.0 + 1, + ), + Style::LineAndColumn, + ); } } else if !self.short_message { // remember where we are in the output buffer for easy reference @@ -1069,7 +1149,7 @@ impl EmitterWriter { let mut multilines = FxHashMap::default(); // Get the left-side margin to remove it - let mut margin = std::usize::MAX; + let mut whitespace_margin = std::usize::MAX; for line_idx in 0..annotated_file.lines.len() { let file = annotated_file.file.clone(); let line = &annotated_file.lines[line_idx]; @@ -1079,14 +1159,15 @@ impl EmitterWriter { .take_while(|c| c.is_whitespace()) .count(); if source_string.chars().any(|c| !c.is_whitespace()) { - margin = std::cmp::min(margin, leading_whitespace); + whitespace_margin = std::cmp::min( + whitespace_margin, + leading_whitespace, + ); } } } - if margin >= 20 { // On errors with generous margins, trim it - margin = margin - 16; // Keep at least 4 spaces margin - } else if margin == std::usize::MAX || !self.strip_margin { - margin = 0; + if whitespace_margin == std::usize::MAX { + whitespace_margin = 0; } // Left-most column any visible span points at. @@ -1100,18 +1181,27 @@ impl EmitterWriter { if span_left_margin == std::usize::MAX { span_left_margin = 0; } - if span_left_margin > 160 { - margin = std::cmp::max(margin, span_left_margin - 100); - } // Right-most column any visible span points at. let mut span_right_margin = 0; + let mut label_right_margin = 0; for line in &annotated_file.lines { for ann in &line.annotations { span_right_margin = std::cmp::max(span_right_margin, ann.start_col); span_right_margin = std::cmp::max(span_right_margin, ann.end_col); + label_right_margin = std::cmp::max( + label_right_margin, + // TODO: account for labels not in the same line + ann.end_col + ann.label.as_ref().map(|l| l.len() + 1).unwrap_or(0), + ); } } + let margin = Margin::new( + whitespace_margin, + span_left_margin, + span_right_margin, + label_right_margin, + ); // Next, output the annotate source for this file for line_idx in 0..annotated_file.lines.len() { @@ -1131,7 +1221,6 @@ impl EmitterWriter { width_offset, code_offset, margin, - span_right_margin, ); let mut to_add = FxHashMap::default(); @@ -1179,24 +1268,29 @@ impl EmitterWriter { let last_buffer_line_num = buffer.num_lines(); - buffer.puts(last_buffer_line_num, - 0, - &self.maybe_anonymized(annotated_file.lines[line_idx + 1] - .line_index - 1), - Style::LineNumber); - draw_col_separator(&mut buffer, - last_buffer_line_num, - 1 + max_line_num_len); - let left_margin = std::cmp::min(margin, unannotated_line.len()); - let right_margin = if unannotated_line.len() > span_right_margin + 120 { - span_right_margin + 120 - } else { - unannotated_line.len() - }; - buffer.puts(last_buffer_line_num, - code_offset, - &unannotated_line[left_margin..right_margin], - Style::Quotation); + buffer.puts( + last_buffer_line_num, + 0, + &self.maybe_anonymized( + annotated_file.lines[line_idx + 1].line_index - 1, + ), + Style::LineNumber, + ); + draw_col_separator( + &mut buffer, + last_buffer_line_num, + 1 + max_line_num_len, + ); + + let mut margin = margin; + margin.line_len = unannotated_line.len(); + margin.compute(); + buffer.puts( + last_buffer_line_num, + code_offset, + &unannotated_line[margin.computed_left..margin.computed_right], + Style::Quotation, + ); for (depth, style) in &multilines { draw_multiline_line(&mut buffer, |
