@@ -15,7 +15,7 @@ use ast::{self, CrateConfig, NodeId};
15
15
use early_buffered_lints:: { BufferedEarlyLint , BufferedEarlyLintId } ;
16
16
use source_map:: { SourceMap , FilePathMapping } ;
17
17
use syntax_pos:: { Span , SourceFile , FileName , MultiSpan } ;
18
- use errors:: { Handler , ColorConfig , Diagnostic , DiagnosticBuilder } ;
18
+ use errors:: { FatalError , Level , Handler , ColorConfig , Diagnostic , DiagnosticBuilder } ;
19
19
use feature_gate:: UnstableFeatures ;
20
20
use parse:: parser:: Parser ;
21
21
use ptr:: P ;
@@ -192,6 +192,14 @@ pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path) -> Parser<'a>
192
192
source_file_to_parser ( sess, file_to_source_file ( sess, path, None ) )
193
193
}
194
194
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
+
195
203
/// Given a session, a crate config, a path, and a span, add
196
204
/// the file at the given path to the source_map, and return a parser.
197
205
/// 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 {
236
244
237
245
// base abstractions
238
246
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
+
239
263
/// Given a session and a path and an optional span (for error reporting),
240
264
/// add the path to the session's source_map and return the new source_file.
241
265
fn file_to_source_file ( sess : & ParseSess , path : & Path , spanopt : Option < Span > )
242
266
-> Lrc < SourceFile > {
243
- match sess . source_map ( ) . load_file ( path) {
267
+ match try_file_to_source_file ( sess , path, spanopt ) {
244
268
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 ( ) ;
251
272
}
252
273
}
253
274
}
0 commit comments