@@ -15,7 +15,7 @@ use ast::{self, CrateConfig, NodeId};
1515use early_buffered_lints:: { BufferedEarlyLint , BufferedEarlyLintId } ;
1616use source_map:: { SourceMap , FilePathMapping } ;
1717use syntax_pos:: { Span , SourceFile , FileName , MultiSpan } ;
18- use errors:: { Handler , ColorConfig , Diagnostic , DiagnosticBuilder } ;
18+ use errors:: { FatalError , Level , Handler , ColorConfig , Diagnostic , DiagnosticBuilder } ;
1919use feature_gate:: UnstableFeatures ;
2020use parse:: parser:: Parser ;
2121use ptr:: P ;
@@ -192,6 +192,14 @@ pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path) -> Parser<'a>
192192 source_file_to_parser ( sess, file_to_source_file ( sess, path, None ) )
193193}
194194
195+ /// Create a new parser, returning buffered diagnostics if the file doesn't
196+ /// exist or from lexing the initial token stream.
197+ pub fn maybe_new_parser_from_file < ' a > ( sess : & ' a ParseSess , path : & Path )
198+ -> Result < Parser < ' a > , Vec < Diagnostic > > {
199+ let file = try_file_to_source_file ( sess, path, None ) . map_err ( |db| vec ! [ db] ) ?;
200+ maybe_source_file_to_parser ( sess, file)
201+ }
202+
195203/// Given a session, a crate config, a path, and a span, add
196204/// the file at the given path to the source_map, and return a parser.
197205/// On an error, use the given span as the source of the problem.
@@ -236,18 +244,31 @@ pub fn new_parser_from_tts(sess: &ParseSess, tts: Vec<TokenTree>) -> Parser {
236244
237245// base abstractions
238246
247+ /// Given a session and a path and an optional span (for error reporting),
248+ /// add the path to the session's source_map and return the new source_file or
249+ /// error when a file can't be read.
250+ fn try_file_to_source_file ( sess : & ParseSess , path : & Path , spanopt : Option < Span > )
251+ -> Result < Lrc < SourceFile > , Diagnostic > {
252+ sess. source_map ( ) . load_file ( path)
253+ . map_err ( |e| {
254+ let msg = format ! ( "couldn't read {}: {}" , path. display( ) , e) ;
255+ let mut diag = Diagnostic :: new ( Level :: Fatal , & msg) ;
256+ if let Some ( sp) = spanopt {
257+ diag. set_span ( sp) ;
258+ }
259+ diag
260+ } )
261+ }
262+
239263/// Given a session and a path and an optional span (for error reporting),
240264/// add the path to the session's source_map and return the new source_file.
241265fn file_to_source_file ( sess : & ParseSess , path : & Path , spanopt : Option < Span > )
242266 -> Lrc < SourceFile > {
243- match sess . source_map ( ) . load_file ( path) {
267+ match try_file_to_source_file ( sess , path, spanopt ) {
244268 Ok ( source_file) => source_file,
245- Err ( e) => {
246- let msg = format ! ( "couldn't read {}: {}" , path. display( ) , e) ;
247- match spanopt {
248- Some ( sp) => sess. span_diagnostic . span_fatal ( sp, & msg) . raise ( ) ,
249- None => sess. span_diagnostic . fatal ( & msg) . raise ( )
250- }
269+ Err ( d) => {
270+ DiagnosticBuilder :: new_diagnostic ( & sess. span_diagnostic , d) . emit ( ) ;
271+ FatalError . raise ( ) ;
251272 }
252273 }
253274}
0 commit comments