15
15
#![ warn( unreachable_pub) ]
16
16
// tidy-alphabetical-end
17
17
18
- use std:: path:: Path ;
18
+ use std:: path:: { Path , PathBuf } ;
19
+ use std:: str:: Utf8Error ;
19
20
20
21
use rustc_ast as ast;
21
22
use rustc_ast:: tokenstream:: TokenStream ;
22
23
use rustc_ast:: { AttrItem , Attribute , MetaItemInner , token} ;
23
24
use rustc_ast_pretty:: pprust;
24
25
use rustc_data_structures:: sync:: Lrc ;
25
- use rustc_errors:: { Diag , FatalError , PResult } ;
26
+ use rustc_errors:: { Diag , EmissionGuarantee , FatalError , PResult } ;
26
27
use rustc_session:: parse:: ParseSess ;
28
+ use rustc_span:: source_map:: SourceMap ;
27
29
use rustc_span:: { FileName , SourceFile , Span } ;
28
30
pub use unicode_normalization:: UNICODE_VERSION as UNICODE_NORMALIZATION_VERSION ;
29
31
@@ -74,36 +76,21 @@ pub fn new_parser_from_file<'a>(
74
76
path : & Path ,
75
77
sp : Option < Span > ,
76
78
) -> Result < Parser < ' a > , Vec < Diag < ' a > > > {
77
- let source_file = psess. source_map ( ) . load_file ( path) . unwrap_or_else ( |e| {
79
+ let sm = psess. source_map ( ) ;
80
+ let source_file = sm. load_file ( path) . unwrap_or_else ( |e| {
78
81
let msg = format ! ( "couldn't read `{}`: {}" , path. display( ) , e) ;
79
82
let mut err = psess. dcx ( ) . struct_fatal ( msg) ;
80
83
if let Ok ( contents) = std:: fs:: read ( path)
81
- && let Err ( utf8err) = String :: from_utf8 ( contents)
84
+ && let Err ( utf8err) = String :: from_utf8 ( contents. clone ( ) )
82
85
{
83
- // The file exists, but it wasn't valid UTF-8.
84
- let start = utf8err. utf8_error ( ) . valid_up_to ( ) ;
85
- let note = format ! ( "invalid utf-8 at byte `{start}`" ) ;
86
- let msg = if let Some ( len) = utf8err. utf8_error ( ) . error_len ( ) {
87
- format ! ( "`{:?}` is not valid utf-8" , & utf8err. as_bytes( ) [ start..start + len] )
88
- } else {
89
- note. clone ( )
90
- } ;
91
- let contents = utf8err. into_utf8_lossy ( ) ;
92
- let source = psess. source_map ( ) . new_source_file ( path. to_owned ( ) . into ( ) , contents) ;
93
- let span = Span :: with_root_ctxt (
94
- source. normalized_byte_pos ( start as u32 ) ,
95
- source. normalized_byte_pos ( start as u32 ) ,
86
+ utf8_error (
87
+ sm,
88
+ & path. display ( ) . to_string ( ) ,
89
+ sp,
90
+ & mut err,
91
+ utf8err. utf8_error ( ) ,
92
+ & contents,
96
93
) ;
97
- if span. is_dummy ( ) {
98
- err. note ( note) ;
99
- } else {
100
- if sp. is_some ( ) {
101
- err. span_note ( span, msg) ;
102
- } else {
103
- err. span ( span) ;
104
- err. span_label ( span, msg) ;
105
- }
106
- }
107
94
}
108
95
if let Some ( sp) = sp {
109
96
err. span ( sp) ;
@@ -113,6 +100,40 @@ pub fn new_parser_from_file<'a>(
113
100
new_parser_from_source_file ( psess, source_file)
114
101
}
115
102
103
+ pub fn utf8_error < E : EmissionGuarantee > (
104
+ sm : & SourceMap ,
105
+ path : & str ,
106
+ sp : Option < Span > ,
107
+ err : & mut Diag < ' _ , E > ,
108
+ utf8err : Utf8Error ,
109
+ contents : & [ u8 ] ,
110
+ ) {
111
+ // The file exists, but it wasn't valid UTF-8.
112
+ let start = utf8err. valid_up_to ( ) ;
113
+ let note = format ! ( "invalid utf-8 at byte `{start}`" ) ;
114
+ let msg = if let Some ( len) = utf8err. error_len ( ) {
115
+ format ! ( "`{:?}` is not valid utf-8" , & contents[ start..start + len] )
116
+ } else {
117
+ note. clone ( )
118
+ } ;
119
+ let contents = String :: from_utf8_lossy ( contents) . to_string ( ) ;
120
+ let source = sm. new_source_file ( PathBuf :: from ( path) . into ( ) , contents) ;
121
+ let span = Span :: with_root_ctxt (
122
+ source. normalized_byte_pos ( start as u32 ) ,
123
+ source. normalized_byte_pos ( start as u32 ) ,
124
+ ) ;
125
+ if span. is_dummy ( ) {
126
+ err. note ( note) ;
127
+ } else {
128
+ if sp. is_some ( ) {
129
+ err. span_note ( span, msg) ;
130
+ } else {
131
+ err. span ( span) ;
132
+ err. span_label ( span, msg) ;
133
+ }
134
+ }
135
+ }
136
+
116
137
/// Given a session and a `source_file`, return a parser. Returns any buffered errors from lexing
117
138
/// the initial token stream.
118
139
fn new_parser_from_source_file (
0 commit comments