diff options
| author | kennytm <kennytm@gmail.com> | 2018-12-14 22:10:07 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-12-14 22:10:07 +0800 |
| commit | 35fe8c92e9b8e9d3f3b4745a6deab71d79aee4e3 (patch) | |
| tree | 3a3e3f5da121a9886bfd11328ce5f0be26322d38 /src/libsyntax/parse | |
| parent | 795f18efb8cfe6b72e23b629e0cf4b1e6d9078d8 (diff) | |
| parent | 85b50d03120cf7bd1beb472a78ce9427c0d8d06e (diff) | |
| download | rust-35fe8c92e9b8e9d3f3b4745a6deab71d79aee4e3.tar.gz rust-35fe8c92e9b8e9d3f3b4745a6deab71d79aee4e3.zip | |
Rollup merge of #56658 - Xanewok:non-panicking-file-parser, r=petrochenkov
Add non-panicking `maybe_new_parser_from_file` variant Add (seemingly?) missing `maybe_new_parser_from_file` constructor variant. Disclaimer: I'm not certain this is the correct approach - just found out we don't have this when working on a Rustfmt PR to catch/prevent more Rust parser panics: https://github.com/rust-lang/rustfmt/pull/3240 and tried to make it work somehow.
Diffstat (limited to 'src/libsyntax/parse')
| -rw-r--r-- | src/libsyntax/parse/mod.rs | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index eb71003d3d0..10c451e1f81 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -15,7 +15,7 @@ use ast::{self, CrateConfig, NodeId}; use early_buffered_lints::{BufferedEarlyLint, BufferedEarlyLintId}; use source_map::{SourceMap, FilePathMapping}; use syntax_pos::{Span, SourceFile, FileName, MultiSpan}; -use errors::{Handler, ColorConfig, Diagnostic, DiagnosticBuilder}; +use errors::{FatalError, Level, Handler, ColorConfig, Diagnostic, DiagnosticBuilder}; use feature_gate::UnstableFeatures; use parse::parser::Parser; use ptr::P; @@ -192,6 +192,14 @@ pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path) -> Parser<'a> source_file_to_parser(sess, file_to_source_file(sess, path, None)) } +/// Create a new parser, returning buffered diagnostics if the file doesn't +/// exist or from lexing the initial token stream. +pub fn maybe_new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path) + -> Result<Parser<'a>, Vec<Diagnostic>> { + let file = try_file_to_source_file(sess, path, None).map_err(|db| vec![db])?; + maybe_source_file_to_parser(sess, file) +} + /// Given a session, a crate config, a path, and a span, add /// the file at the given path to the source_map, and return a parser. /// On an error, use the given span as the source of the problem. @@ -237,17 +245,30 @@ pub fn new_parser_from_tts(sess: &ParseSess, tts: Vec<TokenTree>) -> Parser { // base abstractions /// Given a session and a path and an optional span (for error reporting), +/// add the path to the session's source_map and return the new source_file or +/// error when a file can't be read. +fn try_file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>) + -> Result<Lrc<SourceFile>, Diagnostic> { + sess.source_map().load_file(path) + .map_err(|e| { + let msg = format!("couldn't read {}: {}", path.display(), e); + let mut diag = Diagnostic::new(Level::Fatal, &msg); + if let Some(sp) = spanopt { + diag.set_span(sp); + } + diag + }) +} + +/// Given a session and a path and an optional span (for error reporting), /// add the path to the session's source_map and return the new source_file. fn file_to_source_file(sess: &ParseSess, path: &Path, spanopt: Option<Span>) -> Lrc<SourceFile> { - match sess.source_map().load_file(path) { + match try_file_to_source_file(sess, path, spanopt) { Ok(source_file) => source_file, - Err(e) => { - let msg = format!("couldn't read {}: {}", path.display(), e); - match spanopt { - Some(sp) => sess.span_diagnostic.span_fatal(sp, &msg).raise(), - None => sess.span_diagnostic.fatal(&msg).raise() - } + Err(d) => { + DiagnosticBuilder::new_diagnostic(&sess.span_diagnostic, d).emit(); + FatalError.raise(); } } } |
