Skip to content

Commit eddc6a3

Browse files
committed
coverage: Simplify the heuristic for ignoring async fn return spans
1 parent d6fa38a commit eddc6a3

File tree

2 files changed

+14
-17
lines changed

2 files changed

+14
-17
lines changed

compiler/rustc_mir_transform/src/coverage/spans.rs

+4-17
Original file line numberDiff line numberDiff line change
@@ -319,30 +319,17 @@ impl<'a> CoverageSpansGenerator<'a> {
319319
}
320320
}
321321

322-
let prev = self.take_prev();
323-
debug!(" AT END, adding last prev={prev:?}");
324-
325322
// Take `pending_dups` so that we can drain it while calling self methods.
326323
// It is never used as a field after this point.
327324
for dup in std::mem::take(&mut self.pending_dups) {
328325
debug!(" ...adding at least one pending dup={:?}", dup);
329326
self.push_refined_span(dup);
330327
}
331328

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

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

+10
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)