diff --git a/src/formatting.rs b/src/formatting.rs index 2dadf8e65d2..79f3935e078 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -229,15 +229,15 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> { &visitor.buffer ); - // For some reason, the source_map does not include terminating - // newlines so we must add one on for each file. This is sad. + // The source map does not include terminating newlines, so normalize the file ending. + // Style Edition 2027 and later leave an empty formatted buffer empty. let num_newlines = count_newlines(&visitor.buffer); if self .config .file_lines() .contains_line(&path, num_newlines + 1) { - source_file::append_newline(&mut visitor.buffer); + source_file::append_newline(&mut visitor.buffer, self.config.style_edition()); } format_lines( diff --git a/src/source_file.rs b/src/source_file.rs index b0ec24f3db6..57f499274dd 100644 --- a/src/source_file.rs +++ b/src/source_file.rs @@ -3,10 +3,10 @@ use std::io::{self, Write}; use std::path::Path; use std::sync::Arc; -use crate::NewlineStyle; use crate::config::FileName; use crate::emitter::{self, Emitter}; use crate::parse::session::ParseSess; +use crate::{NewlineStyle, StyleEdition}; #[cfg(test)] use crate::config::Config; @@ -15,8 +15,11 @@ use crate::create_emitter; #[cfg(test)] use crate::formatting::FileRecord; -// Append a newline to the end of each file. -pub(crate) fn append_newline(s: &mut String) { +// Append a final newline, except when Style Edition 2027 or later produces an empty buffer. +pub(crate) fn append_newline(s: &mut String, style_edition: StyleEdition) { + if style_edition >= StyleEdition::Edition2027 && s.is_empty() { + return; + } s.push('\n'); } diff --git a/src/test/mod.rs b/src/test/mod.rs index 213c43d8887..16f645ab45a 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -49,6 +49,13 @@ const FILE_SKIP_LIST: &[&str] = &[ "cfg_mod/bar.rs", "cfg_mod/foo.rs", "cfg_mod/wasm32.rs", + // Empty and newline-only files cannot declare nightly-only 2027 style edition inline. + "empty_file_style_edition_2027.rs", + "newline_only_file_style_edition_2027.rs", + // These roots are tested with child traversal disabled by + // reorder_modules_style_edition_2027_tests. + "reorder_modules/disabled_style_edition_2027.rs", + "reorder_modules/enabled_style_edition_2027.rs", "skip/foo.rs", ]; @@ -528,6 +535,28 @@ fn self_tests() { assert_eq!(warnings, 0, "Rustfmt's code generated {warnings} warnings"); } +#[nightly_only_test] +#[test] +fn empty_files_style_edition_2027_tests() { + init_log(); + run_test_with(&TestSetting::default(), || { + let files = vec![ + PathBuf::from("tests/source/empty_file_style_edition_2027.rs"), + PathBuf::from("tests/source/newline_only_file_style_edition_2027.rs"), + ]; + let config = Some(PathBuf::from( + "tests/config/empty_file_style_edition_2027.toml", + )); + let (_reports, count, fails) = check_files(files, &config); + + println!("Ran {count} empty_files_style_edition_2027 tests."); + assert_eq!( + fails, 0, + "{fails} empty_files_style_edition_2027 tests failed" + ); + }); +} + #[test] fn format_files_find_new_files_via_cfg_if() { init_log(); @@ -605,6 +634,42 @@ fn format_files_find_new_files_via_cfg_select() { }); } +#[nightly_only_test] +#[test] +fn reorder_modules_style_edition_2027_tests() { + init_log(); + run_test_with(&TestSetting::default(), || { + let test_cases = [ + ( + "disabled_style_edition_2027.rs", + "tests/config/reorder_modules_disabled_style_edition_2027.toml", + ), + ( + "enabled_style_edition_2027.rs", + "tests/config/reorder_modules_enabled_style_edition_2027.toml", + ), + ]; + let mut count = 0; + let mut fails = 0; + + for (test_file, config_file) in test_cases { + let files = vec![ + PathBuf::from("tests/source/reorder_modules").join(test_file), + PathBuf::from("tests/target/reorder_modules").join(test_file), + ]; + let (_, case_count, case_fails) = check_files(files, &Some(PathBuf::from(config_file))); + count += case_count; + fails += case_fails; + } + + println!("Ran {count} reorder_modules_style_edition_2027 tests."); + assert_eq!( + fails, 0, + "{fails} reorder_modules_style_edition_2027 tests failed" + ); + }); +} + #[test] fn stdin_formatting_smoke_test() { init_log(); diff --git a/tests/config/empty_file_style_edition_2027.toml b/tests/config/empty_file_style_edition_2027.toml new file mode 100644 index 00000000000..9fe178ccbc2 --- /dev/null +++ b/tests/config/empty_file_style_edition_2027.toml @@ -0,0 +1 @@ +style_edition = "2027" diff --git a/tests/config/newline_file.toml b/tests/config/newline_file.toml new file mode 100644 index 00000000000..3501136812c --- /dev/null +++ b/tests/config/newline_file.toml @@ -0,0 +1 @@ +style_edition = "2024" diff --git a/tests/config/reorder_modules_disabled_style_edition_2027.toml b/tests/config/reorder_modules_disabled_style_edition_2027.toml new file mode 100644 index 00000000000..1d446fbbde2 --- /dev/null +++ b/tests/config/reorder_modules_disabled_style_edition_2027.toml @@ -0,0 +1,3 @@ +reorder_modules = false +skip_children = true +style_edition = "2027" diff --git a/tests/config/reorder_modules_enabled_style_edition_2027.toml b/tests/config/reorder_modules_enabled_style_edition_2027.toml new file mode 100644 index 00000000000..2603c2a562f --- /dev/null +++ b/tests/config/reorder_modules_enabled_style_edition_2027.toml @@ -0,0 +1,3 @@ +reorder_modules = true +skip_children = true +style_edition = "2027" diff --git a/tests/source/empty_file_style_edition_2027.rs b/tests/source/empty_file_style_edition_2027.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/source/newline_file.rs b/tests/source/newline_file.rs new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/tests/source/newline_file.rs @@ -0,0 +1 @@ + diff --git a/tests/source/newline_only_file_style_edition_2027.rs b/tests/source/newline_only_file_style_edition_2027.rs new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/tests/source/newline_only_file_style_edition_2027.rs @@ -0,0 +1 @@ + diff --git a/tests/target/empty_file_style_edition_2027.rs b/tests/target/empty_file_style_edition_2027.rs new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/target/newline_file.rs b/tests/target/newline_file.rs new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/tests/target/newline_file.rs @@ -0,0 +1 @@ + diff --git a/tests/target/newline_only_file_style_edition_2027.rs b/tests/target/newline_only_file_style_edition_2027.rs new file mode 100644 index 00000000000..e69de29bb2d