Skip to content

Commit

Permalink
fix: handle recoverable submod parse errors correctly (#4200)
Browse files Browse the repository at this point in the history
  • Loading branch information
calebcartwright committed May 25, 2020
1 parent 15e2854 commit 3eb864e
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 10 deletions.
9 changes: 5 additions & 4 deletions rustfmt-core/rustfmt-lib/src/formatting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,6 @@ fn format_project(
});
}
};
timer = timer.done_parsing();

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

let files = modules::ModResolver::new(
&parse_session,
Expand All @@ -118,6 +114,11 @@ fn format_project(
)
.visit_crate(&krate)?;

timer = timer.done_parsing();

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

for (path, module) in files {
let should_ignore = !input_is_stdin && parse_session.ignore_file(&path);
if (!operation_setting.recursive && path != main_file) || should_ignore {
Expand Down
4 changes: 2 additions & 2 deletions rustfmt-core/rustfmt-lib/src/formatting/modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ pub(crate) struct ModResolver<'ast, 'sess> {
#[error("failed to resolve mod `{module}`: {kind}")]
#[derive(Debug, Error)]
pub struct ModuleResolutionError {
module: String,
kind: ModuleResolutionErrorKind,
pub(crate) module: String,
pub(crate) kind: ModuleResolutionErrorKind,
}

#[derive(Debug, Error)]
Expand Down
20 changes: 17 additions & 3 deletions rustfmt-core/rustfmt-lib/src/formatting/syntux/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,9 @@ impl<'a> Parser<'a> {
Ok(_attrs) => (),
Err(mut e) => {
e.cancel();
sess.reset_errors();
if sess.can_reset_errors() {
sess.reset_errors();
}
return None;
}
}
Expand All @@ -186,13 +188,25 @@ impl<'a> Parser<'a> {
Ok(m) => Some(m),
Err(mut db) => {
db.cancel();
sess.reset_errors();
if sess.can_reset_errors() {
sess.reset_errors();
}
None
}
}
}));
match result {
Ok(Some(m)) => Ok(m),
Ok(Some(m)) => {
if !sess.has_errors() {
return Ok(m);
}

if sess.can_reset_errors() {
sess.reset_errors();
return Ok(m);
}
Err(ParserError::ParseError)
}
Ok(None) => Err(ParserError::ParseError),
Err(..) if path.exists() => Err(ParserError::ParseError),
Err(_) => Err(ParserError::ParsePanicError),
Expand Down
26 changes: 25 additions & 1 deletion rustfmt-core/rustfmt-lib/src/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ use crate::emitter::rustfmt_diff::{make_diff, print_diff, Mismatch, ModifiedChun
use crate::config::{Config, FileName, NewlineStyle};
use crate::{
emitter::{emit_format_report, Color, EmitMode, EmitterConfig},
format, is_nightly_channel, FormatReport, FormatReportFormatterBuilder, Input, OperationError,
format,
formatting::modules::{ModuleResolutionError, ModuleResolutionErrorKind},
is_nightly_channel, FormatReport, FormatReportFormatterBuilder, Input, OperationError,
OperationSetting,
};

Expand Down Expand Up @@ -519,6 +521,28 @@ fn format_lines_errors_are_reported_with_tabs() {
assert!(report.has_errors());
}

#[test]
fn parser_errors_in_submods_are_surfaced() {
// See also https://github.com/rust-lang/rustfmt/issues/4126
let filename = "tests/parser/issue-4126/lib.rs";
let file = PathBuf::from(filename);
let exp_mod_name = "invalid";
let (config, operation, _) = read_config(&file);
if let Err(OperationError::ModuleResolutionError { 0: inner }) =
format_file(&file, operation, config)
{
let ModuleResolutionError { module, kind } = inner;
assert_eq!(&module, exp_mod_name);
if let ModuleResolutionErrorKind::ParseError { file } = kind {
assert_eq!(file, PathBuf::from("tests/parser/issue-4126/invalid.rs"));
} else {
panic!("Expected parser error");
}
} else {
panic!("Expected ModuleResolution operation error");
}
}

// For each file, run rustfmt and collect the output.
// Returns the number of files checked and the number of failures.
fn check_files(files: Vec<PathBuf>, opt_config: &Option<PathBuf>) -> (Vec<FormatReport>, u32, u32) {
Expand Down
6 changes: 6 additions & 0 deletions rustfmt-core/rustfmt-lib/tests/parser/issue-4126/invalid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fn foo() {
if bar && if !baz {
next_is_none = Some(true);
}
println!("foo");
}
2 changes: 2 additions & 0 deletions rustfmt-core/rustfmt-lib/tests/parser/issue-4126/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// rustfmt-recursive: true
mod invalid;

0 comments on commit 3eb864e

Please sign in to comment.