Skip to content

Commit a3e1a8b

Browse files
Correctly handle multiple macro expansions on a same line
1 parent f7d21de commit a3e1a8b

File tree

1 file changed

+43
-14
lines changed

1 file changed

+43
-14
lines changed

src/librustdoc/html/highlight.rs

+43-14
Original file line numberDiff line numberDiff line change
@@ -265,14 +265,25 @@ fn empty_line_number(out: &mut impl Write, _: u32, extra: &'static str) {
265265
out.write_str(extra).unwrap();
266266
}
267267

268+
fn get_next_expansion<'a>(
269+
expanded_codes: Option<&'a Vec<ExpandedCode>>,
270+
line: u32,
271+
span: Span,
272+
) -> Option<&'a ExpandedCode> {
273+
if let Some(expanded_codes) = expanded_codes {
274+
expanded_codes.iter().find(|code| code.start_line == line && code.span.lo() >= span.lo())
275+
} else {
276+
None
277+
}
278+
}
279+
268280
fn get_expansion<'a, W: Write>(
269281
token_handler: &mut TokenHandler<'_, '_, W>,
270282
expanded_codes: Option<&'a Vec<ExpandedCode>>,
271283
line: u32,
284+
span: Span,
272285
) -> Option<&'a ExpandedCode> {
273-
if let Some(expanded_codes) = expanded_codes
274-
&& let Some(expanded_code) = expanded_codes.iter().find(|code| code.start_line == line)
275-
{
286+
if let Some(expanded_code) = get_next_expansion(expanded_codes, line, span) {
276287
let (closing, reopening) = if let Some(current_class) = token_handler.current_class
277288
&& let class = current_class.as_html()
278289
&& !class.is_empty()
@@ -307,10 +318,21 @@ fn start_expansion(out: &mut Vec<(Cow<'_, str>, Option<Class>)>, expanded_code:
307318
));
308319
}
309320

310-
fn end_expansion<W: Write>(token_handler: &mut TokenHandler<'_, '_, W>, level: usize) {
321+
fn end_expansion<'a, W: Write>(
322+
token_handler: &mut TokenHandler<'_, '_, W>,
323+
expanded_codes: Option<&'a Vec<ExpandedCode>>,
324+
level: usize,
325+
line: u32,
326+
span: Span,
327+
) -> Option<&'a ExpandedCode> {
328+
if let Some(expanded_code) = get_next_expansion(expanded_codes, line, span) {
329+
// We close the current "original" content.
330+
token_handler.pending_elems.push((Cow::Borrowed("</span>"), Some(Class::Expansion)));
331+
return Some(expanded_code);
332+
}
311333
if level == 0 {
312334
token_handler.pending_elems.push((Cow::Borrowed("</span></span>"), Some(Class::Expansion)));
313-
return;
335+
return None;
314336
}
315337
let mut out = String::new();
316338
let mut end = String::new();
@@ -323,6 +345,7 @@ fn end_expansion<W: Write>(token_handler: &mut TokenHandler<'_, '_, W>, level: u
323345
token_handler
324346
.pending_elems
325347
.push((Cow::Owned(format!("</span></span>{out}{end}")), Some(Class::Expansion)));
348+
None
326349
}
327350

328351
#[derive(Clone, Copy)]
@@ -392,11 +415,14 @@ pub(super) fn write_code(
392415
(0, u32::MAX)
393416
};
394417

395-
let expanded_codes = token_handler
396-
.href_context
397-
.as_ref()
398-
.and_then(|c| c.context.shared.expanded_codes.get(&c.file_span.lo()));
399-
let mut current_expansion = get_expansion(&mut token_handler, expanded_codes, line);
418+
let (expanded_codes, file_span) = match token_handler.href_context.as_ref().and_then(|c| {
419+
let expanded_codes = c.context.shared.expanded_codes.get(&c.file_span.lo())?;
420+
Some((expanded_codes, c.file_span))
421+
}) {
422+
Some((expanded_codes, file_span)) => (Some(expanded_codes), file_span),
423+
None => (None, DUMMY_SP),
424+
};
425+
let mut current_expansion = get_expansion(&mut token_handler, expanded_codes, line, file_span);
400426
token_handler.write_pending_elems(None);
401427
let mut level = 0;
402428

@@ -436,7 +462,8 @@ pub(super) fn write_code(
436462
.push((Cow::Borrowed(text), Some(Class::Backline(line))));
437463
}
438464
if current_expansion.is_none() {
439-
current_expansion = get_expansion(&mut token_handler, expanded_codes, line);
465+
current_expansion =
466+
get_expansion(&mut token_handler, expanded_codes, line, span);
440467
}
441468
} else {
442469
token_handler.pending_elems.push((Cow::Borrowed(text), class));
@@ -452,9 +479,11 @@ pub(super) fn write_code(
452479
}
453480
}
454481
if need_end {
455-
end_expansion(&mut token_handler, level);
456-
current_expansion = None;
457-
level = 0;
482+
current_expansion =
483+
end_expansion(&mut token_handler, expanded_codes, level, line, span);
484+
if current_expansion.is_none() {
485+
level = 0;
486+
}
458487
}
459488
}
460489
}

0 commit comments

Comments
 (0)