diff --git a/src/renderer/display_list.rs b/src/renderer/display_list.rs index eea49718..6a1cbd9f 100644 --- a/src/renderer/display_list.rs +++ b/src/renderer/display_list.rs @@ -72,18 +72,12 @@ impl<'a> fmt::Debug for DisplayList<'a> { impl<'a> Display for DisplayList<'a> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let lineno_width = self.body.iter().fold(0, |max, set| { - set.display_lines.iter().fold(max, |max, line| match line { - DisplayLine::Source { lineno, .. } => cmp::max(lineno.unwrap_or(0), max), - _ => max, - }) - }); - let lineno_width = if lineno_width == 0 { - lineno_width - } else if self.anonymized_line_numbers { - ANONYMIZED_LINE_NUM.len() - } else { - ((lineno_width as f64).log10().floor() as usize) + 1 + let max_lineno = get_max_lineno(&self.body); + let lineno_width = match max_lineno { + None => 0, + Some(_max) if self.anonymized_line_numbers => ANONYMIZED_LINE_NUM.len(), + Some(0) => 1, + Some(max) => (max as f64).log10().floor() as usize + 1, }; let multiline_depth = self.body.iter().fold(0, |max, set| { @@ -150,6 +144,16 @@ impl<'a> DisplayList<'a> { } } +fn get_max_lineno(body: &[DisplaySet<'_>]) -> Option { + let max_lineno = body.iter().fold(None, |max, set| { + set.display_lines.iter().fold(max, |max, line| match line { + DisplayLine::Source { lineno, .. } => cmp::max(max, *lineno), + _ => max, + }) + }); + max_lineno +} + #[derive(Debug, PartialEq)] pub(crate) struct DisplaySet<'a> { pub(crate) display_lines: Vec>, diff --git a/tests/formatter.rs b/tests/formatter.rs index 7f914de9..40e5f40f 100644 --- a/tests/formatter.rs +++ b/tests/formatter.rs @@ -905,3 +905,25 @@ error: unused optional dependency let renderer = Renderer::plain(); assert_data_eq!(renderer.render(input).to_string(), expected); } + +// for issue 57 +#[test] +fn test_line_number_0() { + let input = Level::Error.title("dummy").snippet( + Snippet::source("foo") + .origin("file/path") + .line_start(0) + .annotation(Level::Error.span(2..3)), // bar\nbaz + ); + + let expected = str![[r#" +error: dummy + --> file/path:0:3 + | +0 | foo + | ^ + | +"#]]; + let renderer = Renderer::plain(); + assert_data_eq!(renderer.render(input).to_string(), expected); +}