@@ -162,6 +162,17 @@ struct TokenHandler<'a, 'tcx, F: Write> {
162162 write_line_number : fn ( & mut F , u32 , & ' static str ) ,
163163}
164164
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+
165176impl < F : Write > TokenHandler < ' _ , ' _ , F > {
166177 fn handle_exit_span ( & mut self ) {
167178 // We can't get the last `closing_tags` element using `pop()` because `closing_tags` is
@@ -271,7 +282,7 @@ fn get_next_expansion<'a>(
271282 span : Span ,
272283) -> Option < & ' a ExpandedCode > {
273284 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 ( ) )
275286 } else {
276287 None
277288 }
@@ -321,7 +332,7 @@ fn start_expansion(out: &mut Vec<(Cow<'_, str>, Option<Class>)>, expanded_code:
321332fn end_expansion < ' a , W : Write > (
322333 token_handler : & mut TokenHandler < ' _ , ' _ , W > ,
323334 expanded_codes : Option < & ' a Vec < ExpandedCode > > ,
324- level : usize ,
335+ expansion_start_tags : & [ ( & ' static str , Class ) ] ,
325336 line : u32 ,
326337 span : Span ,
327338) -> Option < & ' a ExpandedCode > {
@@ -330,15 +341,27 @@ fn end_expansion<'a, W: Write>(
330341 token_handler. pending_elems . push ( ( Cow :: Borrowed ( "</span>" ) , Some ( Class :: Expansion ) ) ) ;
331342 return Some ( expanded_code) ;
332343 }
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.
334346 token_handler. pending_elems . push ( ( Cow :: Borrowed ( "</span></span>" ) , Some ( Class :: Expansion ) ) ) ;
335347 return None ;
336348 }
349+
350+ // If tags were opened inside the expansion, we need to close them and re-open them outside
351+ // of the expansion span.
337352 let mut out = String :: new ( ) ;
338353 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
341360 {
361+ closing_tags. next ( ) ;
362+ start_closing_tags. next ( ) ;
363+ }
364+ for ( tag, class) in start_closing_tags. chain ( closing_tags) {
342365 out. push_str ( tag) ;
343366 end. push_str ( & format ! ( "<span class=\" {}\" >" , class. as_html( ) ) ) ;
344367 }
@@ -424,7 +447,7 @@ pub(super) fn write_code(
424447 } ;
425448 let mut current_expansion = get_expansion ( & mut token_handler, expanded_codes, line, file_span) ;
426449 token_handler. write_pending_elems ( None ) ;
427- let mut level = 0 ;
450+ let mut expansion_start_tags = Vec :: new ( ) ;
428451
429452 Classifier :: new (
430453 & src,
@@ -464,6 +487,12 @@ pub(super) fn write_code(
464487 if current_expansion. is_none ( ) {
465488 current_expansion =
466489 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) ;
467496 }
468497 } else {
469498 token_handler. pending_elems . push ( ( Cow :: Borrowed ( text) , class) ) ;
@@ -479,11 +508,13 @@ pub(super) fn write_code(
479508 }
480509 }
481510 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+ ) ;
487518 }
488519 }
489520 }
@@ -504,9 +535,6 @@ pub(super) fn write_code(
504535 if should_add {
505536 let closing_tag =
506537 enter_span ( token_handler. out , class, & token_handler. href_context ) ;
507- if current_expansion. is_some ( ) {
508- level += 1 ;
509- }
510538 token_handler. closing_tags . push ( ( closing_tag, class) ) ;
511539 }
512540
@@ -515,9 +543,6 @@ pub(super) fn write_code(
515543 }
516544 Highlight :: ExitSpan => {
517545 token_handler. current_class = None ;
518- if current_expansion. is_some ( ) {
519- level -= 1 ;
520- }
521546 token_handler. pending_exit_span = Some (
522547 token_handler
523548 . closing_tags
0 commit comments