|
| 1 | + 1| |// compile-flags: --edition=2018 |
| 2 | + 2| | |
| 3 | + 3| |use core::{ |
| 4 | + 4| | future::Future, |
| 5 | + 5| | marker::Send, |
| 6 | + 6| | pin::Pin, |
| 7 | + 7| |}; |
| 8 | + 8| | |
| 9 | + 9| 1|fn non_async_func() { |
| 10 | + 10| 1| println!("non_async_func was covered"); |
| 11 | + 11| 1| let b = true; |
| 12 | + 12| 1| if b { |
| 13 | + 13| 1| println!("non_async_func println in block"); |
| 14 | + 14| 1| } |
| 15 | + 15| 1|} |
| 16 | + 16| | |
| 17 | + 17| |// FIXME(#83985): The auto-generated closure in an async function is failing to include |
| 18 | + 18| |// the println!() and `let` assignment lines in the coverage code region(s), as it does in the |
| 19 | + 19| |// non-async function above, unless the `println!()` is inside a covered block. |
| 20 | + 20| 1|async fn async_func() { |
| 21 | + 21| | println!("async_func was covered"); |
| 22 | + 22| | let b = true; |
| 23 | + 23| 1| if b { |
| 24 | + 24| 1| println!("async_func println in block"); |
| 25 | + 25| 1| } |
| 26 | + ^0 |
| 27 | + 26| 1|} |
| 28 | + 27| | |
| 29 | + 28| |// FIXME(#83985): As above, this async function only has the `println!()` macro call, which is not |
| 30 | + 29| |// showing coverage, so the entire async closure _appears_ uncovered; but this is not exactly true. |
| 31 | + 30| |// It's only certain kinds of lines and/or their context that results in missing coverage. |
| 32 | + 31| 1|async fn async_func_just_println() { |
| 33 | + 32| | println!("async_func_just_println was covered"); |
| 34 | + 33| |} |
| 35 | + 34| | |
| 36 | + 35| 1|fn main() { |
| 37 | + 36| 1| println!("codecovsample::main"); |
| 38 | + 37| 1| |
| 39 | + 38| 1| non_async_func(); |
| 40 | + 39| 1| |
| 41 | + 40| 1| executor::block_on(async_func()); |
| 42 | + 41| 1| executor::block_on(async_func_just_println()); |
| 43 | + 42| 1| |
| 44 | + 43| 1| // let mut future = Box::pin(async_func()); |
| 45 | + 44| 1| // executor::block_on(future.as_mut()); |
| 46 | + 45| 1| |
| 47 | + 46| 1| // let mut future = Box::pin(async_func()); |
| 48 | + 47| 1| // executor::block_on(future.as_mut()); |
| 49 | + 48| 1| |
| 50 | + 49| 1| // let mut future = Box::pin(async_func_just_println()); |
| 51 | + 50| 1| // executor::block_on(future.as_mut()); |
| 52 | + 51| 1|} |
| 53 | + 52| | |
| 54 | + 53| |mod executor { |
| 55 | + 54| | use core::{ |
| 56 | + 55| | future::Future, |
| 57 | + 56| | pin::Pin, |
| 58 | + 57| | task::{Context, Poll, RawWaker, RawWakerVTable, Waker}, |
| 59 | + 58| | }; |
| 60 | + 59| | |
| 61 | + 60| 2| pub fn block_on<F: Future>(mut future: F) -> F::Output { |
| 62 | + 61| 2| let mut future = unsafe { Pin::new_unchecked(&mut future) }; |
| 63 | + 62| 2| use std::hint::unreachable_unchecked; |
| 64 | + 63| 2| static VTABLE: RawWakerVTable = RawWakerVTable::new( |
| 65 | + 64| 2| |_| unsafe { unreachable_unchecked() }, // clone |
| 66 | + ^0 |
| 67 | + 65| 2| |_| unsafe { unreachable_unchecked() }, // wake |
| 68 | + ^0 |
| 69 | + 66| 2| |_| unsafe { unreachable_unchecked() }, // wake_by_ref |
| 70 | + ^0 |
| 71 | + 67| 2| |_| (), |
| 72 | + 68| 2| ); |
| 73 | + 69| 2| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; |
| 74 | + 70| 2| let mut context = Context::from_waker(&waker); |
| 75 | + 71| | |
| 76 | + 72| | loop { |
| 77 | + 73| 2| if let Poll::Ready(val) = future.as_mut().poll(&mut context) { |
| 78 | + 74| 2| break val; |
| 79 | + 75| 0| } |
| 80 | + 76| | } |
| 81 | + 77| 2| } |
| 82 | + ------------------ |
| 83 | + | async2::executor::block_on::<core::future::from_generator::GenFuture<async2::async_func::{closure#0}>>: |
| 84 | + | 60| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output { |
| 85 | + | 61| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) }; |
| 86 | + | 62| 1| use std::hint::unreachable_unchecked; |
| 87 | + | 63| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new( |
| 88 | + | 64| 1| |_| unsafe { unreachable_unchecked() }, // clone |
| 89 | + | 65| 1| |_| unsafe { unreachable_unchecked() }, // wake |
| 90 | + | 66| 1| |_| unsafe { unreachable_unchecked() }, // wake_by_ref |
| 91 | + | 67| 1| |_| (), |
| 92 | + | 68| 1| ); |
| 93 | + | 69| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; |
| 94 | + | 70| 1| let mut context = Context::from_waker(&waker); |
| 95 | + | 71| | |
| 96 | + | 72| | loop { |
| 97 | + | 73| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) { |
| 98 | + | 74| 1| break val; |
| 99 | + | 75| 0| } |
| 100 | + | 76| | } |
| 101 | + | 77| 1| } |
| 102 | + ------------------ |
| 103 | + | async2::executor::block_on::<core::future::from_generator::GenFuture<async2::async_func_just_println::{closure#0}>>: |
| 104 | + | 60| 1| pub fn block_on<F: Future>(mut future: F) -> F::Output { |
| 105 | + | 61| 1| let mut future = unsafe { Pin::new_unchecked(&mut future) }; |
| 106 | + | 62| 1| use std::hint::unreachable_unchecked; |
| 107 | + | 63| 1| static VTABLE: RawWakerVTable = RawWakerVTable::new( |
| 108 | + | 64| 1| |_| unsafe { unreachable_unchecked() }, // clone |
| 109 | + | 65| 1| |_| unsafe { unreachable_unchecked() }, // wake |
| 110 | + | 66| 1| |_| unsafe { unreachable_unchecked() }, // wake_by_ref |
| 111 | + | 67| 1| |_| (), |
| 112 | + | 68| 1| ); |
| 113 | + | 69| 1| let waker = unsafe { Waker::from_raw(RawWaker::new(core::ptr::null(), &VTABLE)) }; |
| 114 | + | 70| 1| let mut context = Context::from_waker(&waker); |
| 115 | + | 71| | |
| 116 | + | 72| | loop { |
| 117 | + | 73| 1| if let Poll::Ready(val) = future.as_mut().poll(&mut context) { |
| 118 | + | 74| 1| break val; |
| 119 | + | 75| 0| } |
| 120 | + | 76| | } |
| 121 | + | 77| 1| } |
| 122 | + ------------------ |
| 123 | + 78| |} |
| 124 | + |
0 commit comments