tamer: diagnose::report: Add line of padding above footer

This adds a line of padding between the last line of a source marking and
the first line of a footer, making it easier to read.  This also matches the
behavior of Rust's error message.

This is something I intended to do previously, but didn't have the
time.  Not that I do now, but now that we'll be showing some more robust
diagnostics to users, it ought to look decent.

DEV-13430
main
Mike Gerwitz 2022-12-16 16:24:50 -05:00
parent 8c4923274a
commit 6d9ca6947a
3 changed files with 41 additions and 0 deletions

View File

@ -124,6 +124,10 @@ impl<R: SpanResolver> Reporter for VisualReporter<R> {
// which is more aesthetically pleasing.
report.normalize_gutters();
// Let sections perform any final formatting,
// e.g. to trim or merge padding.
report.finalize_sections();
if report.level.is_error() {
// Not worried about overflow panic
// (you have bigger problems if there are that many errors).
@ -298,6 +302,11 @@ impl<'d, D: Diagnostic> Report<'d, D> {
sec.line_max = self.line_max;
}
}
/// Finalize section formatting before display to the user.
fn finalize_sections(&mut self) {
self.secs.iter_mut().for_each(Section::finalize)
}
}
impl<'d, D: Diagnostic> Extend<Section<'d>> for Report<'d, D> {
@ -469,6 +478,7 @@ impl<'s, 'd> Section<'d> {
SectionLine::SourceLinePadding,
SectionLine::SourceLine(src.into()),
SectionLine::SourceLineMark(LineMark { col, level, label }),
SectionLine::SourceLinePadding,
]);
} else {
dest.extend(vec![
@ -538,6 +548,27 @@ impl<'s, 'd> Section<'d> {
fn gutter_text_width(&self) -> usize {
self.line_max.ilog10().add(1).max(2) as usize
}
/// Finalize formatting of this section before display to the user.
///
/// This is the last chance to clean things up.
fn finalize(&mut self) {
use SectionLine::SourceLinePadding;
// Padding is added conservatively during generation,
// which may lead to adjacent padding for multi-line spans.
// That padding can be merged into a single line.
self.body.dedup_by(|a, b| match (a, b) {
(SourceLinePadding, SourceLinePadding) => true,
_ => false,
});
// Padding at the very end of the section is not desirable since the
// report already adds padding around sections.
if self.body.last() == Some(&SourceLinePadding) {
self.body.pop();
}
}
}
impl<'d, 'a, S> From<MaybeResolvedSpan<'d, S>> for Section<'d>

View File

@ -199,6 +199,8 @@ fn section_from_mspan_resolved() {
label: None,
}),
SectionLine::SourceLinePadding,
// Will be stripped during finalization
SectionLine::SourceLinePadding,
SectionLine::SourceLine(src_lines[1].clone().into()),
SectionLine::SourceLineMark(LineMark {
level: Level::Note,
@ -206,6 +208,8 @@ fn section_from_mspan_resolved() {
// Label at last source line
label: Some("test label".into()),
}),
// Will be stripped during finalization
SectionLine::SourceLinePadding,
],
line_max: 2.unwrap_into(),
}

View File

@ -241,6 +241,7 @@ error: multiple adjacent same span with labels
|
1 | bar/baz line 1
| ^^^^^^ error: A label
|
= error: C label
"
);
@ -275,12 +276,14 @@ error: eq context neq offset/len
|
1 | bar/baz line 1
| ^^^
|
= error: A, first label, after mark
--> bar/baz:1:1
|
1 | bar/baz line 1
| ^^^^^^^ error: B, different length
|
= error: B, collapse
--> bar/baz:2:1
@ -335,6 +338,7 @@ error: multiple adjacent different context
|
1 | foo/bar line 1
| ^^^^^^^
|
= error: A, first, after marked
= error: A, collapsed
@ -342,6 +346,7 @@ error: multiple adjacent different context
|
1 | bar/baz line 1
| ^^^^^^^ error: B, first, no marked
|
= error: B, collapsed
--> foo/bar:1:1
@ -381,6 +386,7 @@ internal error: multiple spans with labels of different severity level
|
4 | foo/bar line 4
| !!!!!! internal error: an internal error
|
= error: an error
= note: a note
= help: a help message