Skip to content

Commit e0cd805

Browse files
committed
coverage: Simplify the heuristic for ignoring async fn return spans
1 parent 5ea6256 commit e0cd805

File tree

2 files changed

+14
-17
lines changed

2 files changed

+14
-17
lines changed

compiler/rustc_mir_transform/src/coverage/spans.rs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -319,29 +319,16 @@ impl<'a> CoverageSpansGenerator<'a> {
319319
}
320320
}
321321

322-
let prev = self.take_prev();
323-
debug!(" AT END, adding last prev={prev:?}");
324-
325322
// Drain any remaining dups into the output.
326323
for dup in self.pending_dups.drain(..) {
327324
debug!(" ...adding at least one pending dup={:?}", dup);
328325
self.refined_spans.push(dup);
329326
}
330327

331-
// Async functions wrap a closure that implements the body to be executed. The enclosing
332-
// function is called and returns an `impl Future` without initially executing any of the
333-
// body. To avoid showing the return from the enclosing function as a "covered" return from
334-
// the closure, the enclosing function's `TerminatorKind::Return`s `CoverageSpan` is
335-
// excluded. The closure's `Return` is the only one that will be counted. This provides
336-
// adequate coverage, and more intuitive counts. (Avoids double-counting the closing brace
337-
// of the function body.)
338-
let body_ends_with_closure = if let Some(last_covspan) = self.refined_spans.last() {
339-
last_covspan.is_closure && last_covspan.span.hi() == self.body_span.hi()
340-
} else {
341-
false
342-
};
343-
344-
if !body_ends_with_closure {
328+
// There is usually a final span remaining in `prev` after the loop ends,
329+
// so add it to the output as well.
330+
if let Some(prev) = self.some_prev.take() {
331+
debug!(" AT END, adding last prev={prev:?}");
345332
self.refined_spans.push(prev);
346333
}
347334

compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@ pub(super) fn mir_to_initial_sorted_coverage_spans(
4444
.then_with(|| Ord::cmp(&a.is_closure, &b.is_closure).reverse())
4545
});
4646

47+
// The desugaring of an async function includes a closure containing the
48+
// original function body, and a terminator that returns the `impl Future`.
49+
// That terminator will cause a confusing coverage count for the function's
50+
// closing brace, so discard everything after the body closure span.
51+
if let Some(body_closure_index) =
52+
initial_spans.iter().rposition(|covspan| covspan.is_closure && covspan.span == body_span)
53+
{
54+
initial_spans.truncate(body_closure_index + 1);
55+
}
56+
4757
initial_spans
4858
}
4959

0 commit comments

Comments
 (0)