Skip to content

Commit ce1a3ef

Browse files
fix: backport fix for submod parser errors
1 parent dead3a8 commit ce1a3ef

File tree

6 files changed

+59
-12
lines changed

6 files changed

+59
-12
lines changed

src/formatting.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ fn format_project<T: FormatHandler>(
6262
let main_file = input.file_name();
6363
let input_is_stdin = main_file == FileName::Stdin;
6464

65-
let mut parse_session = ParseSess::new(config)?;
65+
let parse_session = ParseSess::new(config)?;
6666
if config.skip_children() && parse_session.ignore_file(&main_file) {
6767
return Ok(FormatReport::new());
6868
}
@@ -82,19 +82,19 @@ fn format_project<T: FormatHandler>(
8282
return Ok(report);
8383
}
8484
};
85-
timer = timer.done_parsing();
86-
87-
// Suppress error output if we have to do any further parsing.
88-
parse_session.set_silent_emitter();
8985

9086
let mut context = FormatContext::new(&krate, report, parse_session, config, handler);
9187
let files = modules::ModResolver::new(
9288
&context.parse_session,
9389
directory_ownership.unwrap_or(DirectoryOwnership::UnownedViaMod),
9490
!input_is_stdin && !config.skip_children(),
9591
)
96-
.visit_crate(&krate)
97-
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
92+
.visit_crate(&krate)?;
93+
94+
timer = timer.done_parsing();
95+
96+
// Suppress error output if we have to do any further parsing.
97+
context.parse_session.set_silent_emitter();
9898

9999
for (path, module) in files {
100100
let should_ignore = !input_is_stdin && context.ignore_file(&path);

src/modules.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ pub(crate) struct ModResolver<'ast, 'sess> {
3636
#[error("failed to resolve mod `{module}`: {kind}")]
3737
#[derive(Debug, Error)]
3838
pub struct ModuleResolutionError {
39-
module: String,
40-
kind: ModuleResolutionErrorKind,
39+
pub(crate) module: String,
40+
pub(crate) kind: ModuleResolutionErrorKind,
4141
}
4242

4343
#[derive(Debug, Error)]

src/syntux/parser.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,17 @@ impl<'a> Parser<'a> {
119119
}
120120
}));
121121
match result {
122-
Ok(Some(m)) => Ok(m),
122+
Ok(Some(m)) => {
123+
if !sess.has_errors() {
124+
return Ok(m);
125+
}
126+
127+
if sess.can_reset_errors() {
128+
sess.reset_errors();
129+
return Ok(m);
130+
}
131+
Err(ParserError::ParseError)
132+
}
123133
Ok(None) => Err(ParserError::ParseError),
124134
Err(..) if path.exists() => Err(ParserError::ParseError),
125135
Err(_) => Err(ParserError::ParsePanicError),

src/test/mod.rs

+32-2
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ use std::thread;
1111

1212
use crate::config::{Color, Config, EmitMode, FileName, NewlineStyle, ReportTactic};
1313
use crate::formatting::{ReportedErrors, SourceFile};
14-
use crate::is_nightly_channel;
14+
use crate::modules::{ModuleResolutionError, ModuleResolutionErrorKind};
1515
use crate::rustfmt_diff::{make_diff, print_diff, DiffLine, Mismatch, ModifiedChunk, OutputWriter};
1616
use crate::source_file;
17-
use crate::{FormatReport, FormatReportFormatterBuilder, Input, Session};
17+
use crate::{
18+
is_nightly_channel, ErrorKind, FormatReport, FormatReportFormatterBuilder, Input, Session,
19+
};
1820

1921
mod configuration_snippet;
2022

@@ -483,6 +485,34 @@ fn format_lines_errors_are_reported_with_tabs() {
483485
assert!(session.has_formatting_errors());
484486
}
485487

488+
#[test]
489+
fn parser_errors_in_submods_are_surfaced() {
490+
// See also https://github.com/rust-lang/rustfmt/issues/4126
491+
let filename = "tests/parser/issue-4126/lib.rs";
492+
let input_file = PathBuf::from(filename);
493+
let exp_mod_name = "invalid";
494+
let config = read_config(&input_file);
495+
let mut session = Session::<io::Stdout>::new(config, None);
496+
if let Err(ErrorKind::ModuleResolutionError(ModuleResolutionError { module, kind })) =
497+
session.format(Input::File(filename.into()))
498+
{
499+
assert_eq!(&module, exp_mod_name);
500+
if let ModuleResolutionErrorKind::ParseError {
501+
file: unparseable_file,
502+
} = kind
503+
{
504+
assert_eq!(
505+
unparseable_file,
506+
PathBuf::from("tests/parser/issue-4126/invalid.rs"),
507+
);
508+
} else {
509+
panic!("Expected parser error");
510+
}
511+
} else {
512+
panic!("Expected ModuleResolution operation error");
513+
}
514+
}
515+
486516
// For each file, run rustfmt and collect the output.
487517
// Returns the number of files checked and the number of failures.
488518
fn check_files(files: Vec<PathBuf>, opt_config: &Option<PathBuf>) -> (Vec<FormatReport>, u32, u32) {

tests/parser/issue-4126/invalid.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fn foo() {
2+
if bar && if !baz {
3+
next_is_none = Some(true);
4+
}
5+
println!("foo");
6+
}

tests/parser/issue-4126/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
mod invalid;

0 commit comments

Comments
 (0)