mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-30 13:06:28 +03:00
Rollup merge of #156970 - qaijuang:async_closure_coverage, r=Zalathar
coverage: Use original HIR info for synthetic by-move coroutine bodies > This is a copy of #156952(because my git was acting weird) Synthetic by-move coroutine bodies created for async closures don't have useful HIR of their own. Coverage was falling back to the parent async closure for HIR info, which means the executed `AsyncFnOnce` body could inherit hole spans from the wrong body and report the user-written closure body as uncovered. This PR uses the synthetic body's coroutine type to recover the original coroutine body def-id, then extracts HIR info from that body instead. That keeps the coverage spans tied to the body the synthetic MIR was cloned from. Fixes rust-lang/rust#151135. r? Zalathar
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::intravisit::{Visitor, walk_expr};
|
||||
use rustc_middle::hir::nested_filter;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_middle::ty::{self, TyCtxt};
|
||||
use rustc_span::Span;
|
||||
use rustc_span::def_id::LocalDefId;
|
||||
|
||||
@@ -24,9 +24,16 @@ pub(crate) fn extract_hir_info<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> E
|
||||
// FIXME(#79625): Consider improving MIR to provide the information needed, to avoid going back
|
||||
// to HIR for it.
|
||||
|
||||
// HACK: For synthetic MIR bodies (async closures), use the def id of the HIR body.
|
||||
// Synthetic by-move coroutine bodies don't have useful HIR of their own.
|
||||
// Use the original coroutine body instead. These synthetic bodies are
|
||||
// created with a coroutine type, so we can inspect that type as-is.
|
||||
if tcx.is_synthetic_mir(def_id) {
|
||||
return extract_hir_info(tcx, tcx.local_parent(def_id));
|
||||
let effective_def_id =
|
||||
match *tcx.type_of(def_id).instantiate_identity().skip_normalization().kind() {
|
||||
ty::Coroutine(coroutine_def_id, _) => coroutine_def_id.expect_local(),
|
||||
_ => tcx.local_parent(def_id),
|
||||
};
|
||||
return extract_hir_info(tcx, effective_def_id);
|
||||
}
|
||||
|
||||
let hir_node = tcx.hir_node_by_def_id(def_id);
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
Function name: async_closure2::call_once::<async_closure2::main::{closure#0}>
|
||||
Raw bytes (9): 0x[01, 01, 00, 01, 01, 0c, 01, 00, 2a]
|
||||
Number of files: 1
|
||||
- file 0 => $DIR/async_closure2.rs
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 1
|
||||
- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 42)
|
||||
Highest counter ID seen: c0
|
||||
|
||||
Function name: async_closure2::call_once::<async_closure2::main::{closure#0}>::{closure#0}
|
||||
Raw bytes (21): 0x[01, 01, 01, 05, 09, 03, 01, 0c, 2b, 00, 2c, 01, 01, 05, 00, 0e, 02, 01, 01, 00, 02]
|
||||
Number of files: 1
|
||||
- file 0 => $DIR/async_closure2.rs
|
||||
Number of expressions: 1
|
||||
- expression 0 operands: lhs = Counter(1), rhs = Counter(2)
|
||||
Number of file 0 mappings: 3
|
||||
- Code(Counter(0)) at (prev + 12, 43) to (start + 0, 44)
|
||||
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 14)
|
||||
- Code(Expression(0, Sub)) at (prev + 1, 1) to (start + 0, 2)
|
||||
= (c1 - c2)
|
||||
Highest counter ID seen: c0
|
||||
|
||||
Function name: async_closure2::main
|
||||
Raw bytes (54): 0x[01, 01, 00, 0a, 01, 10, 01, 00, 0e, 01, 01, 09, 00, 16, 01, 04, 05, 00, 17, 01, 00, 18, 00, 21, 01, 00, 22, 00, 2f, 01, 01, 05, 00, 0f, 01, 00, 10, 00, 15, 01, 00, 16, 00, 1a, 01, 00, 1b, 00, 2b, 05, 01, 01, 00, 02]
|
||||
Number of files: 1
|
||||
- file 0 => $DIR/async_closure2.rs
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 10
|
||||
- Code(Counter(0)) at (prev + 16, 1) to (start + 0, 14)
|
||||
- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 22)
|
||||
- Code(Counter(0)) at (prev + 4, 5) to (start + 0, 23)
|
||||
- Code(Counter(0)) at (prev + 0, 24) to (start + 0, 33)
|
||||
- Code(Counter(0)) at (prev + 0, 34) to (start + 0, 47)
|
||||
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 15)
|
||||
- Code(Counter(0)) at (prev + 0, 16) to (start + 0, 21)
|
||||
- Code(Counter(0)) at (prev + 0, 22) to (start + 0, 26)
|
||||
- Code(Counter(0)) at (prev + 0, 27) to (start + 0, 43)
|
||||
- Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2)
|
||||
Highest counter ID seen: c1
|
||||
|
||||
Function name: async_closure2::main::{closure#0}
|
||||
Raw bytes (44): 0x[01, 01, 00, 08, 01, 11, 22, 00, 23, 01, 01, 09, 00, 0e, 01, 00, 0f, 00, 18, 01, 00, 1c, 00, 2c, 01, 01, 09, 00, 0e, 01, 00, 0f, 00, 18, 01, 00, 1c, 00, 2c, 01, 01, 05, 00, 06]
|
||||
Number of files: 1
|
||||
- file 0 => $DIR/async_closure2.rs
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 8
|
||||
- Code(Counter(0)) at (prev + 17, 34) to (start + 0, 35)
|
||||
- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14)
|
||||
- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 24)
|
||||
- Code(Counter(0)) at (prev + 0, 28) to (start + 0, 44)
|
||||
- Code(Counter(0)) at (prev + 1, 9) to (start + 0, 14)
|
||||
- Code(Counter(0)) at (prev + 0, 15) to (start + 0, 24)
|
||||
- Code(Counter(0)) at (prev + 0, 28) to (start + 0, 44)
|
||||
- Code(Counter(0)) at (prev + 1, 5) to (start + 0, 6)
|
||||
Highest counter ID seen: c0
|
||||
|
||||
Function name: async_closure2::main::{closure#0}::{closure#0}::<_> (unused)
|
||||
Raw bytes (44): 0x[01, 01, 00, 08, 00, 11, 22, 00, 23, 00, 01, 09, 00, 0e, 00, 00, 0f, 00, 18, 00, 00, 1c, 00, 2c, 00, 01, 09, 00, 0e, 00, 00, 0f, 00, 18, 00, 00, 1c, 00, 2c, 00, 01, 05, 00, 06]
|
||||
Number of files: 1
|
||||
- file 0 => $DIR/async_closure2.rs
|
||||
Number of expressions: 0
|
||||
Number of file 0 mappings: 8
|
||||
- Code(Zero) at (prev + 17, 34) to (start + 0, 35)
|
||||
- Code(Zero) at (prev + 1, 9) to (start + 0, 14)
|
||||
- Code(Zero) at (prev + 0, 15) to (start + 0, 24)
|
||||
- Code(Zero) at (prev + 0, 28) to (start + 0, 44)
|
||||
- Code(Zero) at (prev + 1, 9) to (start + 0, 14)
|
||||
- Code(Zero) at (prev + 0, 15) to (start + 0, 24)
|
||||
- Code(Zero) at (prev + 0, 28) to (start + 0, 44)
|
||||
- Code(Zero) at (prev + 1, 5) to (start + 0, 6)
|
||||
Highest counter ID seen: (none)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
LL| |// Regression test for <https://github.com/rust-lang/rust/issues/151135>.
|
||||
LL| |
|
||||
LL| |//@ edition: 2021
|
||||
LL| |
|
||||
LL| |//@ aux-build: executor.rs
|
||||
LL| |extern crate executor;
|
||||
LL| |
|
||||
LL| |use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
LL| |
|
||||
LL| |static STEPS: AtomicUsize = AtomicUsize::new(0);
|
||||
LL| |
|
||||
LL| 1|async fn call_once(f: impl AsyncFnOnce()) {
|
||||
LL| 1| f().await;
|
||||
LL| 1|}
|
||||
LL| |
|
||||
LL| 1|pub fn main() {
|
||||
LL| 1| let async_closure = async || {
|
||||
LL| 1| STEPS.fetch_add(1, Ordering::SeqCst);
|
||||
LL| 1| STEPS.fetch_add(1, Ordering::SeqCst);
|
||||
LL| 1| };
|
||||
------------------
|
||||
| Unexecuted instantiation: async_closure2::main::{closure#0}::{closure#0}::<_>
|
||||
------------------
|
||||
| async_closure2::main::{closure#0}:
|
||||
| LL| 1| let async_closure = async || {
|
||||
| LL| 1| STEPS.fetch_add(1, Ordering::SeqCst);
|
||||
| LL| 1| STEPS.fetch_add(1, Ordering::SeqCst);
|
||||
| LL| 1| };
|
||||
------------------
|
||||
LL| 1| executor::block_on(call_once(async_closure));
|
||||
LL| 1| assert_eq!(STEPS.load(Ordering::SeqCst), 2);
|
||||
LL| 1|}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// Regression test for <https://github.com/rust-lang/rust/issues/151135>.
|
||||
|
||||
//@ edition: 2021
|
||||
|
||||
//@ aux-build: executor.rs
|
||||
extern crate executor;
|
||||
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
static STEPS: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
async fn call_once(f: impl AsyncFnOnce()) {
|
||||
f().await;
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
let async_closure = async || {
|
||||
STEPS.fetch_add(1, Ordering::SeqCst);
|
||||
STEPS.fetch_add(1, Ordering::SeqCst);
|
||||
};
|
||||
executor::block_on(call_once(async_closure));
|
||||
assert_eq!(STEPS.load(Ordering::SeqCst), 2);
|
||||
}
|
||||
Reference in New Issue
Block a user