diff --git a/src/test/mod.rs b/src/test/mod.rs index 3353b78b221..69e3c53f85b 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -799,7 +799,7 @@ fn check_files(files: Vec, opt_config: &Option) -> (Vec { print!("{}", FormatReportFormatterBuilder::new(report).build()); fails += 1; @@ -846,6 +846,10 @@ fn print_mismatches String>( fn read_config(filename: &Path) -> Config { let sig_comments = read_significant_comments(filename); + config_from_comments(filename, &sig_comments) +} + +fn config_from_comments(filename: &Path, sig_comments: &HashMap) -> Config { let (edition, style_edition, version) = get_editions_from_comments(&sig_comments); // Look for a config file. If there is a 'config' property in the significant comments, use // that. Otherwise, if there are no significant comments at all, look for a config file with @@ -866,7 +870,7 @@ fn read_config(filename: &Path) -> Config { ) }; - for (key, val) in &sig_comments { + for (key, val) in sig_comments { if key != "target" && key != "config" && key != "unstable" { config.override_value(key, val); } @@ -910,14 +914,14 @@ fn get_editions_from_comments( fn idempotent_check( filename: &PathBuf, opt_config: &Option, + sig_comments: &HashMap, ) -> Result { - let sig_comments = read_significant_comments(filename); let config = if let Some(ref config_file_path) = opt_config { - let (edition, style_edition, version) = get_editions_from_comments(&sig_comments); + let (edition, style_edition, version) = get_editions_from_comments(sig_comments); Config::from_toml_path(config_file_path, edition, style_edition, version) .expect("`rustfmt.toml` not found") } else { - read_config(filename) + config_from_comments(filename, sig_comments) }; let (parsing_errors, source_file, format_report) = format_file(filename, config); if parsing_errors { diff --git a/src/visitor.rs b/src/visitor.rs index 55f9a4d8c8b..5b149f7c251 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -808,7 +808,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { // So here we need to take a minimum between the two. let lo = std::cmp::min(attrs_end + 1, first_line); self.push_rewrite_inner(item_span, None); - let hi = self.line_number + 1; + let hi = self.psess.line_of_byte_pos(item_span.hi()); self.skipped_range.borrow_mut().push((lo, hi)); } diff --git a/tests/target/skip_with_overflow.rs b/tests/target/skip_with_overflow.rs new file mode 100644 index 00000000000..a3a03b80bc3 --- /dev/null +++ b/tests/target/skip_with_overflow.rs @@ -0,0 +1,22 @@ +// rustfmt-error_on_line_overflow: true +// rustfmt-error_on_unformatted: true +// rustfmt-max_width: 100 + +// This is a regression test for a bug where when calculating +// the end of a skip range when use a FmtVisitor's 'line_number' which was _assumed_ to be relative +// to the entire file, but when nesting a visitor inside another would be _relative_ to the start of +// that block + +fn foo() { + let _ = || { + // the bug: we'd mark the region (lo=16, hi=10) as skipped + // the lo value is correct, but the hi value is the offset of the line after the end of the + // 'if' block relative to the start of the '|| {' block + #[rustfmt::skip] + if true { + println!( + "this is a very long string, it goes over max_width. This is just padding to push it over" + ); + } + }; +}