diff --git a/src/syntux/parser.rs b/src/syntux/parser.rs index 711dfc80c2c..78de08b993e 100644 --- a/src/syntux/parser.rs +++ b/src/syntux/parser.rs @@ -23,7 +23,6 @@ pub(crate) struct Directory { /// A parser for Rust source code. pub(crate) struct Parser<'a> { parser: RawParser<'a>, - sess: &'a ParseSess, } /// A builder for the `Parser`. @@ -71,7 +70,7 @@ impl<'a> ParserBuilder<'a> { } }; - Ok(Parser { parser, sess }) + Ok(Parser { parser }) } fn parser( @@ -150,6 +149,25 @@ impl<'a> Parser<'a> { input: Input, directory_ownership: Option, sess: &'a ParseSess, + ) -> Result { + let krate = Parser::parse_crate_inner(config, input, directory_ownership, sess)?; + if !sess.has_errors() { + return Ok(krate); + } + + if sess.can_reset_errors() { + sess.reset_errors(); + return Ok(krate); + } + + Err(ParserError::ParseError) + } + + fn parse_crate_inner( + config: &'a Config, + input: Input, + directory_ownership: Option, + sess: &'a ParseSess, ) -> Result { let mut parser = ParserBuilder::default() .config(config) @@ -157,26 +175,14 @@ impl<'a> Parser<'a> { .directory_ownership(directory_ownership) .sess(sess) .build()?; - - parser.parse_crate_inner() + parser.parse_crate_mod() } - fn parse_crate_inner(&mut self) -> Result { + fn parse_crate_mod(&mut self) -> Result { let mut parser = AssertUnwindSafe(&mut self.parser); match catch_unwind(move || parser.parse_crate_mod()) { - Ok(Ok(krate)) => { - if !self.sess.has_errors() { - return Ok(krate); - } - - if self.sess.can_reset_errors() { - self.sess.reset_errors(); - return Ok(krate); - } - - Err(ParserError::ParseError) - } + Ok(Ok(k)) => Ok(k), Ok(Err(mut db)) => { db.emit(); Err(ParserError::ParseError) diff --git a/src/test/mod.rs b/src/test/mod.rs index 57b5f2a78cd..9b3ca717152 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -11,14 +11,12 @@ use std::thread; use crate::config::{Color, Config, EmitMode, FileName, NewlineStyle, ReportTactic}; use crate::formatting::{ReportedErrors, SourceFile}; -use crate::modules::{ModuleResolutionError, ModuleResolutionErrorKind}; use crate::rustfmt_diff::{make_diff, print_diff, DiffLine, Mismatch, ModifiedChunk, OutputWriter}; use crate::source_file; -use crate::{ - is_nightly_channel, ErrorKind, FormatReport, FormatReportFormatterBuilder, Input, Session, -}; +use crate::{is_nightly_channel, FormatReport, FormatReportFormatterBuilder, Input, Session}; mod configuration_snippet; +mod parser; const DIFF_CONTEXT_SIZE: usize = 3; @@ -485,34 +483,6 @@ fn format_lines_errors_are_reported_with_tabs() { assert!(session.has_formatting_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 input_file = PathBuf::from(filename); - let exp_mod_name = "invalid"; - let config = read_config(&input_file); - let mut session = Session::::new(config, None); - if let Err(ErrorKind::ModuleResolutionError(ModuleResolutionError { module, kind })) = - session.format(Input::File(filename.into())) - { - assert_eq!(&module, exp_mod_name); - if let ModuleResolutionErrorKind::ParseError { - file: unparseable_file, - } = kind - { - assert_eq!( - unparseable_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, opt_config: &Option) -> (Vec, u32, u32) { diff --git a/src/test/parser.rs b/src/test/parser.rs new file mode 100644 index 00000000000..75aed32e68b --- /dev/null +++ b/src/test/parser.rs @@ -0,0 +1,50 @@ +use std::io; +use std::path::PathBuf; + +use super::read_config; + +use crate::modules::{ModuleResolutionError, ModuleResolutionErrorKind}; +use crate::{ErrorKind, Input, Session}; + +#[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 input_file = PathBuf::from(filename); + let exp_mod_name = "invalid"; + let config = read_config(&input_file); + let mut session = Session::::new(config, None); + if let Err(ErrorKind::ModuleResolutionError(ModuleResolutionError { module, kind })) = + session.format(Input::File(filename.into())) + { + assert_eq!(&module, exp_mod_name); + if let ModuleResolutionErrorKind::ParseError { + file: unparseable_file, + } = kind + { + assert_eq!( + unparseable_file, + PathBuf::from("tests/parser/issue-4126/invalid.rs"), + ); + } else { + panic!("Expected parser error"); + } + } else { + panic!("Expected ModuleResolution operation error"); + } +} + +fn assert_parser_error(filename: &str) { + let file = PathBuf::from(filename); + let config = read_config(&file); + let mut session = Session::::new(config, None); + let _ = session.format(Input::File(filename.into())).unwrap(); + assert!(session.has_parsing_errors()); +} + +#[test] +fn crate_parsing_errors_on_unclosed_delims() { + // See also https://github.com/rust-lang/rustfmt/issues/4466 + let filename = "tests/parser/unclosed-delims/issue_4466.rs"; + assert_parser_error(filename); +} diff --git a/tests/parser/unclosed-delims/issue_4466.rs b/tests/parser/unclosed-delims/issue_4466.rs new file mode 100644 index 00000000000..2c2c81c91d1 --- /dev/null +++ b/tests/parser/unclosed-delims/issue_4466.rs @@ -0,0 +1,11 @@ +fn main() { + if true { + println!("answer: {}", a_func(); + } else { + println!("don't think so."); + } +} + +fn a_func() -> i32 { + 42 +} \ No newline at end of file