@@ -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