@@ -162,6 +162,17 @@ struct TokenHandler<'a, 'tcx, F: Write> {
162
162
write_line_number : fn ( & mut F , u32 , & ' static str ) ,
163
163
}
164
164
165
+ impl < F : Write > std:: fmt:: Debug for TokenHandler < ' _ , ' _ , F > {
166
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
167
+ f. debug_struct ( "TokenHandler" )
168
+ . field ( "closing_tags" , & self . closing_tags )
169
+ . field ( "pending_exit_span" , & self . pending_exit_span )
170
+ . field ( "current_class" , & self . current_class )
171
+ . field ( "pending_elems" , & self . pending_elems )
172
+ . finish ( )
173
+ }
174
+ }
175
+
165
176
impl < F : Write > TokenHandler < ' _ , ' _ , F > {
166
177
fn handle_exit_span ( & mut self ) {
167
178
// We can't get the last `closing_tags` element using `pop()` because `closing_tags` is
@@ -271,7 +282,7 @@ fn get_next_expansion<'a>(
271
282
span : Span ,
272
283
) -> Option < & ' a ExpandedCode > {
273
284
if let Some ( expanded_codes) = expanded_codes {
274
- expanded_codes. iter ( ) . find ( |code| code. start_line == line && code. span . lo ( ) >= span. lo ( ) )
285
+ expanded_codes. iter ( ) . find ( |code| code. start_line == line && code. span . lo ( ) > span. lo ( ) )
275
286
} else {
276
287
None
277
288
}
@@ -321,7 +332,7 @@ fn start_expansion(out: &mut Vec<(Cow<'_, str>, Option<Class>)>, expanded_code:
321
332
fn end_expansion < ' a , W : Write > (
322
333
token_handler : & mut TokenHandler < ' _ , ' _ , W > ,
323
334
expanded_codes : Option < & ' a Vec < ExpandedCode > > ,
324
- level : usize ,
335
+ expansion_start_tags : & [ ( & ' static str , Class ) ] ,
325
336
line : u32 ,
326
337
span : Span ,
327
338
) -> Option < & ' a ExpandedCode > {
@@ -330,15 +341,27 @@ fn end_expansion<'a, W: Write>(
330
341
token_handler. pending_elems . push ( ( Cow :: Borrowed ( "</span>" ) , Some ( Class :: Expansion ) ) ) ;
331
342
return Some ( expanded_code) ;
332
343
}
333
- if level == 0 {
344
+ if expansion_start_tags. is_empty ( ) && token_handler. closing_tags . is_empty ( ) {
345
+ // No need tag opened so we can just close expansion.
334
346
token_handler. pending_elems . push ( ( Cow :: Borrowed ( "</span></span>" ) , Some ( Class :: Expansion ) ) ) ;
335
347
return None ;
336
348
}
349
+
350
+ // If tags were opened inside the expansion, we need to close them and re-open them outside
351
+ // of the expansion span.
337
352
let mut out = String :: new ( ) ;
338
353
let mut end = String :: new ( ) ;
339
- for ( tag, class) in
340
- token_handler. closing_tags . iter ( ) . skip ( token_handler. closing_tags . len ( ) - level)
354
+
355
+ let mut closing_tags = token_handler. closing_tags . iter ( ) . peekable ( ) ;
356
+ let mut start_closing_tags = expansion_start_tags. iter ( ) . peekable ( ) ;
357
+
358
+ while let ( Some ( tag) , Some ( start_tag) ) = ( closing_tags. peek ( ) , start_closing_tags. peek ( ) )
359
+ && tag == start_tag
341
360
{
361
+ closing_tags. next ( ) ;
362
+ start_closing_tags. next ( ) ;
363
+ }
364
+ for ( tag, class) in start_closing_tags. chain ( closing_tags) {
342
365
out. push_str ( tag) ;
343
366
end. push_str ( & format ! ( "<span class=\" {}\" >" , class. as_html( ) ) ) ;
344
367
}
@@ -424,7 +447,7 @@ pub(super) fn write_code(
424
447
} ;
425
448
let mut current_expansion = get_expansion ( & mut token_handler, expanded_codes, line, file_span) ;
426
449
token_handler. write_pending_elems ( None ) ;
427
- let mut level = 0 ;
450
+ let mut expansion_start_tags = Vec :: new ( ) ;
428
451
429
452
Classifier :: new (
430
453
& src,
@@ -464,6 +487,12 @@ pub(super) fn write_code(
464
487
if current_expansion. is_none ( ) {
465
488
current_expansion =
466
489
get_expansion ( & mut token_handler, expanded_codes, line, span) ;
490
+ expansion_start_tags = token_handler. closing_tags . clone ( ) ;
491
+ }
492
+ if let Some ( ref current_expansion) = current_expansion
493
+ && current_expansion. span . lo ( ) == span. hi ( )
494
+ {
495
+ start_expansion ( & mut token_handler. pending_elems , current_expansion) ;
467
496
}
468
497
} else {
469
498
token_handler. pending_elems . push ( ( Cow :: Borrowed ( text) , class) ) ;
@@ -479,11 +508,13 @@ pub(super) fn write_code(
479
508
}
480
509
}
481
510
if need_end {
482
- current_expansion =
483
- end_expansion ( & mut token_handler, expanded_codes, level, line, span) ;
484
- if current_expansion. is_none ( ) {
485
- level = 0 ;
486
- }
511
+ current_expansion = end_expansion (
512
+ & mut token_handler,
513
+ expanded_codes,
514
+ & expansion_start_tags,
515
+ line,
516
+ span,
517
+ ) ;
487
518
}
488
519
}
489
520
}
@@ -504,9 +535,6 @@ pub(super) fn write_code(
504
535
if should_add {
505
536
let closing_tag =
506
537
enter_span ( token_handler. out , class, & token_handler. href_context ) ;
507
- if current_expansion. is_some ( ) {
508
- level += 1 ;
509
- }
510
538
token_handler. closing_tags . push ( ( closing_tag, class) ) ;
511
539
}
512
540
@@ -515,9 +543,6 @@ pub(super) fn write_code(
515
543
}
516
544
Highlight :: ExitSpan => {
517
545
token_handler. current_class = None ;
518
- if current_expansion. is_some ( ) {
519
- level -= 1 ;
520
- }
521
546
token_handler. pending_exit_span = Some (
522
547
token_handler
523
548
. closing_tags
0 commit comments