diff options
| author | Caleb Cartwright <caleb.cartwright@outlook.com> | 2020-10-29 22:50:25 -0500 |
|---|---|---|
| committer | Caleb Cartwright <calebcartwright@users.noreply.github.com> | 2020-11-02 18:31:51 -0600 |
| commit | 9faba4539b24ac2db69edd385774d085bb0fd120 (patch) | |
| tree | 926899a142152ef8b30022fb5c4312f5180ad759 /src | |
| parent | e131797b62fd52f48fb59296c4c700a97250dee4 (diff) | |
fix(parser): better unclosed delims handling
Diffstat (limited to 'src')
| -rw-r--r-- | src/syntux/parser.rs | 40 | ||||
| -rw-r--r-- | src/test/mod.rs | 34 | ||||
| -rw-r--r-- | src/test/parser.rs | 50 |
3 files changed, 75 insertions, 49 deletions
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( @@ -151,32 +150,39 @@ impl<'a> Parser<'a> { directory_ownership: Option<DirectoryOwnership>, sess: &'a ParseSess, ) -> Result<ast::Crate, ParserError> { + 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<DirectoryOwnership>, + sess: &'a ParseSess, + ) -> Result<ast::Crate, ParserError> { let mut parser = ParserBuilder::default() .config(config) .input(input) .directory_ownership(directory_ownership) .sess(sess) .build()?; - - parser.parse_crate_inner() + parser.parse_crate_mod() } - fn parse_crate_inner(&mut self) -> Result<ast::Crate, ParserError> { + fn parse_crate_mod(&mut self) -> Result<ast::Crate, ParserError> { 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::<io::Stdout>::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<PathBuf>, opt_config: &Option<PathBuf>) -> (Vec<FormatReport>, 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::<io::Stdout>::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::<io::Stdout>::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); +} |
