@@ -243,6 +243,7 @@ impl EmitterWriter {
243
243
end_col : hi. col_display ,
244
244
is_primary : span_label. is_primary ,
245
245
label : span_label. label . clone ( ) ,
246
+ overlaps_exactly : false ,
246
247
} ;
247
248
multiline_annotations. push ( ( lo. file . clone ( ) , ml. clone ( ) ) ) ;
248
249
AnnotationType :: Multiline ( ml)
@@ -258,10 +259,7 @@ impl EmitterWriter {
258
259
} ;
259
260
260
261
if !ann. is_multiline ( ) {
261
- add_annotation_to_file ( & mut output,
262
- lo. file ,
263
- lo. line ,
264
- ann) ;
262
+ add_annotation_to_file ( & mut output, lo. file , lo. line , ann) ;
265
263
}
266
264
}
267
265
}
@@ -274,10 +272,12 @@ impl EmitterWriter {
274
272
let ref mut a = item. 1 ;
275
273
// Move all other multiline annotations overlapping with this one
276
274
// one level to the right.
277
- if & ann != a &&
275
+ if ! ( ann . same_span ( a ) ) &&
278
276
num_overlap ( ann. line_start , ann. line_end , a. line_start , a. line_end , true )
279
277
{
280
278
a. increase_depth ( ) ;
279
+ } else if ann. same_span ( a) && & ann != a {
280
+ a. overlaps_exactly = true ;
281
281
} else {
282
282
break ;
283
283
}
@@ -289,17 +289,49 @@ impl EmitterWriter {
289
289
if ann. depth > max_depth {
290
290
max_depth = ann. depth ;
291
291
}
292
- add_annotation_to_file ( & mut output, file. clone ( ) , ann. line_start , ann. as_start ( ) ) ;
293
- let middle = min ( ann. line_start + 4 , ann. line_end ) ;
294
- for line in ann. line_start + 1 ..middle {
295
- add_annotation_to_file ( & mut output, file. clone ( ) , line, ann. as_line ( ) ) ;
296
- }
297
- if middle < ann. line_end - 1 {
298
- for line in ann. line_end - 1 ..ann. line_end {
292
+ let mut end_ann = ann. as_end ( ) ;
293
+ if !ann. overlaps_exactly {
294
+ // avoid output like
295
+ //
296
+ // | foo(
297
+ // | _____^
298
+ // | |_____|
299
+ // | || bar,
300
+ // | || );
301
+ // | || ^
302
+ // | ||______|
303
+ // | |______foo
304
+ // | baz
305
+ //
306
+ // and instead get
307
+ //
308
+ // | foo(
309
+ // | _____^
310
+ // | | bar,
311
+ // | | );
312
+ // | | ^
313
+ // | | |
314
+ // | |______foo
315
+ // | baz
316
+ add_annotation_to_file ( & mut output, file. clone ( ) , ann. line_start , ann. as_start ( ) ) ;
317
+ // 4 is the minimum vertical length of a multiline span when presented: two lines
318
+ // of code and two lines of underline. This is not true for the special case where
319
+ // the beginning doesn't have an underline, but the current logic seems to be
320
+ // working correctly.
321
+ let middle = min ( ann. line_start + 4 , ann. line_end ) ;
322
+ for line in ann. line_start + 1 ..middle {
323
+ // Every `|` that joins the beginning of the span (`___^`) to the end (`|__^`).
299
324
add_annotation_to_file ( & mut output, file. clone ( ) , line, ann. as_line ( ) ) ;
300
325
}
326
+ if middle < ann. line_end - 1 {
327
+ for line in ann. line_end - 1 ..ann. line_end {
328
+ add_annotation_to_file ( & mut output, file. clone ( ) , line, ann. as_line ( ) ) ;
329
+ }
330
+ }
331
+ } else {
332
+ end_ann. annotation_type = AnnotationType :: Singleline ;
301
333
}
302
- add_annotation_to_file ( & mut output, file, ann. line_end , ann . as_end ( ) ) ;
334
+ add_annotation_to_file ( & mut output, file, ann. line_end , end_ann ) ;
303
335
}
304
336
for file_vec in output. iter_mut ( ) {
305
337
file_vec. multiline_depth = max_depth;
0 commit comments