-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Test Coverage: cannot find uncovered lines and regions #137524
Comments
git clone https://github.com/Nugine/scoped-writer
cd scoped-writer
git checkout v0.2.0
cargo tarpaulin
|
Hmm, I'm curious to see what shows up in the Would you be able to run those, and post or link them here? |
(The fact that the HTML report can't jump to uncovered lines/regions is arguably an LLVM bug, but it's quite possible that we're emitting something that weird that is causing LLVM's tools to behave strangely, so we would want to fix that on our end if possible anyway.) |
Here are git clone https://github.com/Nugine/scoped-writer
cd scoped-writer
git checkout v0.2.0
1| |#![allow(unsafe_code)]
2| |#![deny(clippy::all, clippy::pedantic, clippy::cargo)]
3| |
4| |use std::cell::RefCell;
5| |use std::io;
6| |use std::ptr;
7| |
8| |type SlotType = *mut dyn io::Write;
9| |
10| |thread_local! {
11| | static SLOT: RefCell<*mut SlotType> = const { RefCell::new(ptr::null_mut()) };
12| |}
13| |
14| |struct SlotGuard(*mut SlotType);
15| |
16| |impl SlotGuard {
17| | #[must_use]
18| 5| fn new(cur: *mut SlotType) -> Self {
19| 5| let prev = SLOT.with(|slot| slot.replace(cur));
20| 5| SlotGuard(prev)
21| 5| }
22| |}
23| |
24| |impl Drop for SlotGuard {
25| 5| fn drop(&mut self) {
26| 5| SLOT.with(|slot| *slot.borrow_mut() = self.0);
27| 5| }
28| |}
29| |
30| |/// Sets the global writer for the duration of the closure in current thread.
31| 5|pub fn scoped<R>(mut w: &mut dyn io::Write, f: impl FnOnce() -> R) -> R {
32| 5| let _guard = SlotGuard::new(ptr::addr_of_mut!(w).cast());
33| 5| f()
34| 5|}
35| |
36| |/// Executes a closure with the global writer, skips if the writer is not set.
37| |///
38| |/// Reentrancy is not allowed.
39| |///
40| |/// # Panics
41| |/// Panics if this function is called recursively
42| 12|pub fn with<R>(f: impl FnOnce(&mut dyn io::Write) -> R) -> Option<R> {
43| 12| SLOT.with(|slot| {
44| 12| let Ok(cur) = slot.try_borrow_mut() else {
^11
45| 1| panic!("Reentrancy is not allowed")
46| | };
47| 11| let p = cur.cast::<&mut dyn io::Write>();
48| 11| if p.is_null() {
49| 4| None
50| | } else {
51| 7| Some(f(unsafe { &mut **p }))
52| | }
53| 12| })
^11
54| 12|}
55| |
56| |/// [`writeln!`] to the global writer.
57| |#[macro_export]
58| |macro_rules! g {
59| | () => {{
60| 1| $crate::with(|w|writeln!(w).unwrap());
61| | }};
62| | ($fmt:literal $($arg:tt)*) => {{
63| 4| $crate::with(|w|writeln!(w, $fmt $($arg)*).unwrap());
64| | }};
65| |}
66| |
67| |/// Writes lines to the global writer.
68| 1|pub fn g<L>(lines: impl AsRef<[L]>)
69| 1|where
70| 1| L: AsRef<str>,
71| 1|{
72| 1| with(|w| {
73| 3| for line in lines.as_ref() {
^1
74| 3| writeln!(w, "{}", line.as_ref()).unwrap();
75| 3| }
76| 1| });
77| 1|}
{"data":[{"files":[{"branches":[],"mcdc_records":[],"expansions":[],"filename":"/home/nugine/projects/scoped-writer/src/lib.rs","segments":[[18,5,5,true,true,false],[19,30,0,false,false,false],[19,37,5,true,true,false],[19,54,5,true,true,false],[21,6,0,false,false,false],[25,5,5,true,true,false],[26,19,0,false,false,false],[26,26,5,true,true,false],[26,53,5,true,true,false],[27,6,0,false,false,false],[31,1,5,true,true,false],[34,2,0,false,false,false],[42,1,12,true,true,false],[43,15,0,false,false,false],[43,22,12,true,true,false],[43,23,0,false,false,false],[44,16,11,true,true,false],[44,19,0,false,false,false],[44,23,12,true,true,false],[44,44,0,false,false,false],[45,13,1,true,true,false],[45,48,0,false,false,false],[47,13,11,true,true,false],[48,23,0,false,false,false],[49,13,4,true,true,false],[49,17,0,false,false,false],[51,13,7,true,true,false],[51,41,0,false,false,false],[53,5,11,true,true,false],[53,6,12,true,true,false],[54,2,0,false,false,false],[60,25,1,true,true,false],[60,45,0,false,false,false],[63,25,4,true,true,false],[63,60,0,false,false,false],[68,1,1,true,true,false],[72,10,0,false,false,false],[72,14,1,true,true,false],[72,15,0,false,false,false],[73,13,3,true,true,false],[73,17,0,false,false,false],[73,21,1,true,true,false],[73,35,0,false,false,false],[73,36,3,true,true,false],[75,10,0,false,false,false],[76,5,1,true,true,false],[76,6,1,true,true,false],[77,2,0,false,false,false]],"summary":{"branches":{"count":0,"covered":0,"notcovered":0,"percent":0.0},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0.0},"functions":{"count":11,"covered":11,"percent":100.0},"instantiations":{"count":55,"covered":40,"percent":72.72727272727273},"lines":{"count":39,"covered":37,"percent":94.87179487179486},"regions":{"count":26,"covered":24,"notcovered":2,"percent":92.3076923076923}}}],"functions":[{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNCNCNCNvCseU1beW9C0OU_5basics_10test_panics_000B7_","regions":[[22,34,23,25,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNCNCNCNvCseU1beW9C0OU_5basics_15test_reentrancy000B7_","regions":[[43,23,46,14,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNCNCNvCseU1beW9C0OU_5basics_10test_panics_00B5_","regions":[[21,30,22,31,1,0,0,0],[24,14,25,10,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNCNCNvCseU1beW9C0OU_5basics_15test_reentrancy00B5_","regions":[[42,19,43,18,1,0,0,0],[46,14,47,10,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCNCNvCseU1beW9C0OU_5basics_8test_vec00B5_","regions":[[63,25,63,60,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCNCNvCseU1beW9C0OU_5basics_8test_vec0s0_0B5_","regions":[[63,25,63,60,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCNCNvCseU1beW9C0OU_5basics_8test_vec0s1_0B5_","regions":[[63,25,63,60,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCNCNvCseU1beW9C0OU_5basics_8test_vec0s2_0B5_","regions":[[63,25,63,60,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCNCNvCseU1beW9C0OU_5basics_8test_vec0s_0B5_","regions":[[60,25,60,45,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNCNvCseU1beW9C0OU_5basics_10test_empty0B3_","regions":[[53,24,53,44,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNCNvCseU1beW9C0OU_5basics_10test_panic0B3_","regions":[[14,24,14,35,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNCNvCseU1beW9C0OU_5basics_10test_panics0_0B3_","regions":[[32,24,32,35,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNCNvCseU1beW9C0OU_5basics_10test_panics_0B3_","regions":[[20,48,21,27,1,0,0,0],[25,10,26,6,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCNvCseU1beW9C0OU_5basics_14test_match_arm0B3_","regions":[[60,25,60,45,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNCNvCseU1beW9C0OU_5basics_15test_reentrancy0B3_","regions":[[41,25,42,14,1,0,0,0],[47,10,48,6,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNCNvCseU1beW9C0OU_5basics_8test_vec0B3_","regions":[[61,25,69,6,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNCNvCseU1beW9C0OU_5basics_9test_file0B3_","regions":[[100,26,100,51,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer1gReABx_j3_ECseU1beW9C0OU_5basic","regions":[[68,1,72,10,1,0,0,0],[76,6,77,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer4withINtNtCs54tgE0qq4eT_4core6option6OptionuENCNCNvCseU1beW9C0OU_5basics_15test_reentrancy00EB1k_","regions":[[42,1,43,15,1,0,0,0],[53,6,54,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer4withINtNtCs54tgE0qq4eT_4core6result6ResultuNtNtNtCshtXwObSDtjQ_3std2io5error5ErrorENCNvCseU1beW9C0OU_5basics_10test_empty0EB1V_","regions":[[42,1,43,15,1,0,0,0],[53,6,54,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer4withINtNtCs54tgE0qq4eT_4core6result6ResultuNtNtNtCshtXwObSDtjQ_3std2io5error5ErrorENCNvCseU1beW9C0OU_5basics_10test_panic0EB1V_","regions":[[42,1,43,15,1,0,0,0],[53,6,54,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer4withINtNtCs54tgE0qq4eT_4core6result6ResultuNtNtNtCshtXwObSDtjQ_3std2io5error5ErrorENCNvCseU1beW9C0OU_5basics_10test_panics0_0EB1V_","regions":[[42,1,43,15,1,0,0,0],[53,6,54,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer4withuNCINvB2_1gReABL_j3_E0ECseU1beW9C0OU_5basic","regions":[[42,1,43,15,1,0,0,0],[53,6,54,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer4withuNCNCNCNvCseU1beW9C0OU_5basics_15test_reentrancy000EBJ_","regions":[[42,1,43,15,1,0,0,0],[53,6,54,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer4withuNCNCNvCseU1beW9C0OU_5basics_8test_vec00EBH_","regions":[[42,1,43,15,1,0,0,0],[53,6,54,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer4withuNCNCNvCseU1beW9C0OU_5basics_8test_vec0s0_0EBH_","regions":[[42,1,43,15,1,0,0,0],[53,6,54,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer4withuNCNCNvCseU1beW9C0OU_5basics_8test_vec0s1_0EBH_","regions":[[42,1,43,15,1,0,0,0],[53,6,54,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer4withuNCNCNvCseU1beW9C0OU_5basics_8test_vec0s2_0EBH_","regions":[[42,1,43,15,1,0,0,0],[53,6,54,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer4withuNCNCNvCseU1beW9C0OU_5basics_8test_vec0s_0EBH_","regions":[[42,1,43,15,1,0,0,0],[53,6,54,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer4withuNCNvCseU1beW9C0OU_5basics_14test_match_arm0EBF_","regions":[[42,1,43,15,1,0,0,0],[53,6,54,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer6scopedINtNtCs54tgE0qq4eT_4core6option6OptionIBD_uEENCNvCseU1beW9C0OU_5basics_15test_reentrancy0EB1p_","regions":[[31,1,34,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer6scopeduNCNCNCNvCseU1beW9C0OU_5basics_10test_panics_000EBL_","regions":[[31,1,34,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer6scopeduNCNCNvCseU1beW9C0OU_5basics_10test_panics_00EBJ_","regions":[[31,1,34,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer6scopeduNCNvCseU1beW9C0OU_5basics_8test_vec0EBH_","regions":[[31,1,34,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer6scopeduNCNvCseU1beW9C0OU_5basics_9test_file0EBH_","regions":[[31,1,34,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsh4UBuZMk7J1_13scoped_writer1gReABz_j3_E0CseU1beW9C0OU_5basic","regions":[[72,14,72,15,1,0,0,0],[73,13,73,17,3,0,0,0],[73,21,73,35,1,0,0,0],[73,36,75,10,3,0,0,0],[76,5,76,6,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsh4UBuZMk7J1_13scoped_writer4withINtNtCs54tgE0qq4eT_4core6option6OptionuENCNCNvCseU1beW9C0OU_5basics_15test_reentrancy00E0B1m_","regions":[[43,22,43,23,1,0,0,0],[44,16,44,19,1,0,0,0],[44,23,44,44,1,0,0,0],[45,13,45,48,0,0,0,0],[47,13,48,23,1,0,0,0],[49,13,49,17,0,0,0,0],[51,13,51,41,1,0,0,0],[53,5,53,6,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsh4UBuZMk7J1_13scoped_writer4withINtNtCs54tgE0qq4eT_4core6result6ResultuNtNtNtCshtXwObSDtjQ_3std2io5error5ErrorENCNvCseU1beW9C0OU_5basics_10test_empty0E0B1X_","regions":[[43,22,43,23,1,0,0,0],[44,16,44,19,1,0,0,0],[44,23,44,44,1,0,0,0],[45,13,45,48,0,0,0,0],[47,13,48,23,1,0,0,0],[49,13,49,17,1,0,0,0],[51,13,51,41,0,0,0,0],[53,5,53,6,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsh4UBuZMk7J1_13scoped_writer4withINtNtCs54tgE0qq4eT_4core6result6ResultuNtNtNtCshtXwObSDtjQ_3std2io5error5ErrorENCNvCseU1beW9C0OU_5basics_10test_panic0E0B1X_","regions":[[43,22,43,23,1,0,0,0],[44,16,44,19,1,0,0,0],[44,23,44,44,1,0,0,0],[45,13,45,48,0,0,0,0],[47,13,48,23,1,0,0,0],[49,13,49,17,1,0,0,0],[51,13,51,41,0,0,0,0],[53,5,53,6,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsh4UBuZMk7J1_13scoped_writer4withINtNtCs54tgE0qq4eT_4core6result6ResultuNtNtNtCshtXwObSDtjQ_3std2io5error5ErrorENCNvCseU1beW9C0OU_5basics_10test_panics0_0E0B1X_","regions":[[43,22,43,23,1,0,0,0],[44,16,44,19,1,0,0,0],[44,23,44,44,1,0,0,0],[45,13,45,48,0,0,0,0],[47,13,48,23,1,0,0,0],[49,13,49,17,1,0,0,0],[51,13,51,41,0,0,0,0],[53,5,53,6,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsh4UBuZMk7J1_13scoped_writer4withuNCINvB4_1gReABN_j3_E0E0CseU1beW9C0OU_5basic","regions":[[43,22,43,23,1,0,0,0],[44,16,44,19,1,0,0,0],[44,23,44,44,1,0,0,0],[45,13,45,48,0,0,0,0],[47,13,48,23,1,0,0,0],[49,13,49,17,0,0,0,0],[51,13,51,41,1,0,0,0],[53,5,53,6,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsh4UBuZMk7J1_13scoped_writer4withuNCNCNCNvCseU1beW9C0OU_5basics_15test_reentrancy000E0BL_","regions":[[43,22,43,23,1,0,0,0],[44,16,44,19,0,0,0,0],[44,23,44,44,1,0,0,0],[45,13,45,48,1,0,0,0],[47,13,48,23,0,0,0,0],[49,13,49,17,0,0,0,0],[51,13,51,41,0,0,0,0],[53,5,53,6,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsh4UBuZMk7J1_13scoped_writer4withuNCNCNvCseU1beW9C0OU_5basics_8test_vec00E0BJ_","regions":[[43,22,43,23,1,0,0,0],[44,16,44,19,1,0,0,0],[44,23,44,44,1,0,0,0],[45,13,45,48,0,0,0,0],[47,13,48,23,1,0,0,0],[49,13,49,17,0,0,0,0],[51,13,51,41,1,0,0,0],[53,5,53,6,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsh4UBuZMk7J1_13scoped_writer4withuNCNCNvCseU1beW9C0OU_5basics_8test_vec0s0_0E0BJ_","regions":[[43,22,43,23,1,0,0,0],[44,16,44,19,1,0,0,0],[44,23,44,44,1,0,0,0],[45,13,45,48,0,0,0,0],[47,13,48,23,1,0,0,0],[49,13,49,17,0,0,0,0],[51,13,51,41,1,0,0,0],[53,5,53,6,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsh4UBuZMk7J1_13scoped_writer4withuNCNCNvCseU1beW9C0OU_5basics_8test_vec0s1_0E0BJ_","regions":[[43,22,43,23,1,0,0,0],[44,16,44,19,1,0,0,0],[44,23,44,44,1,0,0,0],[45,13,45,48,0,0,0,0],[47,13,48,23,1,0,0,0],[49,13,49,17,0,0,0,0],[51,13,51,41,1,0,0,0],[53,5,53,6,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsh4UBuZMk7J1_13scoped_writer4withuNCNCNvCseU1beW9C0OU_5basics_8test_vec0s2_0E0BJ_","regions":[[43,22,43,23,1,0,0,0],[44,16,44,19,1,0,0,0],[44,23,44,44,1,0,0,0],[45,13,45,48,0,0,0,0],[47,13,48,23,1,0,0,0],[49,13,49,17,0,0,0,0],[51,13,51,41,1,0,0,0],[53,5,53,6,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsh4UBuZMk7J1_13scoped_writer4withuNCNCNvCseU1beW9C0OU_5basics_8test_vec0s_0E0BJ_","regions":[[43,22,43,23,1,0,0,0],[44,16,44,19,1,0,0,0],[44,23,44,44,1,0,0,0],[45,13,45,48,0,0,0,0],[47,13,48,23,1,0,0,0],[49,13,49,17,0,0,0,0],[51,13,51,41,1,0,0,0],[53,5,53,6,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsh4UBuZMk7J1_13scoped_writer4withuNCNvCseU1beW9C0OU_5basics_14test_match_arm0E0BH_","regions":[[43,22,43,23,1,0,0,0],[44,16,44,19,1,0,0,0],[44,23,44,44,1,0,0,0],[45,13,45,48,0,0,0,0],[47,13,48,23,1,0,0,0],[49,13,49,17,1,0,0,0],[51,13,51,41,0,0,0,0],[53,5,53,6,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNvCseU1beW9C0OU_5basics_10test_empty","regions":[[52,1,53,20,1,0,0,0],[53,44,54,27,1,0,0,0],[55,1,55,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNvCseU1beW9C0OU_5basics_10test_panic","regions":[[13,1,14,20,1,0,0,0],[14,35,15,27,1,0,0,0],[17,9,20,45,1,0,0,0],[26,6,28,26,1,0,0,0],[29,5,29,29,1,0,0,0],[30,5,30,29,1,0,0,0],[32,9,32,20,1,0,0,0],[32,35,33,27,1,0,0,0],[34,1,34,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNvCseU1beW9C0OU_5basics_14test_match_arm","regions":[[116,1,117,22,1,0,0,0],[118,14,120,10,0,0,0,0],[121,17,121,21,1,0,0,0],[123,1,123,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNvCseU1beW9C0OU_5basics_15test_reentrancy","regions":[[38,1,41,22,1,0,0,0],[48,6,49,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNvCseU1beW9C0OU_5basics_8test_vec","regions":[[58,1,61,22,1,0,0,0],[69,6,80,6,1,0,0,0],[81,1,81,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/projects/scoped-writer/tests/basic.rs"],"name":"_RNvCseU1beW9C0OU_5basics_9test_file","regions":[[84,1,100,23,1,0,0,0],[100,51,104,48,1,0,0,0],[108,13,111,48,1,0,0,0],[113,1,113,2,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":1,"filenames":["/home/nugine/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/panic.rs"],"name":"_RNvNCNCNCNvCseU1beW9C0OU_5basics_10test_panics_00019panic_cold_explicit","regions":[[87,9,88,48,1,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer1gppEB2_","regions":[[68,1,72,10,0,0,0,0],[76,6,77,2,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer4withppEB2_","regions":[[42,1,43,15,0,0,0,0],[53,6,54,2,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsh4UBuZMk7J1_13scoped_writer6scopedppEB2_","regions":[[31,1,34,2,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsh4UBuZMk7J1_13scoped_writer1gppE0B4_","regions":[[72,14,72,15,0,0,0,0],[73,13,73,17,0,0,0,0],[73,21,73,35,0,0,0,0],[73,36,75,10,0,0,0,0],[76,5,76,6,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsh4UBuZMk7J1_13scoped_writer4withppE0B4_","regions":[[43,22,43,23,0,0,0,0],[44,16,44,19,0,0,0,0],[44,23,44,44,0,0,0,0],[45,13,45,48,0,0,0,0],[47,13,48,23,0,0,0,0],[49,13,49,17,0,0,0,0],[51,13,51,41,0,0,0,0],[53,5,53,6,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/thread_local/native/mod.rs"],"name":"_RNCNkNvCsh4UBuZMk7J1_13scoped_writer4SLOT00B5_","regions":[[63,25,63,26,0,0,0,0],[67,25,68,22,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":5,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNvXs_Csh4UBuZMk7J1_13scoped_writerNtB4_9SlotGuardNtNtNtCs54tgE0qq4eT_4core3ops4drop4Drop4drop","regions":[[25,5,26,19,5,0,0,0],[26,53,27,6,5,0,0,0]]},{"branches":[],"mcdc_records":[],"count":5,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNvMCsh4UBuZMk7J1_13scoped_writerNtB2_9SlotGuard3new","regions":[[18,5,19,30,5,0,0,0],[19,54,21,6,5,0,0,0]]},{"branches":[],"mcdc_records":[],"count":22,"filenames":["/home/nugine/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/thread_local/native/mod.rs"],"name":"_RNCNkNvCsh4UBuZMk7J1_13scoped_writer4SLOT0s_0B5_","regions":[[70,25,70,26,22,0,0,0],[73,25,74,22,22,0,0,0]]},{"branches":[],"mcdc_records":[],"count":5,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCNvMCsh4UBuZMk7J1_13scoped_writerNtB4_9SlotGuard3new0B4_","regions":[[19,37,19,54,5,0,0,0]]},{"branches":[],"mcdc_records":[],"count":5,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCNvXs_Csh4UBuZMk7J1_13scoped_writerNtB6_9SlotGuardNtNtNtCs54tgE0qq4eT_4core3ops4drop4Drop4drop0B6_","regions":[[26,26,26,53,5,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsbzcfUEGh2C8_13scoped_writer1gppEB2_","regions":[[68,1,72,10,0,0,0,0],[76,6,77,2,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsbzcfUEGh2C8_13scoped_writer4withppEB2_","regions":[[42,1,43,15,0,0,0,0],[53,6,54,2,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RINvCsbzcfUEGh2C8_13scoped_writer6scopedppEB2_","regions":[[31,1,34,2,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsbzcfUEGh2C8_13scoped_writer1gppE0B4_","regions":[[72,14,72,15,0,0,0,0],[73,13,73,17,0,0,0,0],[73,21,73,35,0,0,0,0],[73,36,75,10,0,0,0,0],[76,5,76,6,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCINvCsbzcfUEGh2C8_13scoped_writer4withppE0B4_","regions":[[43,22,43,23,0,0,0,0],[44,16,44,19,0,0,0,0],[44,23,44,44,0,0,0,0],[45,13,45,48,0,0,0,0],[47,13,48,23,0,0,0,0],[49,13,49,17,0,0,0,0],[51,13,51,41,0,0,0,0],[53,5,53,6,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/thread_local/native/mod.rs"],"name":"_RNCNkNvCsbzcfUEGh2C8_13scoped_writer4SLOT00B5_","regions":[[63,25,63,26,0,0,0,0],[67,25,68,22,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCNvMCsbzcfUEGh2C8_13scoped_writerNtB4_9SlotGuard3new0B4_","regions":[[19,37,19,54,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNCNvXs_CsbzcfUEGh2C8_13scoped_writerNtB6_9SlotGuardNtNtNtCs54tgE0qq4eT_4core3ops4drop4Drop4drop0B6_","regions":[[26,26,26,53,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNvMCsbzcfUEGh2C8_13scoped_writerNtB2_9SlotGuard3new","regions":[[18,5,19,30,0,0,0,0],[19,54,21,6,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/projects/scoped-writer/src/lib.rs"],"name":"_RNvXs_CsbzcfUEGh2C8_13scoped_writerNtB4_9SlotGuardNtNtNtCs54tgE0qq4eT_4core3ops4drop4Drop4drop","regions":[[25,5,26,19,0,0,0,0],[26,53,27,6,0,0,0,0]]},{"branches":[],"mcdc_records":[],"count":0,"filenames":["/home/nugine/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/thread_local/native/mod.rs"],"name":"_RNCNkNvCsbzcfUEGh2C8_13scoped_writer4SLOT0s_0B5_","regions":[[70,25,70,26,0,0,0,0],[73,25,74,22,0,0,0,0]]}],"totals":{"branches":{"count":0,"covered":0,"notcovered":0,"percent":0},"functions":{"count":11,"covered":11,"percent":100},"instantiations":{"count":55,"covered":40,"percent":72.72727272727273},"lines":{"count":39,"covered":37,"percent":94.87179487179486},"mcdc":{"count":0,"covered":0,"notcovered":0,"percent":0},"regions":{"count":26,"covered":24,"notcovered":2,"percent":92.3076923076923}}}],"type":"llvm.coverage.json.export","version":"2.0.1","cargo_llvm_cov":{"version":"0.6.16","manifest_path":"/home/nugine/projects/scoped-writer/Cargo.toml"}} $ rustc -v --version
rustc 1.85.0 (4d91de4e4 2025-02-17)
binary: rustc
commit-hash: 4d91de4e48198da2e33413efdcd9cd2cc0c46688
commit-date: 2025-02-17
host: x86_64-unknown-linux-gnu
release: 1.85.0
LLVM version: 19.1.7 |
Ah, I think what's happening is that the closures in Some of those instantiations are unused, but others are used, and the used ones appear to have made the unused ones invisible, even though they are still counted in the totals. Does running |
cargo llvm-cov --show-instantiations --text 1| |#![allow(unsafe_code)]
2| |#![deny(clippy::all, clippy::pedantic, clippy::cargo)]
3| |
4| |use std::cell::RefCell;
5| |use std::io;
6| |use std::ptr;
7| |
8| |type SlotType = *mut dyn io::Write;
9| |
10| |thread_local! {
11| | static SLOT: RefCell<*mut SlotType> = const { RefCell::new(ptr::null_mut()) };
12| |}
13| |
14| |struct SlotGuard(*mut SlotType);
15| |
16| |impl SlotGuard {
17| | #[must_use]
18| 5| fn new(cur: *mut SlotType) -> Self {
19| 5| let prev = SLOT.with(|slot| slot.replace(cur));
------------------
| <scoped_writer::SlotGuard>::new::{closure#0}:
| 19| 5| let prev = SLOT.with(|slot| slot.replace(cur));
------------------
| Unexecuted instantiation: <scoped_writer::SlotGuard>::new::{closure#0}
------------------
20| 5| SlotGuard(prev)
21| 5| }
------------------
| <scoped_writer::SlotGuard>::new:
| 18| 5| fn new(cur: *mut SlotType) -> Self {
| 19| 5| let prev = SLOT.with(|slot| slot.replace(cur));
| 20| 5| SlotGuard(prev)
| 21| 5| }
------------------
| Unexecuted instantiation: <scoped_writer::SlotGuard>::new
------------------
22| |}
23| |
24| |impl Drop for SlotGuard {
25| 5| fn drop(&mut self) {
26| 5| SLOT.with(|slot| *slot.borrow_mut() = self.0);
------------------
| <scoped_writer::SlotGuard as core::ops::drop::Drop>::drop::{closure#0}:
| 26| 5| SLOT.with(|slot| *slot.borrow_mut() = self.0);
------------------
| Unexecuted instantiation: <scoped_writer::SlotGuard as core::ops::drop::Drop>::drop::{closure#0}
------------------
27| 5| }
------------------
| <scoped_writer::SlotGuard as core::ops::drop::Drop>::drop:
| 25| 5| fn drop(&mut self) {
| 26| 5| SLOT.with(|slot| *slot.borrow_mut() = self.0);
| 27| 5| }
------------------
| Unexecuted instantiation: <scoped_writer::SlotGuard as core::ops::drop::Drop>::drop
------------------
28| |}
29| |
30| |/// Sets the global writer for the duration of the closure in current thread.
31| 5|pub fn scoped<R>(mut w: &mut dyn io::Write, f: impl FnOnce() -> R) -> R {
32| 5| let _guard = SlotGuard::new(ptr::addr_of_mut!(w).cast());
33| 5| f()
34| 5|}
------------------
| scoped_writer::scoped::<core::option::Option<core::option::Option<()>>, basic::test_reentrancy::{closure#0}>:
| 31| 1|pub fn scoped<R>(mut w: &mut dyn io::Write, f: impl FnOnce() -> R) -> R {
| 32| 1| let _guard = SlotGuard::new(ptr::addr_of_mut!(w).cast());
| 33| 1| f()
| 34| 1|}
------------------
| scoped_writer::scoped::<(), basic::test_panic::{closure#1}::{closure#0}::{closure#0}>:
| 31| 1|pub fn scoped<R>(mut w: &mut dyn io::Write, f: impl FnOnce() -> R) -> R {
| 32| 1| let _guard = SlotGuard::new(ptr::addr_of_mut!(w).cast());
| 33| 1| f()
| 34| 1|}
------------------
| scoped_writer::scoped::<(), basic::test_panic::{closure#1}::{closure#0}>:
| 31| 1|pub fn scoped<R>(mut w: &mut dyn io::Write, f: impl FnOnce() -> R) -> R {
| 32| 1| let _guard = SlotGuard::new(ptr::addr_of_mut!(w).cast());
| 33| 1| f()
| 34| 1|}
------------------
| scoped_writer::scoped::<(), basic::test_vec::{closure#0}>:
| 31| 1|pub fn scoped<R>(mut w: &mut dyn io::Write, f: impl FnOnce() -> R) -> R {
| 32| 1| let _guard = SlotGuard::new(ptr::addr_of_mut!(w).cast());
| 33| 1| f()
| 34| 1|}
------------------
| scoped_writer::scoped::<(), basic::test_file::{closure#0}>:
| 31| 1|pub fn scoped<R>(mut w: &mut dyn io::Write, f: impl FnOnce() -> R) -> R {
| 32| 1| let _guard = SlotGuard::new(ptr::addr_of_mut!(w).cast());
| 33| 1| f()
| 34| 1|}
------------------
| Unexecuted instantiation: scoped_writer::scoped::<_, _>
------------------
| Unexecuted instantiation: scoped_writer::scoped::<_, _>
------------------
35| |
36| |/// Executes a closure with the global writer, skips if the writer is not set.
37| |///
38| |/// Reentrancy is not allowed.
39| |///
40| |/// # Panics
41| |/// Panics if this function is called recursively
42| 12|pub fn with<R>(f: impl FnOnce(&mut dyn io::Write) -> R) -> Option<R> {
43| 12| SLOT.with(|slot| {
44| 12| let Ok(cur) = slot.try_borrow_mut() else {
^11
45| 1| panic!("Reentrancy is not allowed")
46| | };
47| 11| let p = cur.cast::<&mut dyn io::Write>();
48| 11| if p.is_null() {
49| 4| None
50| | } else {
51| 7| Some(f(unsafe { &mut **p }))
52| | }
53| 12| })
^11
------------------
| scoped_writer::with::<core::option::Option<()>, basic::test_reentrancy::{closure#0}::{closure#0}>::{closure#0}:
| 43| 1| SLOT.with(|slot| {
| 44| 1| let Ok(cur) = slot.try_borrow_mut() else {
| 45| 0| panic!("Reentrancy is not allowed")
| 46| | };
| 47| 1| let p = cur.cast::<&mut dyn io::Write>();
| 48| 1| if p.is_null() {
| 49| 0| None
| 50| | } else {
| 51| 1| Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
------------------
| scoped_writer::with::<core::result::Result<(), std::io::error::Error>, basic::test_empty::{closure#0}>::{closure#0}:
| 43| 1| SLOT.with(|slot| {
| 44| 1| let Ok(cur) = slot.try_borrow_mut() else {
| 45| 0| panic!("Reentrancy is not allowed")
| 46| | };
| 47| 1| let p = cur.cast::<&mut dyn io::Write>();
| 48| 1| if p.is_null() {
| 49| 1| None
| 50| | } else {
| 51| 0| Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
------------------
| scoped_writer::with::<core::result::Result<(), std::io::error::Error>, basic::test_panic::{closure#0}>::{closure#0}:
| 43| 1| SLOT.with(|slot| {
| 44| 1| let Ok(cur) = slot.try_borrow_mut() else {
| 45| 0| panic!("Reentrancy is not allowed")
| 46| | };
| 47| 1| let p = cur.cast::<&mut dyn io::Write>();
| 48| 1| if p.is_null() {
| 49| 1| None
| 50| | } else {
| 51| 0| Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
------------------
| scoped_writer::with::<core::result::Result<(), std::io::error::Error>, basic::test_panic::{closure#2}>::{closure#0}:
| 43| 1| SLOT.with(|slot| {
| 44| 1| let Ok(cur) = slot.try_borrow_mut() else {
| 45| 0| panic!("Reentrancy is not allowed")
| 46| | };
| 47| 1| let p = cur.cast::<&mut dyn io::Write>();
| 48| 1| if p.is_null() {
| 49| 1| None
| 50| | } else {
| 51| 0| Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
------------------
| scoped_writer::with::<(), scoped_writer::g<&str, [&str; 3]>::{closure#0}>::{closure#0}:
| 43| 1| SLOT.with(|slot| {
| 44| 1| let Ok(cur) = slot.try_borrow_mut() else {
| 45| 0| panic!("Reentrancy is not allowed")
| 46| | };
| 47| 1| let p = cur.cast::<&mut dyn io::Write>();
| 48| 1| if p.is_null() {
| 49| 0| None
| 50| | } else {
| 51| 1| Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
------------------
| scoped_writer::with::<(), basic::test_reentrancy::{closure#0}::{closure#0}::{closure#0}>::{closure#0}:
| 43| 1| SLOT.with(|slot| {
| 44| 1| let Ok(cur) = slot.try_borrow_mut() else {
| ^0
| 45| 1| panic!("Reentrancy is not allowed")
| 46| | };
| 47| 0| let p = cur.cast::<&mut dyn io::Write>();
| 48| 0| if p.is_null() {
| 49| 0| None
| 50| | } else {
| 51| 0| Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 0| })
------------------
| scoped_writer::with::<(), basic::test_vec::{closure#0}::{closure#0}>::{closure#0}:
| 43| 1| SLOT.with(|slot| {
| 44| 1| let Ok(cur) = slot.try_borrow_mut() else {
| 45| 0| panic!("Reentrancy is not allowed")
| 46| | };
| 47| 1| let p = cur.cast::<&mut dyn io::Write>();
| 48| 1| if p.is_null() {
| 49| 0| None
| 50| | } else {
| 51| 1| Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
------------------
| scoped_writer::with::<(), basic::test_vec::{closure#0}::{closure#2}>::{closure#0}:
| 43| 1| SLOT.with(|slot| {
| 44| 1| let Ok(cur) = slot.try_borrow_mut() else {
| 45| 0| panic!("Reentrancy is not allowed")
| 46| | };
| 47| 1| let p = cur.cast::<&mut dyn io::Write>();
| 48| 1| if p.is_null() {
| 49| 0| None
| 50| | } else {
| 51| 1| Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
------------------
| scoped_writer::with::<(), basic::test_vec::{closure#0}::{closure#3}>::{closure#0}:
| 43| 1| SLOT.with(|slot| {
| 44| 1| let Ok(cur) = slot.try_borrow_mut() else {
| 45| 0| panic!("Reentrancy is not allowed")
| 46| | };
| 47| 1| let p = cur.cast::<&mut dyn io::Write>();
| 48| 1| if p.is_null() {
| 49| 0| None
| 50| | } else {
| 51| 1| Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
------------------
| scoped_writer::with::<(), basic::test_vec::{closure#0}::{closure#4}>::{closure#0}:
| 43| 1| SLOT.with(|slot| {
| 44| 1| let Ok(cur) = slot.try_borrow_mut() else {
| 45| 0| panic!("Reentrancy is not allowed")
| 46| | };
| 47| 1| let p = cur.cast::<&mut dyn io::Write>();
| 48| 1| if p.is_null() {
| 49| 0| None
| 50| | } else {
| 51| 1| Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
------------------
| scoped_writer::with::<(), basic::test_vec::{closure#0}::{closure#1}>::{closure#0}:
| 43| 1| SLOT.with(|slot| {
| 44| 1| let Ok(cur) = slot.try_borrow_mut() else {
| 45| 0| panic!("Reentrancy is not allowed")
| 46| | };
| 47| 1| let p = cur.cast::<&mut dyn io::Write>();
| 48| 1| if p.is_null() {
| 49| 0| None
| 50| | } else {
| 51| 1| Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
------------------
| scoped_writer::with::<(), basic::test_match_arm::{closure#0}>::{closure#0}:
| 43| 1| SLOT.with(|slot| {
| 44| 1| let Ok(cur) = slot.try_borrow_mut() else {
| 45| 0| panic!("Reentrancy is not allowed")
| 46| | };
| 47| 1| let p = cur.cast::<&mut dyn io::Write>();
| 48| 1| if p.is_null() {
| 49| 1| None
| 50| | } else {
| 51| 0| Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
------------------
| Unexecuted instantiation: scoped_writer::with::<_, _>::{closure#0}
------------------
| Unexecuted instantiation: scoped_writer::with::<_, _>::{closure#0}
------------------
54| 12|}
------------------
| scoped_writer::with::<core::option::Option<()>, basic::test_reentrancy::{closure#0}::{closure#0}>:
| 42| 1|pub fn with<R>(f: impl FnOnce(&mut dyn io::Write) -> R) -> Option<R> {
| 43| 1| SLOT.with(|slot| {
| 44| | let Ok(cur) = slot.try_borrow_mut() else {
| 45| | panic!("Reentrancy is not allowed")
| 46| | };
| 47| | let p = cur.cast::<&mut dyn io::Write>();
| 48| | if p.is_null() {
| 49| | None
| 50| | } else {
| 51| | Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
| 54| 1|}
------------------
| scoped_writer::with::<core::result::Result<(), std::io::error::Error>, basic::test_empty::{closure#0}>:
| 42| 1|pub fn with<R>(f: impl FnOnce(&mut dyn io::Write) -> R) -> Option<R> {
| 43| 1| SLOT.with(|slot| {
| 44| | let Ok(cur) = slot.try_borrow_mut() else {
| 45| | panic!("Reentrancy is not allowed")
| 46| | };
| 47| | let p = cur.cast::<&mut dyn io::Write>();
| 48| | if p.is_null() {
| 49| | None
| 50| | } else {
| 51| | Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
| 54| 1|}
------------------
| scoped_writer::with::<core::result::Result<(), std::io::error::Error>, basic::test_panic::{closure#0}>:
| 42| 1|pub fn with<R>(f: impl FnOnce(&mut dyn io::Write) -> R) -> Option<R> {
| 43| 1| SLOT.with(|slot| {
| 44| | let Ok(cur) = slot.try_borrow_mut() else {
| 45| | panic!("Reentrancy is not allowed")
| 46| | };
| 47| | let p = cur.cast::<&mut dyn io::Write>();
| 48| | if p.is_null() {
| 49| | None
| 50| | } else {
| 51| | Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
| 54| 1|}
------------------
| scoped_writer::with::<core::result::Result<(), std::io::error::Error>, basic::test_panic::{closure#2}>:
| 42| 1|pub fn with<R>(f: impl FnOnce(&mut dyn io::Write) -> R) -> Option<R> {
| 43| 1| SLOT.with(|slot| {
| 44| | let Ok(cur) = slot.try_borrow_mut() else {
| 45| | panic!("Reentrancy is not allowed")
| 46| | };
| 47| | let p = cur.cast::<&mut dyn io::Write>();
| 48| | if p.is_null() {
| 49| | None
| 50| | } else {
| 51| | Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
| 54| 1|}
------------------
| scoped_writer::with::<(), scoped_writer::g<&str, [&str; 3]>::{closure#0}>:
| 42| 1|pub fn with<R>(f: impl FnOnce(&mut dyn io::Write) -> R) -> Option<R> {
| 43| 1| SLOT.with(|slot| {
| 44| | let Ok(cur) = slot.try_borrow_mut() else {
| 45| | panic!("Reentrancy is not allowed")
| 46| | };
| 47| | let p = cur.cast::<&mut dyn io::Write>();
| 48| | if p.is_null() {
| 49| | None
| 50| | } else {
| 51| | Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
| 54| 1|}
------------------
| scoped_writer::with::<(), basic::test_reentrancy::{closure#0}::{closure#0}::{closure#0}>:
| 42| 1|pub fn with<R>(f: impl FnOnce(&mut dyn io::Write) -> R) -> Option<R> {
| 43| 1| SLOT.with(|slot| {
| 44| | let Ok(cur) = slot.try_borrow_mut() else {
| 45| | panic!("Reentrancy is not allowed")
| 46| | };
| 47| | let p = cur.cast::<&mut dyn io::Write>();
| 48| | if p.is_null() {
| 49| | None
| 50| | } else {
| 51| | Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
| 54| 1|}
------------------
| scoped_writer::with::<(), basic::test_vec::{closure#0}::{closure#0}>:
| 42| 1|pub fn with<R>(f: impl FnOnce(&mut dyn io::Write) -> R) -> Option<R> {
| 43| 1| SLOT.with(|slot| {
| 44| | let Ok(cur) = slot.try_borrow_mut() else {
| 45| | panic!("Reentrancy is not allowed")
| 46| | };
| 47| | let p = cur.cast::<&mut dyn io::Write>();
| 48| | if p.is_null() {
| 49| | None
| 50| | } else {
| 51| | Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
| 54| 1|}
------------------
| scoped_writer::with::<(), basic::test_vec::{closure#0}::{closure#2}>:
| 42| 1|pub fn with<R>(f: impl FnOnce(&mut dyn io::Write) -> R) -> Option<R> {
| 43| 1| SLOT.with(|slot| {
| 44| | let Ok(cur) = slot.try_borrow_mut() else {
| 45| | panic!("Reentrancy is not allowed")
| 46| | };
| 47| | let p = cur.cast::<&mut dyn io::Write>();
| 48| | if p.is_null() {
| 49| | None
| 50| | } else {
| 51| | Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
| 54| 1|}
------------------
| scoped_writer::with::<(), basic::test_vec::{closure#0}::{closure#3}>:
| 42| 1|pub fn with<R>(f: impl FnOnce(&mut dyn io::Write) -> R) -> Option<R> {
| 43| 1| SLOT.with(|slot| {
| 44| | let Ok(cur) = slot.try_borrow_mut() else {
| 45| | panic!("Reentrancy is not allowed")
| 46| | };
| 47| | let p = cur.cast::<&mut dyn io::Write>();
| 48| | if p.is_null() {
| 49| | None
| 50| | } else {
| 51| | Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
| 54| 1|}
------------------
| scoped_writer::with::<(), basic::test_vec::{closure#0}::{closure#4}>:
| 42| 1|pub fn with<R>(f: impl FnOnce(&mut dyn io::Write) -> R) -> Option<R> {
| 43| 1| SLOT.with(|slot| {
| 44| | let Ok(cur) = slot.try_borrow_mut() else {
| 45| | panic!("Reentrancy is not allowed")
| 46| | };
| 47| | let p = cur.cast::<&mut dyn io::Write>();
| 48| | if p.is_null() {
| 49| | None
| 50| | } else {
| 51| | Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
| 54| 1|}
------------------
| scoped_writer::with::<(), basic::test_vec::{closure#0}::{closure#1}>:
| 42| 1|pub fn with<R>(f: impl FnOnce(&mut dyn io::Write) -> R) -> Option<R> {
| 43| 1| SLOT.with(|slot| {
| 44| | let Ok(cur) = slot.try_borrow_mut() else {
| 45| | panic!("Reentrancy is not allowed")
| 46| | };
| 47| | let p = cur.cast::<&mut dyn io::Write>();
| 48| | if p.is_null() {
| 49| | None
| 50| | } else {
| 51| | Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
| 54| 1|}
------------------
| scoped_writer::with::<(), basic::test_match_arm::{closure#0}>:
| 42| 1|pub fn with<R>(f: impl FnOnce(&mut dyn io::Write) -> R) -> Option<R> {
| 43| 1| SLOT.with(|slot| {
| 44| | let Ok(cur) = slot.try_borrow_mut() else {
| 45| | panic!("Reentrancy is not allowed")
| 46| | };
| 47| | let p = cur.cast::<&mut dyn io::Write>();
| 48| | if p.is_null() {
| 49| | None
| 50| | } else {
| 51| | Some(f(unsafe { &mut **p }))
| 52| | }
| 53| 1| })
| 54| 1|}
------------------
| Unexecuted instantiation: scoped_writer::with::<_, _>
------------------
| Unexecuted instantiation: scoped_writer::with::<_, _>
------------------
55| |
56| |/// [`writeln!`] to the global writer.
57| |#[macro_export]
58| |macro_rules! g {
59| | () => {{
60| 1| $crate::with(|w|writeln!(w).unwrap());
------------------
| basic::test_vec::{closure#0}::{closure#1}:
| 60| 1| $crate::with(|w|writeln!(w).unwrap());
------------------
| Unexecuted instantiation: basic::test_match_arm::{closure#0}
------------------
61| | }};
62| | ($fmt:literal $($arg:tt)*) => {{
63| 4| $crate::with(|w|writeln!(w, $fmt $($arg)*).unwrap());
------------------
| basic::test_vec::{closure#0}::{closure#0}:
| 63| 1| $crate::with(|w|writeln!(w, $fmt $($arg)*).unwrap());
------------------
| basic::test_vec::{closure#0}::{closure#2}:
| 63| 1| $crate::with(|w|writeln!(w, $fmt $($arg)*).unwrap());
------------------
| basic::test_vec::{closure#0}::{closure#3}:
| 63| 1| $crate::with(|w|writeln!(w, $fmt $($arg)*).unwrap());
------------------
| basic::test_vec::{closure#0}::{closure#4}:
| 63| 1| $crate::with(|w|writeln!(w, $fmt $($arg)*).unwrap());
------------------
64| | }};
65| |}
66| |
67| |/// Writes lines to the global writer.
68| 1|pub fn g<L>(lines: impl AsRef<[L]>)
69| 1|where
70| 1| L: AsRef<str>,
71| 1|{
72| 1| with(|w| {
73| 3| for line in lines.as_ref() {
^1
74| 3| writeln!(w, "{}", line.as_ref()).unwrap();
75| 3| }
76| 1| });
------------------
| scoped_writer::g::<&str, [&str; 3]>::{closure#0}:
| 72| 1| with(|w| {
| 73| 3| for line in lines.as_ref() {
| ^1
| 74| 3| writeln!(w, "{}", line.as_ref()).unwrap();
| 75| 3| }
| 76| 1| });
------------------
| Unexecuted instantiation: scoped_writer::g::<_, _>::{closure#0}
------------------
| Unexecuted instantiation: scoped_writer::g::<_, _>::{closure#0}
------------------
77| 1|}
------------------
| scoped_writer::g::<&str, [&str; 3]>:
| 68| 1|pub fn g<L>(lines: impl AsRef<[L]>)
| 69| 1|where
| 70| 1| L: AsRef<str>,
| 71| 1|{
| 72| 1| with(|w| {
| 73| | for line in lines.as_ref() {
| 74| | writeln!(w, "{}", line.as_ref()).unwrap();
| 75| | }
| 76| 1| });
| 77| 1|}
------------------
| Unexecuted instantiation: scoped_writer::g::<_, _>
------------------
| Unexecuted instantiation: scoped_writer::g::<_, _>
------------------ I haven't fully understood what the report means. And how to fix it? |
It seems this behavior aligns precisely with what you described. Specifically, closures instantiated at multiple sites in the test file cause some unused instantiations to remain invisible, despite being included in the overall coverage totals. By running cargo llvm-cov with the --show-instantiations flag does indeed make the uncovered regions visible in the report and I am experiencing the exact same problem. Is there a timeline or road-map for addressing this issue? |
https://github.com/Nugine/scoped-writer
https://github.com/Nugine/scoped-writer/blob/v0.2.0/src/lib.rs (Only 77 LoC)
git clone https://github.com/Nugine/scoped-writer cd scoped-writer git checkout v0.2.0 cargo llvm-cov --html --open
When I click
next uncovered line (L)
ornext uncovered region (R)
, there is no reaction. I don't know what is uncovered.Related
The text was updated successfully, but these errors were encountered: