Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustfmt panics unecessarily due to redundant tabs->spaces logic #5431

Closed
BenjaminBrienen opened this issue Jul 8, 2022 · 2 comments
Closed
Labels
bug Panic, non-idempotency, invalid code, etc. only-with-option requires a non-default option value to reproduce p-low

Comments

@BenjaminBrienen
Copy link

BenjaminBrienen commented Jul 8, 2022

The code:

main.rs:

fn main() {
	println!("Hello, world!");
}

rustfmt.toml:

error_on_line_overflow = true
error_on_unformatted = true
hard_tabs = true
tab_spaces = 100

>cargo fmt

stderr: thread 'main' panicked at 'SourceAnnotation range `(100, 126)` is bigger than source length `27`', /cargo/registry/src/github.lhy31512.workers.dev-1ecc6299db9ec823/annotate-snippets-0.9.1/src/display_list/from_snippet.rs:286:9
stack backtrace:
   0: rust_begin_unwind
             at /rustc/1517f5de01c445b5124b30f02257b02b4c5ef3b2/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/1517f5de01c445b5124b30f02257b02b4c5ef3b2/library/core/src/panicking.rs:142:14
   2: annotate_snippets::display_list::from_snippet::format_slice
   3: <annotate_snippets::display_list::structs::DisplayList as core::convert::From<annotate_snippets::snippet::Snippet>>::from
   4: <rustfmt_nightly::format_report_formatter::FormatReportFormatter as core::fmt::Display>::fmt
   5: core::fmt::write
             at /rustc/1517f5de01c445b5124b30f02257b02b4c5ef3b2/library/core/src/fmt/mod.rs:1198:17
   6: std::io::Write::write_fmt
             at /rustc/1517f5de01c445b5124b30f02257b02b4c5ef3b2/library/std/src/io/mod.rs:1672:15
   7: <&std::io::stdio::Stderr as std::io::Write>::write_fmt
             at /rustc/1517f5de01c445b5124b30f02257b02b4c5ef3b2/library/std/src/io/stdio.rs:934:9
   8: <std::io::stdio::Stderr as std::io::Write>::write_fmt
             at /rustc/1517f5de01c445b5124b30f02257b02b4c5ef3b2/library/std/src/io/stdio.rs:908:9
   9: std::io::stdio::print_to
             at /rustc/1517f5de01c445b5124b30f02257b02b4c5ef3b2/library/std/src/io/stdio.rs:1014:21
  10: std::io::stdio::_eprint
             at /rustc/1517f5de01c445b5124b30f02257b02b4c5ef3b2/library/std/src/io/stdio.rs:1038:5
  11: rustfmt::format_and_emit_report::<std::io::stdio::Stdout>
  12: rustfmt::execute
  13: rustfmt::main

The error explained:

When rustfmt tries to replace the \t tab character with 100 spaces, it overflows the line. For some reason, both error_on_line_overflow AND error_on_unformatted must be true for this to produce an error. Normally, this error would be pretty-printed as in the following example where the only change is hard_tabs = false:
cargo fmt

error[internal]: line formatted, but exceeded maximum width (maximum: 100 (see `max_width` option), found: 126)
 --> /home/techn0/projects/hello_cargo/src/main.rs:2:2:101
  |
2 |                                                                                                     println!("Hello, world!");
  |                                                                                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: set `error_on_unformatted = false` to suppress the warning against comments or string literals

warning: rustfmt has failed to format. See previous 1 errors.

Again, this error only displays when both error_on_line_overflow AND error_on_unformatted are true.

The issue:

hard_tabs is true, so this error should never happen! The overflow comes from replacing tabs with 100 spaces, according to the tab_spaces option. However, tabs shouldn't be replaced with spaces according to the hard_tabs option. It would appear that this is actually handled later on in rustfmt, because the final output of the formatter correctly has tabs. This implies that there is a part of the code that replaces tabs with spaces, but doesn't actually need to, because the result of that isn't used in the final output. Alternatively, it means that there is more logic happening down the line that replaces the 100 spaces with \t tabs before outputting. Either way, redundent work is being done, causing rustfmt to panic unnecessarily. I say unnecessarily because the file does actually get formatted. With error_on_line_overflow or error_on_unformatted set to false, or with tab_spaces set to a smaller value, there wouldn't seem to be anything wrong.

This happens on many tested versions of nightly. Only the nightly toolchain can trigger this panic because error_on_line_overflow and error_on_unformatted are marked as unstable.

@BenjaminBrienen
Copy link
Author

Correction: formatting can still fail even when error_on_line_overflow and error_on_unformatted are both false.
#5433 is "solved" by changing tab_spaces to a smaller value, which shouldn't be necessary. The value should hardly be read, let alone used.

@ytmimi ytmimi added bug Panic, non-idempotency, invalid code, etc. only-with-option requires a non-default option value to reproduce p-low labels Jul 9, 2022
@ytmimi
Copy link
Contributor

ytmimi commented Jul 27, 2022

based on the discussion in #4968 I think this is a duplicate and I'm going to close this

@ytmimi ytmimi closed this as not planned Won't fix, can't repro, duplicate, stale Jul 27, 2022
@BenjaminBrienen BenjaminBrienen changed the title rustfmt panics unecessarily due to redundent tabs->spaces logic rustfmt panics unecessarily due to redundant tabs->spaces logic Oct 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Panic, non-idempotency, invalid code, etc. only-with-option requires a non-default option value to reproduce p-low
Projects
None yet
Development

No branches or pull requests

2 participants