Completes support for coverage in external crates
The prior PR corrected for errors encountered when trying to generate the coverage map on source code inlined from external crates (including macros and generics) by avoiding adding external DefIds to the coverage map. This made it possible to generate a coverage report including external crates, but the external crate coverage was incomplete (did not include coverage for the DefIds that were eliminated. The root issue was that the coverage map was converting Span locations to source file and locations, using the SourceMap for the current crate, and this would not work for spans from external crates (compliled with a different SourceMap). The solution was to convert the Spans to filename and location during MIR generation instead, so precompiled external crates would already have the correct source code locations embedded in their MIR, when imported into another crate.
This commit is contained in:
parent
5ef872f961
commit
e0dc8dec27
15 changed files with 415 additions and 372 deletions
|
|
@ -2,58 +2,76 @@
|
|||
+ // MIR for `bar` after InstrumentCoverage
|
||||
|
||||
fn bar() -> bool {
|
||||
let mut _0: bool; // return place in scope 0 at $DIR/instrument_coverage.rs:18:13: 18:17
|
||||
+ let mut _1: (); // in scope 0 at $DIR/instrument_coverage.rs:18:18: 18:18
|
||||
let mut _0: bool; // return place in scope 0 at /the/src/instrument_coverage.rs:19:13: 19:17
|
||||
+ let mut _1: (); // in scope 0 at /the/src/instrument_coverage.rs:19:18: 19:18
|
||||
|
||||
bb0: {
|
||||
+ StorageLive(_1); // scope 0 at $DIR/instrument_coverage.rs:18:18: 18:18
|
||||
+ _1 = const std::intrinsics::count_code_region(const 10208505205182607101_u64, const 0_u32, const 529_u32, const 541_u32) -> bb2; // scope 0 at $DIR/instrument_coverage.rs:18:18: 18:18
|
||||
+ StorageLive(_1); // scope 0 at /the/src/instrument_coverage.rs:19:18: 19:18
|
||||
+ _1 = const std::intrinsics::count_code_region(const 10208505205182607101_u64, const 0_u32, const "/the/src/instrument_coverage.rs", const 19_u32, const 18_u32, const 21_u32, const 2_u32) -> bb2; // scope 0 at /the/src/instrument_coverage.rs:19:18: 19:18
|
||||
+ // ty::Const
|
||||
+ // + ty: unsafe extern "rust-intrinsic" fn(u64, u32, u32, u32) {std::intrinsics::count_code_region}
|
||||
+ // + ty: unsafe extern "rust-intrinsic" fn(u64, u32, &'static str, u32, u32, u32, u32) {std::intrinsics::count_code_region}
|
||||
+ // + val: Value(Scalar(<ZST>))
|
||||
+ // mir::Constant
|
||||
+ // + span: $DIR/instrument_coverage.rs:18:18: 18:18
|
||||
+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u64, u32, u32, u32) {std::intrinsics::count_code_region}, val: Value(Scalar(<ZST>)) }
|
||||
+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
|
||||
+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u64, u32, &'static str, u32, u32, u32, u32) {std::intrinsics::count_code_region}, val: Value(Scalar(<ZST>)) }
|
||||
+ // ty::Const
|
||||
+ // + ty: u64
|
||||
+ // + val: Value(Scalar(0x8dabe565aaa2aefd))
|
||||
+ // mir::Constant
|
||||
+ // + span: $DIR/instrument_coverage.rs:18:18: 18:18
|
||||
+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
|
||||
+ // + literal: Const { ty: u64, val: Value(Scalar(0x8dabe565aaa2aefd)) }
|
||||
+ // ty::Const
|
||||
+ // + ty: u32
|
||||
+ // + val: Value(Scalar(0x00000000))
|
||||
+ // mir::Constant
|
||||
+ // + span: $DIR/instrument_coverage.rs:18:18: 18:18
|
||||
+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
|
||||
+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
|
||||
+ // ty::Const
|
||||
+ // + ty: u32
|
||||
+ // + val: Value(Scalar(0x00000211))
|
||||
+ // + ty: &str
|
||||
+ // + val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 })
|
||||
+ // mir::Constant
|
||||
+ // + span: $DIR/instrument_coverage.rs:18:18: 18:18
|
||||
+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000211)) }
|
||||
+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
|
||||
+ // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 }) }
|
||||
+ // ty::Const
|
||||
+ // + ty: u32
|
||||
+ // + val: Value(Scalar(0x0000021d))
|
||||
+ // + val: Value(Scalar(0x00000013))
|
||||
+ // mir::Constant
|
||||
+ // + span: $DIR/instrument_coverage.rs:18:18: 18:18
|
||||
+ // + literal: Const { ty: u32, val: Value(Scalar(0x0000021d)) }
|
||||
+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
|
||||
+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000013)) }
|
||||
+ // ty::Const
|
||||
+ // + ty: u32
|
||||
+ // + val: Value(Scalar(0x00000012))
|
||||
+ // mir::Constant
|
||||
+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
|
||||
+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000012)) }
|
||||
+ // ty::Const
|
||||
+ // + ty: u32
|
||||
+ // + val: Value(Scalar(0x00000015))
|
||||
+ // mir::Constant
|
||||
+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
|
||||
+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000015)) }
|
||||
+ // ty::Const
|
||||
+ // + ty: u32
|
||||
+ // + val: Value(Scalar(0x00000002))
|
||||
+ // mir::Constant
|
||||
+ // + span: /the/src/instrument_coverage.rs:19:18: 19:18
|
||||
+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
|
||||
+ }
|
||||
+
|
||||
+ bb1 (cleanup): {
|
||||
+ resume; // scope 0 at $DIR/instrument_coverage.rs:18:1: 20:2
|
||||
+ resume; // scope 0 at /the/src/instrument_coverage.rs:19:1: 21:2
|
||||
+ }
|
||||
+
|
||||
+ bb2: {
|
||||
+ StorageDead(_1); // scope 0 at $DIR/instrument_coverage.rs:19:5: 19:9
|
||||
_0 = const true; // scope 0 at $DIR/instrument_coverage.rs:19:5: 19:9
|
||||
+ StorageDead(_1); // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9
|
||||
_0 = const true; // scope 0 at /the/src/instrument_coverage.rs:20:5: 20:9
|
||||
// ty::Const
|
||||
// + ty: bool
|
||||
// + val: Value(Scalar(0x01))
|
||||
// mir::Constant
|
||||
// + span: $DIR/instrument_coverage.rs:19:5: 19:9
|
||||
// + span: /the/src/instrument_coverage.rs:20:5: 20:9
|
||||
// + literal: Const { ty: bool, val: Value(Scalar(0x01)) }
|
||||
return; // scope 0 at $DIR/instrument_coverage.rs:20:2: 20:2
|
||||
return; // scope 0 at /the/src/instrument_coverage.rs:21:2: 21:2
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,99 +2,117 @@
|
|||
+ // MIR for `main` after InstrumentCoverage
|
||||
|
||||
fn main() -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/instrument_coverage.rs:9:11: 9:11
|
||||
let mut _1: (); // in scope 0 at $DIR/instrument_coverage.rs:9:1: 15:2
|
||||
let mut _2: bool; // in scope 0 at $DIR/instrument_coverage.rs:11:12: 11:17
|
||||
let mut _3: !; // in scope 0 at $DIR/instrument_coverage.rs:11:18: 13:10
|
||||
+ let mut _4: (); // in scope 0 at $DIR/instrument_coverage.rs:9:11: 9:11
|
||||
let mut _0: (); // return place in scope 0 at /the/src/instrument_coverage.rs:10:11: 10:11
|
||||
let mut _1: (); // in scope 0 at /the/src/instrument_coverage.rs:10:1: 16:2
|
||||
let mut _2: bool; // in scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17
|
||||
let mut _3: !; // in scope 0 at /the/src/instrument_coverage.rs:12:18: 14:10
|
||||
+ let mut _4: (); // in scope 0 at /the/src/instrument_coverage.rs:10:11: 10:11
|
||||
|
||||
bb0: {
|
||||
- falseUnwind -> [real: bb1, cleanup: bb2]; // scope 0 at $DIR/instrument_coverage.rs:10:5: 14:6
|
||||
+ StorageLive(_4); // scope 0 at $DIR/instrument_coverage.rs:9:11: 9:11
|
||||
+ _4 = const std::intrinsics::count_code_region(const 16004455475339839479_u64, const 0_u32, const 425_u32, const 493_u32) -> bb7; // scope 0 at $DIR/instrument_coverage.rs:9:11: 9:11
|
||||
- falseUnwind -> [real: bb1, cleanup: bb2]; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
|
||||
+ StorageLive(_4); // scope 0 at /the/src/instrument_coverage.rs:10:11: 10:11
|
||||
+ _4 = const std::intrinsics::count_code_region(const 16004455475339839479_u64, const 0_u32, const "/the/src/instrument_coverage.rs", const 10_u32, const 11_u32, const 16_u32, const 2_u32) -> bb7; // scope 0 at /the/src/instrument_coverage.rs:10:11: 10:11
|
||||
+ // ty::Const
|
||||
+ // + ty: unsafe extern "rust-intrinsic" fn(u64, u32, u32, u32) {std::intrinsics::count_code_region}
|
||||
+ // + ty: unsafe extern "rust-intrinsic" fn(u64, u32, &'static str, u32, u32, u32, u32) {std::intrinsics::count_code_region}
|
||||
+ // + val: Value(Scalar(<ZST>))
|
||||
+ // mir::Constant
|
||||
+ // + span: $DIR/instrument_coverage.rs:9:11: 9:11
|
||||
+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u64, u32, u32, u32) {std::intrinsics::count_code_region}, val: Value(Scalar(<ZST>)) }
|
||||
+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
|
||||
+ // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(u64, u32, &'static str, u32, u32, u32, u32) {std::intrinsics::count_code_region}, val: Value(Scalar(<ZST>)) }
|
||||
+ // ty::Const
|
||||
+ // + ty: u64
|
||||
+ // + val: Value(Scalar(0xde1b3f75a72fc7f7))
|
||||
+ // mir::Constant
|
||||
+ // + span: $DIR/instrument_coverage.rs:9:11: 9:11
|
||||
+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
|
||||
+ // + literal: Const { ty: u64, val: Value(Scalar(0xde1b3f75a72fc7f7)) }
|
||||
+ // ty::Const
|
||||
+ // + ty: u32
|
||||
+ // + val: Value(Scalar(0x00000000))
|
||||
+ // mir::Constant
|
||||
+ // + span: $DIR/instrument_coverage.rs:9:11: 9:11
|
||||
+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
|
||||
+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000000)) }
|
||||
+ // ty::Const
|
||||
+ // + ty: u32
|
||||
+ // + val: Value(Scalar(0x000001a9))
|
||||
+ // + ty: &str
|
||||
+ // + val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 })
|
||||
+ // mir::Constant
|
||||
+ // + span: $DIR/instrument_coverage.rs:9:11: 9:11
|
||||
+ // + literal: Const { ty: u32, val: Value(Scalar(0x000001a9)) }
|
||||
+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
|
||||
+ // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [47, 116, 104, 101, 47, 115, 114, 99, 47, 105, 110, 115, 116, 114, 117, 109, 101, 110, 116, 95, 99, 111, 118, 101, 114, 97, 103, 101, 46, 114, 115], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [2147483647], len: Size { raw: 31 } }, size: Size { raw: 31 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 31 }) }
|
||||
+ // ty::Const
|
||||
+ // + ty: u32
|
||||
+ // + val: Value(Scalar(0x000001ed))
|
||||
+ // + val: Value(Scalar(0x0000000a))
|
||||
+ // mir::Constant
|
||||
+ // + span: $DIR/instrument_coverage.rs:9:11: 9:11
|
||||
+ // + literal: Const { ty: u32, val: Value(Scalar(0x000001ed)) }
|
||||
+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
|
||||
+ // + literal: Const { ty: u32, val: Value(Scalar(0x0000000a)) }
|
||||
+ // ty::Const
|
||||
+ // + ty: u32
|
||||
+ // + val: Value(Scalar(0x0000000b))
|
||||
+ // mir::Constant
|
||||
+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
|
||||
+ // + literal: Const { ty: u32, val: Value(Scalar(0x0000000b)) }
|
||||
+ // ty::Const
|
||||
+ // + ty: u32
|
||||
+ // + val: Value(Scalar(0x00000010))
|
||||
+ // mir::Constant
|
||||
+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
|
||||
+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000010)) }
|
||||
+ // ty::Const
|
||||
+ // + ty: u32
|
||||
+ // + val: Value(Scalar(0x00000002))
|
||||
+ // mir::Constant
|
||||
+ // + span: /the/src/instrument_coverage.rs:10:11: 10:11
|
||||
+ // + literal: Const { ty: u32, val: Value(Scalar(0x00000002)) }
|
||||
}
|
||||
|
||||
bb1: {
|
||||
StorageLive(_2); // scope 0 at $DIR/instrument_coverage.rs:11:12: 11:17
|
||||
_2 = const bar() -> [return: bb3, unwind: bb2]; // scope 0 at $DIR/instrument_coverage.rs:11:12: 11:17
|
||||
StorageLive(_2); // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17
|
||||
_2 = const bar() -> [return: bb3, unwind: bb2]; // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17
|
||||
// ty::Const
|
||||
// + ty: fn() -> bool {bar}
|
||||
// + val: Value(Scalar(<ZST>))
|
||||
// mir::Constant
|
||||
// + span: $DIR/instrument_coverage.rs:11:12: 11:15
|
||||
// + span: /the/src/instrument_coverage.rs:12:12: 12:15
|
||||
// + literal: Const { ty: fn() -> bool {bar}, val: Value(Scalar(<ZST>)) }
|
||||
}
|
||||
|
||||
bb2 (cleanup): {
|
||||
resume; // scope 0 at $DIR/instrument_coverage.rs:9:1: 15:2
|
||||
resume; // scope 0 at /the/src/instrument_coverage.rs:10:1: 16:2
|
||||
}
|
||||
|
||||
bb3: {
|
||||
FakeRead(ForMatchedPlace, _2); // scope 0 at $DIR/instrument_coverage.rs:11:12: 11:17
|
||||
switchInt(_2) -> [false: bb5, otherwise: bb4]; // scope 0 at $DIR/instrument_coverage.rs:11:9: 13:10
|
||||
FakeRead(ForMatchedPlace, _2); // scope 0 at /the/src/instrument_coverage.rs:12:12: 12:17
|
||||
switchInt(_2) -> [false: bb5, otherwise: bb4]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
|
||||
}
|
||||
|
||||
bb4: {
|
||||
falseEdge -> [real: bb6, imaginary: bb5]; // scope 0 at $DIR/instrument_coverage.rs:11:9: 13:10
|
||||
falseEdge -> [real: bb6, imaginary: bb5]; // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
|
||||
}
|
||||
|
||||
bb5: {
|
||||
_1 = const (); // scope 0 at $DIR/instrument_coverage.rs:11:9: 13:10
|
||||
_1 = const (); // scope 0 at /the/src/instrument_coverage.rs:12:9: 14:10
|
||||
// ty::Const
|
||||
// + ty: ()
|
||||
// + val: Value(Scalar(<ZST>))
|
||||
// mir::Constant
|
||||
// + span: $DIR/instrument_coverage.rs:11:9: 13:10
|
||||
// + span: /the/src/instrument_coverage.rs:12:9: 14:10
|
||||
// + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
|
||||
StorageDead(_2); // scope 0 at $DIR/instrument_coverage.rs:14:5: 14:6
|
||||
goto -> bb0; // scope 0 at $DIR/instrument_coverage.rs:10:5: 14:6
|
||||
StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6
|
||||
goto -> bb0; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
|
||||
}
|
||||
|
||||
bb6: {
|
||||
_0 = const (); // scope 0 at $DIR/instrument_coverage.rs:12:13: 12:18
|
||||
_0 = const (); // scope 0 at /the/src/instrument_coverage.rs:13:13: 13:18
|
||||
// ty::Const
|
||||
// + ty: ()
|
||||
// + val: Value(Scalar(<ZST>))
|
||||
// mir::Constant
|
||||
// + span: $DIR/instrument_coverage.rs:12:13: 12:18
|
||||
// + span: /the/src/instrument_coverage.rs:13:13: 13:18
|
||||
// + literal: Const { ty: (), val: Value(Scalar(<ZST>)) }
|
||||
StorageDead(_2); // scope 0 at $DIR/instrument_coverage.rs:14:5: 14:6
|
||||
return; // scope 0 at $DIR/instrument_coverage.rs:15:2: 15:2
|
||||
StorageDead(_2); // scope 0 at /the/src/instrument_coverage.rs:15:5: 15:6
|
||||
return; // scope 0 at /the/src/instrument_coverage.rs:16:2: 16:2
|
||||
+ }
|
||||
+
|
||||
+ bb7: {
|
||||
+ StorageDead(_4); // scope 0 at $DIR/instrument_coverage.rs:10:5: 14:6
|
||||
+ falseUnwind -> [real: bb1, cleanup: bb2]; // scope 0 at $DIR/instrument_coverage.rs:10:5: 14:6
|
||||
+ StorageDead(_4); // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
|
||||
+ falseUnwind -> [real: bb1, cleanup: bb2]; // scope 0 at /the/src/instrument_coverage.rs:11:5: 15:6
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
// intrinsics, during codegen.
|
||||
|
||||
// needs-profiler-support
|
||||
// compile-flags: -Zinstrument-coverage
|
||||
// ignore-windows
|
||||
// compile-flags: -Zinstrument-coverage --remap-path-prefix={{src-base}}=/the/src
|
||||
// EMIT_MIR instrument_coverage.main.InstrumentCoverage.diff
|
||||
// EMIT_MIR instrument_coverage.bar.InstrumentCoverage.diff
|
||||
fn main() {
|
||||
|
|
@ -18,3 +19,18 @@ fn main() {
|
|||
fn bar() -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
// Note that the MIR with injected coverage intrinsics includes references to source locations,
|
||||
// including the source file absolute path. Typically, MIR pretty print output with file
|
||||
// references are safe because the file prefixes are substituted with `$DIR`, but in this case
|
||||
// the file references are encoded as function arguments, with an `Operand` type representation
|
||||
// (`Slice` `Allocation` interned byte array) that cannot be normalized by simple substitution.
|
||||
//
|
||||
// The first workaround is to use the `SourceMap`-supported `--remap-path-prefix` option; however,
|
||||
// the implementation of the `--remap-path-prefix` option currently joins the new prefix and the
|
||||
// remaining source path with an OS-specific path separator (`\` on Windows). This difference still
|
||||
// shows up in the byte array representation of the path, causing Windows tests to fail to match
|
||||
// blessed results baselined with a `/` path separator.
|
||||
//
|
||||
// Since this `mir-opt` test does not have any significant platform dependencies, other than the
|
||||
// path separator differences, the final workaround is to disable testing on Windows.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue