]> git.lizzy.rs Git - rust.git/commitdiff
fix: resolve some parser related bugs
authorCaleb Cartwright <caleb.cartwright@outlook.com>
Sat, 26 Sep 2020 05:00:49 +0000 (00:00 -0500)
committerCaleb Cartwright <calebcartwright@users.noreply.github.com>
Tue, 3 Nov 2020 00:31:51 +0000 (18:31 -0600)
src/syntux/parser.rs
src/syntux/session.rs

index 78de08b993ecd75e05f82968ffcc63529c59badb..3a72fb6be881c958a431c4b538939c5f08a47a07 100644 (file)
@@ -65,8 +65,11 @@ pub(crate) fn build(self) -> Result<Parser<'a>, ParserError> {
         let parser = match Self::parser(sess.inner(), input) {
             Ok(p) => p,
             Err(db) => {
-                sess.emit_diagnostics(db);
-                return Err(ParserError::ParserCreationError);
+                if let Some(diagnostics) = db {
+                    sess.emit_diagnostics(diagnostics);
+                    return Err(ParserError::ParserCreationError);
+                }
+                return Err(ParserError::ParsePanicError);
             }
         };
 
@@ -76,14 +79,18 @@ pub(crate) fn build(self) -> Result<Parser<'a>, ParserError> {
     fn parser(
         sess: &'a rustc_session::parse::ParseSess,
         input: Input,
-    ) -> Result<rustc_parse::parser::Parser<'a>, Vec<Diagnostic>> {
+    ) -> Result<rustc_parse::parser::Parser<'a>, Option<Vec<Diagnostic>>> {
         match input {
-            Input::File(ref file) => Ok(new_parser_from_file(sess, file, None)),
+            Input::File(ref file) => catch_unwind(AssertUnwindSafe(move || {
+                new_parser_from_file(sess, file, None)
+            }))
+            .map_err(|_| None),
             Input::Text(text) => rustc_parse::maybe_new_parser_from_source_str(
                 sess,
                 rustc_span::FileName::Custom("stdin".to_owned()),
                 text,
-            ),
+            )
+            .map_err(|db| Some(db)),
         }
     }
 }
@@ -120,8 +127,10 @@ pub(crate) fn parse_file_as_module(
             match parser.parse_mod(&TokenKind::Eof, ast::Unsafe::No) {
                 Ok(result) => Some(result),
                 Err(mut e) => {
-                    e.cancel();
-                    sess.reset_errors();
+                    sess.emit_or_cancel_diagnostic(&mut e);
+                    if sess.can_reset_errors() {
+                        sess.reset_errors();
+                    }
                     None
                 }
             }
index 5045eab29dd58a8f86c5f487df7275138098055c..ef5ad62674ee9b200ff5c777f8ad91d34382553f 100644 (file)
@@ -230,6 +230,17 @@ pub(super) fn emit_diagnostics(&self, diagnostics: Vec<Diagnostic>) {
         }
     }
 
+    pub(crate) fn emit_or_cancel_diagnostic(&self, diagnostic: &mut Diagnostic) {
+        self.parse_sess.span_diagnostic.emit_diagnostic(diagnostic);
+        // The Handler will check whether the diagnostic should be emitted
+        // based on the user's rustfmt configuration and the originating file
+        // that caused the parser error. If the Handler determined it should skip
+        // emission then we need to ensure the diagnostic is cancelled.
+        if !diagnostic.cancelled() {
+            diagnostic.cancel();
+        }
+    }
+
     pub(super) fn can_reset_errors(&self) -> bool {
         *self.can_reset_errors.borrow()
     }