diff --git a/src/formatting.rs b/src/formatting.rs index e6995210a94..23d90d9e2e0 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -40,12 +40,10 @@ pub(crate) fn format_input_inner( rustc_span::create_session_if_not_set_then(self.config.edition().into(), |_| { if self.config.disable_all_formatting() { // When the input is from stdin, echo back the input. - if let Input::Text(ref buf) = input { - if let Err(e) = io::stdout().write_all(buf.as_bytes()) { - return Err(From::from(e)); - } - } - return Ok(FormatReport::new()); + return match input { + Input::Text(ref buf) => echo_back_stdin(buf), + _ => Ok(FormatReport::new()), + }; } let config = &self.config.clone(); @@ -94,6 +92,13 @@ fn should_skip_module( false } +fn echo_back_stdin(input: &str) -> Result { + if let Err(e) = io::stdout().write_all(input.as_bytes()) { + return Err(From::from(e)); + } + Ok(FormatReport::new()) +} + // Format an entire crate (or subset of the module tree). fn format_project( input: Input, @@ -136,7 +141,8 @@ fn format_project( .visit_crate(&krate)? .into_iter() .filter(|(path, module)| { - !should_skip_module(config, &context, input_is_stdin, &main_file, path, module) + input_is_stdin + || !should_skip_module(config, &context, input_is_stdin, &main_file, path, module) }) .collect::>(); @@ -146,6 +152,14 @@ fn format_project( context.parse_session.set_silent_emitter(); for (path, module) in files { + if input_is_stdin && contains_skip(module.attrs()) { + return echo_back_stdin( + context + .parse_session + .snippet_provider(module.span) + .entire_snippet(), + ); + } should_emit_verbose(input_is_stdin, config, || println!("Formatting {}", path)); context.format_file(path, &module, is_macro_def)?; } diff --git a/src/test/mod.rs b/src/test/mod.rs index 0eda9e4b116..18ec8620fac 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -578,6 +578,30 @@ fn stdin_generated_files_issue_5172() { ); } +#[test] +fn stdin_handles_mod_inner_ignore_attr() { + // see https://github.com/rust-lang/rustfmt/issues/5368 + init_log(); + let input = String::from("#![rustfmt::skip]\n\nfn main() { }"); + let mut child = Command::new(rustfmt().to_str().unwrap()) + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .expect("failed to execute child"); + + { + let stdin = child.stdin.as_mut().expect("failed to get stdin"); + stdin + .write_all(input.as_bytes()) + .expect("failed to write stdin"); + } + + let output = child.wait_with_output().expect("failed to wait on child"); + assert!(output.status.success()); + assert!(output.stderr.is_empty()); + assert_eq!(input, String::from_utf8(output.stdout).unwrap()); +} + #[test] fn format_lines_errors_are_reported() { init_log();