Skip to content

Commit 66b8fe1

Browse files
committed
Backport: Do not touch module with #![rustfmt::skip] (4297)
Although the implementation is slightly different than the original PR, the general idea is the same. After collecting all modules we want to exclude formatting those that contain the #![rustfmt::skip] attribute.
1 parent 4389a4c commit 66b8fe1

File tree

9 files changed

+86
-25
lines changed

9 files changed

+86
-25
lines changed

src/formatting.rs

+34-11
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::io::{self, Write};
55
use std::time::{Duration, Instant};
66

77
use rustc_ast::ast;
8+
use rustc_ast::AstLike;
89
use rustc_span::Span;
910

1011
use self::newline_style::apply_newline_style;
@@ -15,7 +16,7 @@ use crate::issues::BadIssueSeeker;
1516
use crate::modules::Module;
1617
use crate::syntux::parser::{DirectoryOwnership, Parser, ParserError};
1718
use crate::syntux::session::ParseSess;
18-
use crate::utils::count_newlines;
19+
use crate::utils::{contains_skip, count_newlines};
1920
use crate::visitor::FmtVisitor;
2021
use crate::{modules, source_file, ErrorKind, FormatReport, Input, Session};
2122

@@ -58,6 +59,32 @@ impl<'b, T: Write + 'b> Session<'b, T> {
5859
}
5960
}
6061

62+
/// Determine if a module should be skipped. True if the module should be skipped, false otherwise.
63+
fn should_skip_module<T: FormatHandler>(
64+
config: &Config,
65+
context: &FormatContext<'_, T>,
66+
input_is_stdin: bool,
67+
main_file: &FileName,
68+
path: &FileName,
69+
module: &Module<'_>,
70+
) -> bool {
71+
if contains_skip(module.attrs()) {
72+
return true;
73+
}
74+
75+
let source_file = context.parse_session.span_to_file_contents(module.span);
76+
let src = source_file.src.as_ref().expect("SourceFile without src");
77+
78+
let should_ignore = (!input_is_stdin && context.ignore_file(&path))
79+
|| (!config.format_generated_files() && is_generated_file(src));
80+
81+
if (config.skip_children() && path != main_file) || should_ignore {
82+
return true;
83+
}
84+
85+
false
86+
}
87+
6188
// Format an entire crate (or subset of the module tree).
6289
fn format_project<T: FormatHandler>(
6390
input: Input,
@@ -97,23 +124,19 @@ fn format_project<T: FormatHandler>(
97124
directory_ownership.unwrap_or(DirectoryOwnership::UnownedViaBlock),
98125
!input_is_stdin && !config.skip_children(),
99126
)
100-
.visit_crate(&krate)?;
127+
.visit_crate(&krate)?
128+
.into_iter()
129+
.filter(|(path, module)| {
130+
!should_skip_module(config, &context, input_is_stdin, &main_file, path, module)
131+
})
132+
.collect::<Vec<_>>();
101133

102134
timer = timer.done_parsing();
103135

104136
// Suppress error output if we have to do any further parsing.
105137
context.parse_session.set_silent_emitter();
106138

107139
for (path, module) in files {
108-
let source_file = context.parse_session.span_to_file_contents(module.span);
109-
let src = source_file.src.as_ref().expect("SourceFile without src");
110-
111-
let should_ignore = (!input_is_stdin && context.ignore_file(&path))
112-
|| (!config.format_generated_files() && is_generated_file(src));
113-
114-
if (config.skip_children() && path != main_file) || should_ignore {
115-
continue;
116-
}
117140
should_emit_verbose(input_is_stdin, config, || println!("Formatting {}", path));
118141
context.format_file(path, &module, is_macro_def)?;
119142
}

src/test/configuration_snippet.rs

+13-8
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,7 @@ impl ConfigCodeBlock {
110110
assert!(self.code_block.is_some() && self.code_block_start.is_some());
111111

112112
// See if code block begins with #![rustfmt::skip].
113-
let fmt_skip = self
114-
.code_block
115-
.as_ref()
116-
.unwrap()
117-
.lines()
118-
.nth(0)
119-
.unwrap_or("")
120-
== "#![rustfmt::skip]";
113+
let fmt_skip = self.fmt_skip();
121114

122115
if self.config_name.is_none() && !fmt_skip {
123116
write_message(&format!(
@@ -138,6 +131,17 @@ impl ConfigCodeBlock {
138131
true
139132
}
140133

134+
/// True if the code block starts with #![rustfmt::skip]
135+
fn fmt_skip(&self) -> bool {
136+
self.code_block
137+
.as_ref()
138+
.unwrap()
139+
.lines()
140+
.nth(0)
141+
.unwrap_or("")
142+
== "#![rustfmt::skip]"
143+
}
144+
141145
fn has_parsing_errors<T: Write>(&self, session: &Session<'_, T>) -> bool {
142146
if session.has_parsing_errors() {
143147
write_message(&format!(
@@ -251,6 +255,7 @@ fn configuration_snippet_tests() {
251255
let blocks = get_code_blocks();
252256
let failures = blocks
253257
.iter()
258+
.filter(|block| !block.fmt_skip())
254259
.map(ConfigCodeBlock::formatted_is_idempotent)
255260
.fold(0, |acc, r| acc + (!r as u32));
256261

src/test/mod_resolver.rs

+9
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,12 @@ fn out_of_line_nested_inline_within_out_of_line() {
4141
],
4242
);
4343
}
44+
45+
#[test]
46+
fn skip_out_of_line_nested_inline_within_out_of_line() {
47+
// See also https://github.com/rust-lang/rustfmt/issues/5065
48+
verify_mod_resolution(
49+
"tests/mod-resolver/skip-files-issue-5065/main.rs",
50+
&["tests/mod-resolver/skip-files-issue-5065/one.rs"],
51+
);
52+
}

src/visitor.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -948,12 +948,13 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
948948

949949
pub(crate) fn format_separate_mod(&mut self, m: &Module<'_>, end_pos: BytePos) {
950950
self.block_indent = Indent::empty();
951-
if self.visit_attrs(m.attrs(), ast::AttrStyle::Inner) {
952-
self.push_skipped_with_span(m.attrs(), m.span, m.span);
953-
} else {
954-
self.walk_mod_items(&m.items);
955-
self.format_missing_with_indent(end_pos);
956-
}
951+
let skipped = self.visit_attrs(m.attrs(), ast::AttrStyle::Inner);
952+
assert!(
953+
!skipped,
954+
"Skipping module must be handled before reaching this line."
955+
);
956+
self.walk_mod_items(&m.items);
957+
self.format_missing_with_indent(end_pos);
957958
}
958959

959960
pub(crate) fn skip_empty_lines(&mut self, end_pos: BytePos) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#![rustfmt::skip]
2+
3+
mod bar {
4+
5+
mod baz;}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn baz() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#![rustfmt::skip]
2+
3+
mod foo;
4+
mod one;
5+
6+
fn main() {println!("Hello, world!");
7+
}
8+
9+
// trailing commet
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
struct One { value: String }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![rustfmt::skip]
2+
3+
fn main() {
4+
println!("Hello, world!");
5+
}
6+
7+
// Trailing Comment

0 commit comments

Comments
 (0)