@@ -76,61 +76,16 @@ impl Session {
7676 self . diagnostic ( ) . handler ( ) . fatal ( msg)
7777 }
7878 pub fn span_err ( & self , sp : Span , msg : & str ) {
79- // Conditions for enabling multi-line errors:
80- if !msg. contains ( "mismatched types" ) &&
81- !msg. contains ( "type mismatch resolving" ) &&
82- !msg. contains ( "if and else have incompatible types" ) &&
83- !msg. contains ( "if may be missing an else clause" ) &&
84- !msg. contains ( "match arms have incompatible types" ) &&
85- !msg. contains ( "structure constructor specifies a structure of type" ) {
86- return self . diagnostic ( ) . span_err ( sp, msg) ;
79+ match split_msg_into_multilines ( msg) {
80+ Some ( msg) => self . diagnostic ( ) . span_err ( sp, & msg[ ] ) ,
81+ None => self . diagnostic ( ) . span_err ( sp, msg)
8782 }
88-
89- let first = Regex :: new ( r"[( ]expected" ) . unwrap ( ) ;
90- let second = Regex :: new ( r" found" ) . unwrap ( ) ;
91- let third = Regex :: new (
92- r"\((values differ|lifetime|cyclic type of infinite size)" ) . unwrap ( ) ;
93-
94- let mut new_msg = String :: new ( ) ;
95- let mut head = 0 u;
96-
97- // Insert `\n` before expected and found.
98- for ( pos1, pos2) in first. find_iter ( msg) . zip (
99- second. find_iter ( msg) ) {
100- new_msg = new_msg +
101- // A `(` may be preceded by a space and it should be trimmed
102- msg[ head..pos1. 0 ] . trim_right ( ) + // prefix
103- "\n " + // insert before first
104- & msg[ pos1. 0 ..pos1. 1 ] + // insert what first matched
105- & msg[ pos1. 1 ..pos2. 0 ] + // between matches
106- "\n " + // insert before second
107- // 123
108- // `expected` is 3 char longer than `found`. To align the types, `found` gets
109- // 3 spaces prepended.
110- & msg[ pos2. 0 ..pos2. 1 ] ; // insert what second matched
111-
112- head = pos2. 1 ;
113- }
114-
115- let mut tail = & msg[ head..] ;
116- // Insert `\n` before any remaining messages which match.
117- for pos in third. find_iter ( tail) . take ( 1 ) {
118- // The end of the message may just be wrapped in `()` without `expected`/`found`.
119- // Push this also to a new line and add the final tail after.
120- new_msg = new_msg +
121- // `(` is usually preceded by a space and should be trimmed.
122- tail[ ..pos. 0 ] . trim_right ( ) + // prefix
123- "\n " + // insert before paren
124- & tail[ pos. 0 ..] ; // append the tail
125-
126- tail = "" ;
127- }
128-
129- new_msg. push_str ( tail) ;
130- self . diagnostic ( ) . span_err ( sp, & new_msg[ ] )
13183 }
13284 pub fn span_err_with_code ( & self , sp : Span , msg : & str , code : & str ) {
133- self . diagnostic ( ) . span_err_with_code ( sp, msg, code)
85+ match split_msg_into_multilines ( msg) {
86+ Some ( msg) => self . diagnostic ( ) . span_err_with_code ( sp, & msg[ ] , code) ,
87+ None => self . diagnostic ( ) . span_err_with_code ( sp, msg, code)
88+ }
13489 }
13590 pub fn err ( & self , msg : & str ) {
13691 self . diagnostic ( ) . handler ( ) . err ( msg)
@@ -288,6 +243,62 @@ impl Session {
288243 }
289244}
290245
246+ fn split_msg_into_multilines ( msg : & str ) -> Option < String > {
247+ // Conditions for enabling multi-line errors:
248+ if !msg. contains ( "mismatched types" ) &&
249+ !msg. contains ( "type mismatch resolving" ) &&
250+ !msg. contains ( "if and else have incompatible types" ) &&
251+ !msg. contains ( "if may be missing an else clause" ) &&
252+ !msg. contains ( "match arms have incompatible types" ) &&
253+ !msg. contains ( "structure constructor specifies a structure of type" ) {
254+ return None
255+ }
256+
257+ let first = Regex :: new ( r"[( ]expected" ) . unwrap ( ) ;
258+ let second = Regex :: new ( r" found" ) . unwrap ( ) ;
259+ let third = Regex :: new (
260+ r"\((values differ|lifetime|cyclic type of infinite size)" ) . unwrap ( ) ;
261+
262+ let mut new_msg = String :: new ( ) ;
263+ let mut head = 0 u;
264+
265+ // Insert `\n` before expected and found.
266+ for ( pos1, pos2) in first. find_iter ( msg) . zip (
267+ second. find_iter ( msg) ) {
268+ new_msg = new_msg +
269+ // A `(` may be preceded by a space and it should be trimmed
270+ msg[ head..pos1. 0 ] . trim_right ( ) + // prefix
271+ "\n " + // insert before first
272+ & msg[ pos1. 0 ..pos1. 1 ] + // insert what first matched
273+ & msg[ pos1. 1 ..pos2. 0 ] + // between matches
274+ "\n " + // insert before second
275+ // 123
276+ // `expected` is 3 char longer than `found`. To align the types, `found` gets
277+ // 3 spaces prepended.
278+ & msg[ pos2. 0 ..pos2. 1 ] ; // insert what second matched
279+
280+ head = pos2. 1 ;
281+ }
282+
283+ let mut tail = & msg[ head..] ;
284+ // Insert `\n` before any remaining messages which match.
285+ for pos in third. find_iter ( tail) . take ( 1 ) {
286+ // The end of the message may just be wrapped in `()` without `expected`/`found`.
287+ // Push this also to a new line and add the final tail after.
288+ new_msg = new_msg +
289+ // `(` is usually preceded by a space and should be trimmed.
290+ tail[ ..pos. 0 ] . trim_right ( ) + // prefix
291+ "\n " + // insert before paren
292+ & tail[ pos. 0 ..] ; // append the tail
293+
294+ tail = "" ;
295+ }
296+
297+ new_msg. push_str ( tail) ;
298+
299+ return Some ( new_msg)
300+ }
301+
291302pub fn build_session ( sopts : config:: Options ,
292303 local_crate_source_file : Option < Path > ,
293304 registry : diagnostics:: registry:: Registry )
0 commit comments