-
Notifications
You must be signed in to change notification settings - Fork 74
Open
Description
I have a bindgen generated ffi function that returns !
. This is allowed on stable rust. The code that automock
generates fails to compile for stable rust.
Code Example:
mod outer {
#[cfg_attr(test, mockall::automock)]
pub mod ffi {
extern "C" {
pub fn never_returns() -> !;
}
}
}
#[mockall_double::double]
pub use outer::ffi;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn t() {
let ctx = ffi::never_returns_context();
ctx.expect();
unsafe {
ffi::never_returns();
}
}
}
Error:
error[E0658]: the `!` type is experimental
--> src\lib.rs:5:39
|
5 | pub fn never_returns() -> !;
| ^
|
= note: see issue #35121 <https://github.com/rust-lang/rust/issues/35121> for more information
= help: add `#![feature(never_type)]` to the crate attributes to enable
= note: this compiler was built on 2024-11-03; consider upgrading it if it is out of date
warning: unreachable call
--> src\lib.rs:2:22
|
2 | #[cfg_attr(test, mockall::automock)]
| ^^^^^^^^^^^^^^^^^
| |
| unreachable call
| any code following this expression is unreachable
|
= note: `#[warn(unreachable_code)]` on by default
= note: this warning originates in the attribute macro `mockall::automock` (in Nightly builds, run with -Z macro-backtrace for more info)
The error[E0658]: the `!` type is experimental
error is actually coming from the macro-generated code, not the original ffi declaration:
Expanded macro
// Recursive expansion of automock macro
// ======================================
pub mod ffi {
extern "C" {
pub fn never_returns() -> !;
}
}
#[allow(unused_imports)]
#[doc = "Mock version of the `ffi` module"]
pub mod mock_ffi {
#[allow(missing_docs)]
#[allow(clippy::too_many_arguments, clippy::indexing_slicing)]
pub mod __never_returns {
use super::*;
use ::mockall::CaseTreeExt;
use ::std::sync::MutexGuard;
use ::std::{
boxed::Box,
mem,
ops::{DerefMut, Range},
sync::Mutex,
vec::Vec,
};
#[allow(clippy::unused_unit)]
enum Rfunc {
Default,
Expired,
Mut(Box<dyn FnMut() -> ! + Send>),
MutSt(::mockall::Fragile<Box<dyn FnMut() -> !>>),
Once(Box<dyn FnOnce() -> ! + Send>),
OnceSt(::mockall::Fragile<Box<dyn FnOnce() -> !>>),
_Phantom(Box<dyn Fn() + Send>),
}
impl Rfunc {
fn call_mut(&mut self) -> std::result::Result<!, &'static str> {
match self {
Rfunc::Default => {
use ::mockall::ReturnDefault;
::mockall::DefaultReturner::<!>::return_default()
}
Rfunc::Expired => Err("called twice, but it returns by move"),
Rfunc::Mut(__mockall_f) => ::std::result::Result::Ok(__mockall_f()),
Rfunc::MutSt(__mockall_f) => {
::std::result::Result::Ok((__mockall_f.get_mut())())
}
Rfunc::Once(_) => {
if let Rfunc::Once(mut __mockall_f) = mem::replace(self, Rfunc::Expired) {
::std::result::Result::Ok(__mockall_f())
} else {
core::panicking::panic("internal error: entered unreachable code")
}
}
Rfunc::OnceSt(_) => {
if let Rfunc::OnceSt(mut __mockall_f) = mem::replace(self, Rfunc::Expired) {
::std::result::Result::Ok((__mockall_f.into_inner())())
} else {
core::panicking::panic("internal error: entered unreachable code")
}
}
Rfunc::_Phantom(_) => {
core::panicking::panic("internal error: entered unreachable code")
}
}
}
}
impl std::default::Default for Rfunc {
fn default() -> Self {
Rfunc::Default
}
}
enum Matcher {
Always,
Func(Box<dyn Fn() -> bool + Send>),
FuncSt(::mockall::Fragile<Box<dyn Fn() -> bool>>),
Pred(Box<()>),
_Phantom(Box<dyn Fn() + Send>),
}
impl Matcher {
#[allow(clippy::ptr_arg)]
#[allow(clippy::ref_option)]
fn matches(&self) -> bool {
match self {
Matcher::Always => true,
Matcher::Func(__mockall_f) => __mockall_f(),
Matcher::FuncSt(__mockall_f) => (__mockall_f.get())(),
Matcher::Pred(__mockall_pred) => [].iter().all(|__mockall_x| *__mockall_x),
_ => core::panicking::panic("internal error: entered unreachable code"),
}
}
}
impl Default for Matcher {
#[allow(unused_variables)]
fn default() -> Self {
Matcher::Always
}
}
impl ::std::fmt::Display for Matcher {
fn fmt(&self, __mockall_fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
match self {
Matcher::Always => __mockall_fmt.write_fmt(core::format_args!("<anything>")),
Matcher::Func(_) => __mockall_fmt.write_fmt(core::format_args!("<function>")),
Matcher::FuncSt(_) => {
__mockall_fmt.write_fmt(core::format_args!("<single threaded function>"))
}
Matcher::Pred(__mockall_p) => __mockall_fmt.write_fmt(core::format_args!("",)),
_ => core::panicking::panic("internal error: entered unreachable code"),
}
}
}
#[doc = r" Holds the stuff that is independent of the output type"]
struct Common {
matcher: Mutex<Matcher>,
seq_handle: Option<::mockall::SeqHandle>,
times: ::mockall::Times,
}
impl std::default::Default for Common {
fn default() -> Self {
Common {
matcher: Mutex::new(Matcher::default()),
seq_handle: None,
times: ::mockall::Times::default(),
}
}
}
impl Common {
fn call(&self, desc: &str) {
self.times.call().unwrap_or_else(|m| {
let desc = alloc::__export::must_use({
let res = alloc::fmt::format(alloc::__export::format_args!(
"{}",
self.matcher.lock().unwrap()
));
res
});
{
core::panicking::panic_fmt(core::const_format_args!(
"{}: Expectation({}) {}",
"never_returns",
desc,
m
));
};
});
self.verify_sequence(desc);
if ::mockall::ExpectedCalls::TooFew != self.times.is_satisfied() {
self.satisfy_sequence()
}
}
fn in_sequence(&mut self, __mockall_seq: &mut ::mockall::Sequence) -> &mut Self {
{
if !(self.times.is_exact()) {
{
core::panicking::panic_fmt(core::const_format_args!(
"Only Expectations with an exact call count have sequences"
));
};
}
};
self.seq_handle = Some(__mockall_seq.next_handle());
self
}
fn is_done(&self) -> bool {
self.times.is_done()
}
#[allow(clippy::ptr_arg)]
#[allow(clippy::ref_option)]
fn matches(&self) -> bool {
self.matcher.lock().unwrap().matches()
}
#[doc = r" Forbid this expectation from ever being called."]
fn never(&mut self) {
self.times.never();
}
fn satisfy_sequence(&self) {
if let Some(__mockall_handle) = &self.seq_handle {
__mockall_handle.satisfy()
}
}
#[doc = r" Expect this expectation to be called any number of times"]
#[doc = r" contained with the given range."]
fn times<MockallR>(&mut self, __mockall_r: MockallR)
where
MockallR: Into<::mockall::TimesRange>,
{
self.times.times(__mockall_r)
}
fn with(&mut self) {
let mut __mockall_guard = self.matcher.lock().unwrap();
*__mockall_guard.deref_mut() = Matcher::Pred(Box::new(()));
}
fn withf<MockallF>(&mut self, __mockall_f: MockallF)
where
MockallF: Fn() -> bool + Send + 'static,
{
let mut __mockall_guard = self.matcher.lock().unwrap();
*__mockall_guard.deref_mut() = Matcher::Func(Box::new(__mockall_f));
}
fn withf_st<MockallF>(&mut self, __mockall_f: MockallF)
where
MockallF: Fn() -> bool + 'static,
{
let mut __mockall_guard = self.matcher.lock().unwrap();
*__mockall_guard.deref_mut() =
Matcher::FuncSt(::mockall::Fragile::new(Box::new(__mockall_f)));
}
fn verify_sequence(&self, desc: &str) {
if let Some(__mockall_handle) = &self.seq_handle {
__mockall_handle.verify(desc)
}
}
}
impl Drop for Common {
fn drop(&mut self) {
if !::std::thread::panicking() {
let desc = alloc::__export::must_use({
let res = alloc::fmt::format(alloc::__export::format_args!(
"{}",
self.matcher.lock().unwrap()
));
res
});
match self.times.is_satisfied() {
::mockall::ExpectedCalls::TooFew => {
{
core::panicking::panic_fmt(core::const_format_args!("{}: Expectation({}) called {} time(s) which is fewer than expected {}","never_returns",desc,self.times.count(),self.times.minimum()));
};
}
::mockall::ExpectedCalls::TooMany => {
{
core::panicking::panic_fmt(core::const_format_args!("{}: Expectation({}) called {} time(s) which is more than expected {}","never_returns",desc,self.times.count(),self.times.maximum()));
};
}
_ => (),
}
}
}
}
#[doc = r" Expectation type for methods that return a `'static` type."]
#[doc = r" This is the type returned by the `expect_*` methods."]
pub struct Expectation {
common: Common,
rfunc: Mutex<Rfunc>,
}
#[allow(clippy::unused_unit)]
impl Expectation {
#[doc = r" Call this [`Expectation`] as if it were the real method."]
#[doc(hidden)]
pub fn call(&self) -> ! {
use ::mockall::{ViaDebug, ViaNothing};
self.common.call(&alloc::__export::must_use({
let res = alloc::fmt::format(alloc::__export::format_args!(
"mock_ffi::never_returns()",
));
res
}));
self.rfunc
.lock()
.unwrap()
.call_mut()
.unwrap_or_else(|message| {
let desc = alloc::__export::must_use({
let res = alloc::fmt::format(alloc::__export::format_args!(
"{}",
self.common.matcher.lock().unwrap()
));
res
});
{
core::panicking::panic_fmt(core::const_format_args!(
"{}: Expectation({}) {}",
"never_returns",
desc,
message
));
};
})
}
#[doc = r" Return a constant value from the `Expectation`"]
#[doc = r""]
#[doc = r" The output type must be `Clone`. The compiler can't always"]
#[doc = r" infer the proper type to use with this method; you will"]
#[doc = r" usually need to specify it explicitly. i.e."]
#[doc = r" `return_const(42i32)` instead of `return_const(42)`."]
#[allow(unused_variables)]
pub fn return_const<MockallOutput>(&mut self, __mockall_c: MockallOutput) -> &mut Self
where
MockallOutput: Clone + Into<!> + Send + 'static,
{
self.returning(move || __mockall_c.clone().into())
}
#[doc = r" Single-threaded version of"]
#[doc = r" [`return_const`](#method.return_const). This is useful for"]
#[doc = r" return types that are not `Send`."]
#[doc = r""]
#[doc = r" The output type must be `Clone`. The compiler can't always"]
#[doc = r" infer the proper type to use with this method; you will"]
#[doc = r" usually need to specify it explicitly. i.e."]
#[doc = r" `return_const(42i32)` instead of `return_const(42)`."]
#[doc = r""]
#[doc = r" It is a runtime error to call the mock method from a"]
#[doc = r" different thread than the one that originally called this"]
#[doc = r" method."]
#[allow(unused_variables)]
pub fn return_const_st<MockallOutput>(
&mut self,
__mockall_c: MockallOutput,
) -> &mut Self
where
MockallOutput: Clone + Into<!> + 'static,
{
self.returning_st(move || __mockall_c.clone().into())
}
#[doc = r" Supply an `FnOnce` closure that will provide the return"]
#[doc = r" value for this Expectation. This is useful for return types"]
#[doc = r" that aren't `Clone`. It will be an error to call this"]
#[doc = r" method multiple times."]
pub fn return_once<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Self
where
MockallF: FnOnce() -> ! + Send + 'static,
{
{
let mut __mockall_guard = self.rfunc.lock().unwrap();
*__mockall_guard.deref_mut() = Rfunc::Once(Box::new(__mockall_f));
}
self
}
#[doc = r" Single-threaded version of"]
#[doc = r" [`return_once`](#method.return_once). This is useful for"]
#[doc = r" return types that are neither `Send` nor `Clone`."]
#[doc = r""]
#[doc = r" It is a runtime error to call the mock method from a"]
#[doc = r" different thread than the one that originally called this"]
#[doc = r" method. It is also a runtime error to call the method more"]
#[doc = r" than once."]
pub fn return_once_st<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Self
where
MockallF: FnOnce() -> ! + 'static,
{
{
let mut __mockall_guard = self.rfunc.lock().unwrap();
*__mockall_guard.deref_mut() =
Rfunc::OnceSt(::mockall::Fragile::new(Box::new(__mockall_f)));
}
self
}
#[doc = r" Supply a closure that will provide the return value for this"]
#[doc = r" `Expectation`. The method's arguments are passed to the"]
#[doc = r" closure by value."]
pub fn returning<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Self
where
MockallF: FnMut() -> ! + Send + 'static,
{
{
let mut __mockall_guard = self.rfunc.lock().unwrap();
*__mockall_guard.deref_mut() = Rfunc::Mut(Box::new(__mockall_f));
}
self
}
#[doc = r" Single-threaded version of [`returning`](#method.returning)."]
#[doc = r" Can be used when the argument or return type isn't `Send`."]
#[doc = r""]
#[doc = r" It is a runtime error to call the mock method from a"]
#[doc = r" different thread than the one that originally called this"]
#[doc = r" method."]
pub fn returning_st<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Self
where
MockallF: FnMut() -> ! + 'static,
{
{
let mut __mockall_guard = self.rfunc.lock().unwrap();
*__mockall_guard.deref_mut() =
Rfunc::MutSt(::mockall::Fragile::new(Box::new(__mockall_f)));
}
self
}
#[doc = r" Add this expectation to a"]
#[doc = r" [`Sequence`](../../../mockall/struct.Sequence.html)."]
pub fn in_sequence(&mut self, __mockall_seq: &mut ::mockall::Sequence) -> &mut Self {
self.common.in_sequence(__mockall_seq);
self
}
fn is_done(&self) -> bool {
self.common.is_done()
}
#[doc = r" Validate this expectation's matcher."]
#[allow(clippy::ptr_arg)]
#[allow(clippy::ref_option)]
fn matches(&self) -> bool {
self.common.matches()
}
#[doc = r" Forbid this expectation from ever being called."]
pub fn never(&mut self) -> &mut Self {
self.common.never();
self
}
#[doc = r" Create a new, default, [`Expectation`](struct.Expectation.html)"]
pub fn new() -> Self {
Self::default()
}
#[doc = r" Expect this expectation to be called exactly once. Shortcut for"]
#[doc = r" [`times(1)`](#method.times)."]
pub fn once(&mut self) -> &mut Self {
self.times(1)
}
#[doc = r" Restrict the number of times that that this method may be called."]
#[doc = r""]
#[doc = r" The argument may be:"]
#[doc = r" * A fixed number: `.times(4)`"]
#[doc = r" * Various types of range:"]
#[doc = r" - `.times(5..10)`"]
#[doc = r" - `.times(..10)`"]
#[doc = r" - `.times(5..)`"]
#[doc = r" - `.times(5..=10)`"]
#[doc = r" - `.times(..=10)`"]
#[doc = r" * The wildcard: `.times(..)`"]
pub fn times<MockallR>(&mut self, __mockall_r: MockallR) -> &mut Self
where
MockallR: Into<::mockall::TimesRange>,
{
self.common.times(__mockall_r);
self
}
#[doc = r" Set matching criteria for this Expectation."]
#[doc = r""]
#[doc = r" The matching predicate can be anything implemening the"]
#[doc = r" [`Predicate`](../../../mockall/trait.Predicate.html) trait. Only"]
#[doc = r" one matcher can be set per `Expectation` at a time."]
pub fn with(&mut self) -> &mut Self {
self.common.with();
self
}
#[doc = r" Set a matching function for this Expectation."]
#[doc = r""]
#[doc = r" This is equivalent to calling [`with`](#method.with) with a"]
#[doc = r" function argument, like `with(predicate::function(f))`."]
pub fn withf<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Self
where
MockallF: Fn() -> bool + Send + 'static,
{
self.common.withf(__mockall_f);
self
}
#[doc = r" Single-threaded version of [`withf`](#method.withf)."]
#[doc = r" Can be used when the argument type isn't `Send`."]
pub fn withf_st<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Self
where
MockallF: Fn() -> bool + 'static,
{
self.common.withf_st(__mockall_f);
self
}
}
impl Default for Expectation {
fn default() -> Self {
Expectation {
common: Common::default(),
rfunc: Mutex::new(Rfunc::default()),
}
}
}
#[doc = r" A collection of [`Expectation`](struct.Expectations.html)"]
#[doc = r" objects. Users will rarely if ever use this struct directly."]
#[doc(hidden)]
pub struct Expectations(Vec<Expectation>);
impl Expectations {
#[doc = r" Verify that all current expectations are satisfied and clear"]
#[doc = r" them."]
pub fn checkpoint(&mut self) -> std::vec::Drain<Expectation> {
self.0.drain(..)
}
#[doc = r" Create a new expectation for this method."]
pub fn expect(&mut self) -> &mut Expectation {
self.0.push(Expectation::default());
let __mockall_l = self.0.len();
&mut self.0[__mockall_l - 1]
}
pub const fn new() -> Self {
Self(Vec::new())
}
}
impl Default for Expectations {
fn default() -> Self {
Expectations::new()
}
}
impl Expectations {
#[doc = r" Simulate calling the real method. Every current expectation"]
#[doc = r" will be checked in FIFO order and the first one with"]
#[doc = r" matching arguments will be used."]
pub fn call(&self) -> Option<!> {
self.0
.iter()
.find(|__mockall_e| {
__mockall_e.matches() && (!__mockall_e.is_done() || self.0.len() == 1)
})
.map(move |__mockall_e| __mockall_e.call())
}
}
#[doc(hidden)]
pub fn get_expectations() -> &'static ::std::sync::Mutex<Expectations> {
static EXPECTATIONS: ::std::sync::Mutex<Expectations> =
::std::sync::Mutex::new(Expectations::new());
&EXPECTATIONS
}
#[doc = r" Like an [`&Expectation`](struct.Expectation.html) but"]
#[doc = r" protected by a Mutex guard. Useful for mocking static"]
#[doc = r" methods. Forwards accesses to an `Expectation` object."]
pub struct ExpectationGuard<'__mockall_lt> {
guard: MutexGuard<'__mockall_lt, Expectations>,
i: usize,
}
#[allow(clippy::unused_unit)]
impl<'__mockall_lt> ExpectationGuard<'__mockall_lt> {
#[doc(hidden)]
pub fn new(mut __mockall_guard: MutexGuard<'__mockall_lt, Expectations>) -> Self {
__mockall_guard.expect();
let __mockall_i = __mockall_guard.0.len() - 1;
ExpectationGuard {
guard: __mockall_guard,
i: __mockall_i,
}
}
#[doc = r" Just like"]
#[doc = r" [`Expectation::in_sequence`](struct.Expectation.html#method.in_sequence)"]
pub fn in_sequence(
&mut self,
__mockall_seq: &mut ::mockall::Sequence,
) -> &mut Expectation {
self.guard.0[self.i].in_sequence(__mockall_seq)
}
#[doc = r" Just like"]
#[doc = r" [`Expectation::never`](struct.Expectation.html#method.never)"]
pub fn never(&mut self) -> &mut Expectation {
self.guard.0[self.i].never()
}
#[doc = r" Just like"]
#[doc = r" [`Expectation::once`](struct.Expectation.html#method.once)"]
pub fn once(&mut self) -> &mut Expectation {
self.guard.0[self.i].once()
}
#[doc = r" Just like"]
#[doc = r" [`Expectation::return_const`](struct.Expectation.html#method.return_const)"]
pub fn return_const<MockallOutput>(
&mut self,
__mockall_c: MockallOutput,
) -> &mut Expectation
where
MockallOutput: Clone + Into<!> + Send + 'static,
{
self.guard.0[self.i].return_const(__mockall_c)
}
#[doc = r" Just like"]
#[doc = r" [`Expectation::return_const_st`](struct.Expectation.html#method.return_const_st)"]
pub fn return_const_st<MockallOutput>(
&mut self,
__mockall_c: MockallOutput,
) -> &mut Expectation
where
MockallOutput: Clone + Into<!> + 'static,
{
self.guard.0[self.i].return_const_st(__mockall_c)
}
#[doc = r" Just like"]
#[doc = r" [`Expectation::returning`](struct.Expectation.html#method.returning)"]
pub fn returning<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Expectation
where
MockallF: FnMut() -> ! + Send + 'static,
{
self.guard.0[self.i].returning(__mockall_f)
}
#[doc = r" Just like"]
#[doc = r" [`Expectation::return_once`](struct.Expectation.html#method.return_once)"]
pub fn return_once<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Expectation
where
MockallF: FnOnce() -> ! + Send + 'static,
{
self.guard.0[self.i].return_once(__mockall_f)
}
#[doc = r" Just like"]
#[doc = r" [`Expectation::return_once_st`](struct.Expectation.html#method.return_once_st)"]
pub fn return_once_st<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Expectation
where
MockallF: FnOnce() -> ! + 'static,
{
self.guard.0[self.i].return_once_st(__mockall_f)
}
#[doc = r" Just like"]
#[doc = r" [`Expectation::returning_st`](struct.Expectation.html#method.returning_st)"]
pub fn returning_st<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Expectation
where
MockallF: FnMut() -> ! + 'static,
{
self.guard.0[self.i].returning_st(__mockall_f)
}
#[doc = r" Just like"]
#[doc = r" [`Expectation::times`](struct.Expectation.html#method.times)"]
pub fn times<MockallR>(&mut self, __mockall_r: MockallR) -> &mut Expectation
where
MockallR: Into<::mockall::TimesRange>,
{
self.guard.0[self.i].times(__mockall_r)
}
#[doc = r" Just like"]
#[doc = r" [`Expectation::with`](struct.Expectation.html#method.with)"]
pub fn with(&mut self) -> &mut Expectation {
self.guard.0[self.i].with()
}
#[doc = r" Just like"]
#[doc = r" [`Expectation::withf`](struct.Expectation.html#method.withf)"]
pub fn withf<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Expectation
where
MockallF: Fn() -> bool + Send + 'static,
{
self.guard.0[self.i].withf(__mockall_f)
}
#[doc = r" Just like"]
#[doc = r" [`Expectation::withf_st`](struct.Expectation.html#method.withf_st)"]
pub fn withf_st<MockallF>(&mut self, __mockall_f: MockallF) -> &mut Expectation
where
MockallF: Fn() -> bool + 'static,
{
self.guard.0[self.i].withf_st(__mockall_f)
}
}
#[doc = r" Manages the context for expectations of static methods."]
#[doc = r""]
#[doc = r" Expectations on this method will be validated and cleared when"]
#[doc = r" the `Context` object drops. The `Context` object does *not*"]
#[doc = r" provide any form of synchronization, so multiple tests that set"]
#[doc = r" expectations on the same static method must provide their own."]
#[must_use = "Context only serves to create expectations"]
pub struct Context {
_phantom: ::std::marker::PhantomData<Box<dyn Fn() + Send>>,
}
impl Context {
#[doc = r" Verify that all current expectations for this method are"]
#[doc = r" satisfied and clear them."]
pub fn checkpoint(&self) {
Self::do_checkpoint()
}
#[doc(hidden)]
pub fn do_checkpoint() {
let __mockall_timeses = get_expectations()
.lock()
.unwrap()
.checkpoint()
.collect::<Vec<_>>();
}
#[doc = r" Create a new expectation for this method."]
#[must_use = "Must set return value when not using the \"nightly\" feature"]
pub fn expect<'__mockall_lt>(&self) -> ExpectationGuard<'__mockall_lt> {
ExpectationGuard::new(get_expectations().lock().unwrap())
}
}
impl Default for Context {
fn default() -> Self {
Context {
_phantom: std::marker::PhantomData,
}
}
}
impl Drop for Context {
fn drop(&mut self) {
if ::std::thread::panicking() {
let _ = get_expectations()
.lock()
.map(|mut g| g.checkpoint().collect::<Vec<_>>());
} else {
Self::do_checkpoint();
}
}
}
}
#[no_mangle]
pub unsafe extern "C-unwind" fn never_returns() -> ! {
use ::mockall::{ViaDebug, ViaNothing};
let no_match_msg = alloc::__export::must_use({
let res = alloc::fmt::format(alloc::__export::format_args!(
"{}: No matching expectation found",
std::format!("mock_ffi::never_returns()",)
));
res
});
{
let __mockall_guard = __never_returns::get_expectations().lock().unwrap();
__mockall_guard.call()
}
.expect(&no_match_msg)
}
#[doc = "Create a [`Context`](__never_returns/struct.Context.html) for mocking the `never_returns` method"]
pub fn never_returns_context() -> __never_returns::Context {
__never_returns::Context::default()
}
#[doc = r" Verify that all current expectations for every function in"]
#[doc = r" this module are satisfied and clear them."]
pub fn checkpoint() {
{
let __mockall_timeses = __never_returns::get_expectations()
.lock()
.unwrap()
.checkpoint()
.collect::<Vec<_>>();
}
}
}
Some situations in which supporting mocks for never returning functions would be useful include:
- ensuring the never-returning function is called in certain code paths
- ensuring the never-returning function is called with the correct parameters
Metadata
Metadata
Assignees
Labels
No labels