@@ -76,61 +76,16 @@ impl Session {
76
76
self . diagnostic ( ) . handler ( ) . fatal ( msg)
77
77
}
78
78
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)
87
82
}
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[ ] )
131
83
}
132
84
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
+ }
134
89
}
135
90
pub fn err ( & self , msg : & str ) {
136
91
self . diagnostic ( ) . handler ( ) . err ( msg)
@@ -288,6 +243,62 @@ impl Session {
288
243
}
289
244
}
290
245
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
+
291
302
pub fn build_session ( sopts : config:: Options ,
292
303
local_crate_source_file : Option < Path > ,
293
304
registry : diagnostics:: registry:: Registry )
0 commit comments