diff --git a/src/lib.rs b/src/lib.rs index b9ab3ffd989..8800e200fa4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,6 +28,7 @@ extern crate thin_vec; extern crate rustc_driver; use std::cell::RefCell; +use std::cmp::min; use std::collections::HashMap; use std::fmt; use std::io::{self, Write}; @@ -385,9 +386,15 @@ fn format_code_block( .snippet .rfind('}') .unwrap_or_else(|| formatted.snippet.len()); + + // It's possible that `block_len < FN_MAIN_PREFIX.len()`. This can happen if the code block was + // formatted into the empty string, leading to the enclosing `fn main() {\n}` being formatted + // into `fn main() {}`. In this case no unindentation is done. + let block_start = min(FN_MAIN_PREFIX.len(), block_len); + let mut is_indented = true; let indent_str = Indent::from_width(config, config.tab_spaces()).to_string(config); - for (kind, ref line) in LineClasses::new(&formatted.snippet[FN_MAIN_PREFIX.len()..block_len]) { + for (kind, ref line) in LineClasses::new(&formatted.snippet[block_start..block_len]) { if !is_first { result.push('\n'); } else { diff --git a/tests/source/issue_5730.rs b/tests/source/issue_5730.rs new file mode 100644 index 00000000000..9a3f4f0d07a --- /dev/null +++ b/tests/source/issue_5730.rs @@ -0,0 +1,3 @@ +macro_rules! statement { + () => {;}; +} diff --git a/tests/target/issue_5730.rs b/tests/target/issue_5730.rs new file mode 100644 index 00000000000..7922fdcc90f --- /dev/null +++ b/tests/target/issue_5730.rs @@ -0,0 +1,3 @@ +macro_rules! statement { + () => {}; +}