Skip to content

Commit 6316ac8

Browse files
committed
Auto merge of #118595 - Zalathar:visible-macro, r=TaKO8Ki
coverage: Be more strict about what counts as a "visible macro" This is a follow-up to the workaround in #117827, and I believe it now properly fixes #117788. The old code treats a span as having a “visible macro” if it is part of a macro-expansion, and its parent callsite's context is the same as the body span's context. But if the body span is itself part of an expansion, the macro in question might not actually be visible from the body span. That results in the macro name's length being meaningless as a span offset. We now only consider spans whose parent callsite is the same as the source callsite, i.e. the parent has no parent. --- I've also included some related cleanup for the code added by #117827. That code was more complicated than normal, because I wanted it to be easy to backport to stable/beta.
2 parents dd6126e + 242bff3 commit 6316ac8

File tree

1 file changed

+20
-18
lines changed
  • compiler/rustc_mir_transform/src/coverage

1 file changed

+20
-18
lines changed

compiler/rustc_mir_transform/src/coverage/spans.rs

+20-18
Original file line numberDiff line numberDiff line change
@@ -129,16 +129,14 @@ impl CoverageSpan {
129129
/// If the span is part of a macro, and the macro is visible (expands directly to the given
130130
/// body_span), returns the macro name symbol.
131131
pub fn visible_macro(&self, body_span: Span) -> Option<Symbol> {
132-
if let Some(current_macro) = self.current_macro()
133-
&& self
134-
.expn_span
135-
.parent_callsite()
136-
.unwrap_or_else(|| bug!("macro must have a parent"))
137-
.eq_ctxt(body_span)
138-
{
139-
return Some(current_macro);
140-
}
141-
None
132+
let current_macro = self.current_macro()?;
133+
let parent_callsite = self.expn_span.parent_callsite()?;
134+
135+
// In addition to matching the context of the body span, the parent callsite
136+
// must also be the source callsite, i.e. the parent must have no parent.
137+
let is_visible_macro =
138+
parent_callsite.parent_callsite().is_none() && parent_callsite.eq_ctxt(body_span);
139+
is_visible_macro.then_some(current_macro)
142140
}
143141

144142
pub fn is_macro_expansion(&self) -> bool {
@@ -379,18 +377,22 @@ impl<'a> CoverageSpansGenerator<'a> {
379377
return;
380378
}
381379

382-
let merged_prefix_len = self.curr_original_span.lo() - curr.span.lo();
383-
let after_macro_bang = merged_prefix_len + BytePos(visible_macro.as_str().len() as u32 + 1);
384-
if self.curr().span.lo() + after_macro_bang > self.curr().span.hi() {
380+
// The split point is relative to `curr_original_span`,
381+
// because `curr.span` may have been merged with preceding spans.
382+
let split_point_after_macro_bang = self.curr_original_span.lo()
383+
+ BytePos(visible_macro.as_str().len() as u32)
384+
+ BytePos(1); // add 1 for the `!`
385+
debug_assert!(split_point_after_macro_bang <= curr.span.hi());
386+
if split_point_after_macro_bang > curr.span.hi() {
385387
// Something is wrong with the macro name span;
386-
// return now to avoid emitting malformed mappings.
387-
// FIXME(#117788): Track down why this happens.
388+
// return now to avoid emitting malformed mappings (e.g. #117788).
388389
return;
389390
}
391+
390392
let mut macro_name_cov = curr.clone();
391-
self.curr_mut().span = curr.span.with_lo(curr.span.lo() + after_macro_bang);
392-
macro_name_cov.span =
393-
macro_name_cov.span.with_hi(macro_name_cov.span.lo() + after_macro_bang);
393+
macro_name_cov.span = macro_name_cov.span.with_hi(split_point_after_macro_bang);
394+
self.curr_mut().span = curr.span.with_lo(split_point_after_macro_bang);
395+
394396
debug!(
395397
" and curr starts a new macro expansion, so add a new span just for \
396398
the macro `{visible_macro}!`, new span={macro_name_cov:?}",

0 commit comments

Comments
 (0)