You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have a bindgen generated ffi function that uses variadic arguments. This is allowed on stable rust for extern C functions. The code that automock generates fails to compile for stable rust.
error[E0658]: C-variadic functions are unstable
--> src\lib.rs:2:22
|
2 | #[cfg_attr(test, mockall::automock)]
| ^^^^^^^^^^^^^^^^^
|
= note: see issue #44930 <https://github.com/rust-lang/rust/issues/44930> for more information
= help: add `#![feature(c_variadic)]` to the crate attributes to enable
= note: this compiler was built on 2024-11-03; consider upgrading it if it is out of date
= note: this error originates in the attribute macro `mockall::automock` (in Nightly builds, run with -Z macro-backtrace for more info)
The error[E0658]: C-variadic functions are unstable error is actually coming from the macro-generated code, not the original ffi declaration:
Expanded macro
// Recursive expansion of automock macro// ======================================pubmod ffi {extern"C"{pubfnvariadic(a:u32,b:u32, ...);}}#[allow(unused_imports)]#[doc = "Mock version of the `ffi` module"]pubmod mock_ffi {#[allow(missing_docs)]#[allow(clippy::too_many_arguments, clippy::indexing_slicing)]pubmod __variadic {usesuper::*;use::mockall::CaseTreeExt;use::std::sync::MutexGuard;use::std::{
boxed::Box,
mem,
ops::{DerefMut,Range},
sync::Mutex,
vec::Vec,};#[allow(clippy::unused_unit)]enumRfunc{Default,Expired,Mut(Box<dynFnMut(u32,u32) -> () + Send>),MutSt(::mockall::Fragile<Box<dynFnMut(u32,u32) -> ()>>),Once(Box<dynFnOnce(u32,u32) -> () + Send>),OnceSt(::mockall::Fragile<Box<dynFnOnce(u32,u32) -> ()>>),
_Phantom(Box<dynFn() + Send>),}implRfunc{fncall_mut(&mutself,a:u32,b:u32) -> std::result::Result<(),&'static str>{matchself{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(a, b)),Rfunc::MutSt(__mockall_f) => {::std::result::Result::Ok((__mockall_f.get_mut())(a, b))}Rfunc::Once(_) => {ifletRfunc::Once(mut __mockall_f) = mem::replace(self,Rfunc::Expired){::std::result::Result::Ok(__mockall_f(a, b))}else{
core::panicking::panic("internal error: entered unreachable code")}}Rfunc::OnceSt(_) => {ifletRfunc::OnceSt(mut __mockall_f) = mem::replace(self,Rfunc::Expired){::std::result::Result::Ok((__mockall_f.into_inner())(a, b))}else{
core::panicking::panic("internal error: entered unreachable code")}}Rfunc::_Phantom(_) => {
core::panicking::panic("internal error: entered unreachable code")}}}}impl std::default::DefaultforRfunc{fndefault() -> Self{Rfunc::Default}}enumMatcher{Always,Func(Box<dynFn(&u32,&u32) -> bool + Send>),FuncSt(::mockall::Fragile<Box<dynFn(&u32,&u32) -> bool>>),Pred(Box<(Box<dyn::mockall::Predicate<u32> + Send>,Box<dyn::mockall::Predicate<u32> + Send>,)>,),
_Phantom(Box<dynFn() + Send>),}implMatcher{#[allow(clippy::ptr_arg)]#[allow(clippy::ref_option)]fnmatches(&self,a:&u32,b:&u32) -> bool{matchself{Matcher::Always => true,Matcher::Func(__mockall_f) => __mockall_f(a, b),Matcher::FuncSt(__mockall_f) => (__mockall_f.get())(a, b),Matcher::Pred(__mockall_pred) => {[__mockall_pred.0.eval(a), __mockall_pred.1.eval(b)].iter().all(|__mockall_x| *__mockall_x)}
_ => core::panicking::panic("internal error: entered unreachable code"),}}}implDefaultforMatcher{#[allow(unused_variables)]fndefault() -> Self{Matcher::Always}}impl::std::fmt::DisplayforMatcher{fnfmt(&self,__mockall_fmt:&mut::std::fmt::Formatter<'_>) -> ::std::fmt::Result{matchself{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!("{}, {}",
__mockall_p.0,
__mockall_p.1,)),
_ => core::panicking::panic("internal error: entered unreachable code"),}}}#[doc = r" Holds the stuff that is independent of the output type"]structCommon{matcher:Mutex<Matcher>,seq_handle:Option<::mockall::SeqHandle>,times:::mockall::Times,}impl std::default::DefaultforCommon{fndefault() -> Self{Common{matcher:Mutex::new(Matcher::default()),seq_handle:None,times:::mockall::Times::default(),}}}implCommon{fncall(&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({}) {}","variadic",
desc,
m
));};});self.verify_sequence(desc);if::mockall::ExpectedCalls::TooFew != self.times.is_satisfied(){self.satisfy_sequence()}}fnin_sequence(&mutself,__mockall_seq:&mut::mockall::Sequence) -> &mutSelf{{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}fnis_done(&self) -> bool{self.times.is_done()}#[allow(clippy::ptr_arg)]#[allow(clippy::ref_option)]fnmatches(&self,a:&u32,b:&u32) -> bool{self.matcher.lock().unwrap().matches(a, b)}#[doc = r" Forbid this expectation from ever being called."]fnnever(&mutself){self.times.never();}fnsatisfy_sequence(&self){ifletSome(__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."]fntimes<MockallR>(&mutself,__mockall_r:MockallR)whereMockallR:Into<::mockall::TimesRange>,{self.times.times(__mockall_r)}fnwith<MockallMatcher0:::mockall::Predicate<u32> + Send + 'static,MockallMatcher1:::mockall::Predicate<u32> + Send + 'static,>(&mutself,a:MockallMatcher0,b:MockallMatcher1,){letmut __mockall_guard = self.matcher.lock().unwrap();*__mockall_guard.deref_mut() = Matcher::Pred(Box::new((Box::new(a),Box::new(b))));}fnwithf<MockallF>(&mutself,__mockall_f:MockallF)whereMockallF:Fn(&u32,&u32) -> bool + Send + 'static,{letmut __mockall_guard = self.matcher.lock().unwrap();*__mockall_guard.deref_mut() = Matcher::Func(Box::new(__mockall_f));}fnwithf_st<MockallF>(&mutself,__mockall_f:MockallF)whereMockallF:Fn(&u32,&u32) -> bool + 'static,{letmut __mockall_guard = self.matcher.lock().unwrap();*__mockall_guard.deref_mut() =
Matcher::FuncSt(::mockall::Fragile::new(Box::new(__mockall_f)));}fnverify_sequence(&self,desc:&str){ifletSome(__mockall_handle) = &self.seq_handle{
__mockall_handle.verify(desc)}}}implDropforCommon{fndrop(&mutself){if !::std::thread::panicking(){let desc = alloc::__export::must_use({let res = alloc::fmt::format(alloc::__export::format_args!("{}",self.matcher.lock().unwrap()));
res
});matchself.times.is_satisfied(){::mockall::ExpectedCalls::TooFew => {{
core::panicking::panic_fmt(core::const_format_args!("{}: Expectation({}) called {} time(s) which is fewer than expected {}","variadic",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 {}","variadic",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."]pubstructExpectation{common:Common,rfunc:Mutex<Rfunc>,}#[allow(clippy::unused_unit)]implExpectation{#[doc = r" Call this [`Expectation`] as if it were the real method."]#[doc(hidden)]pubfncall(&self,a:u32,b:u32) -> (){use::mockall::{ViaDebug,ViaNothing};self.common.call(&alloc::__export::must_use({let res = alloc::fmt::format(alloc::__export::format_args!("mock_ffi::variadic({:?}, {:?})",(&&::mockall::ArgPrinter(&a)).debug_string(),(&&::mockall::ArgPrinter(&b)).debug_string()));
res
}));self.rfunc.lock().unwrap().call_mut(a, b).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({}) {}","variadic",
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)]pubfnreturn_const<MockallOutput>(&mutself,__mockall_c:MockallOutput) -> &mutSelfwhereMockallOutput:Clone + Into<()> + Send + 'static,{self.returning(move |a, b| __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)]pubfnreturn_const_st<MockallOutput>(&mutself,__mockall_c:MockallOutput,) -> &mutSelfwhereMockallOutput:Clone + Into<()> + 'static,{self.returning_st(move |a, b| __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."]pubfnreturn_once<MockallF>(&mutself,__mockall_f:MockallF) -> &mutSelfwhereMockallF:FnOnce(u32,u32) -> () + Send + 'static,{{letmut __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."]pubfnreturn_once_st<MockallF>(&mutself,__mockall_f:MockallF) -> &mutSelfwhereMockallF:FnOnce(u32,u32) -> () + 'static,{{letmut __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."]pubfnreturning<MockallF>(&mutself,__mockall_f:MockallF) -> &mutSelfwhereMockallF:FnMut(u32,u32) -> () + Send + 'static,{{letmut __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."]pubfnreturning_st<MockallF>(&mutself,__mockall_f:MockallF) -> &mutSelfwhereMockallF:FnMut(u32,u32) -> () + 'static,{{letmut __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)."]pubfnin_sequence(&mutself,__mockall_seq:&mut::mockall::Sequence) -> &mutSelf{self.common.in_sequence(__mockall_seq);self}fnis_done(&self) -> bool{self.common.is_done()}#[doc = r" Validate this expectation's matcher."]#[allow(clippy::ptr_arg)]#[allow(clippy::ref_option)]fnmatches(&self,a:&u32,b:&u32) -> bool{self.common.matches(a, b)}#[doc = r" Forbid this expectation from ever being called."]pubfnnever(&mutself) -> &mutSelf{self.common.never();self}#[doc = r" Create a new, default, [`Expectation`](struct.Expectation.html)"]pubfnnew() -> Self{Self::default()}#[doc = r" Expect this expectation to be called exactly once. Shortcut for"]#[doc = r" [`times(1)`](#method.times)."]pubfnonce(&mutself) -> &mutSelf{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(..)`"]pubfntimes<MockallR>(&mutself,__mockall_r:MockallR) -> &mutSelfwhereMockallR: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."]pubfnwith<MockallMatcher0:::mockall::Predicate<u32> + Send + 'static,MockallMatcher1:::mockall::Predicate<u32> + Send + 'static,>(&mutself,a:MockallMatcher0,b:MockallMatcher1,) -> &mutSelf{self.common.with(a, b);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))`."]pubfnwithf<MockallF>(&mutself,__mockall_f:MockallF) -> &mutSelfwhereMockallF:Fn(&u32,&u32) -> 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`."]pubfnwithf_st<MockallF>(&mutself,__mockall_f:MockallF) -> &mutSelfwhereMockallF:Fn(&u32,&u32) -> bool + 'static,{self.common.withf_st(__mockall_f);self}}implDefaultforExpectation{fndefault() -> 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)]pubstructExpectations(Vec<Expectation>);implExpectations{#[doc = r" Verify that all current expectations are satisfied and clear"]#[doc = r" them."]pubfncheckpoint(&mutself) -> std::vec::Drain<Expectation>{self.0.drain(..)}#[doc = r" Create a new expectation for this method."]pubfnexpect(&mutself) -> &mutExpectation{self.0.push(Expectation::default());let __mockall_l = self.0.len();&mutself.0[__mockall_l - 1]}pubconstfnnew() -> Self{Self(Vec::new())}}implDefaultforExpectations{fndefault() -> Self{Expectations::new()}}implExpectations{#[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."]pubfncall(&self,a:u32,b:u32) -> Option<()>{self.0.iter().find(|__mockall_e| {
__mockall_e.matches(&a,&b) && (!__mockall_e.is_done() || self.0.len() == 1)}).map(move |__mockall_e| __mockall_e.call(a, b))}}#[doc(hidden)]pubfnget_expectations() -> &'static ::std::sync::Mutex<Expectations>{staticEXPECTATIONS:::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."]pubstructExpectationGuard<'__mockall_lt>{guard:MutexGuard<'__mockall_lt,Expectations>,i:usize,}#[allow(clippy::unused_unit)]impl<'__mockall_lt>ExpectationGuard<'__mockall_lt>{#[doc(hidden)]pubfnnew(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)"]pubfnin_sequence(&mutself,__mockall_seq:&mut::mockall::Sequence,) -> &mutExpectation{self.guard.0[self.i].in_sequence(__mockall_seq)}#[doc = r" Just like"]#[doc = r" [`Expectation::never`](struct.Expectation.html#method.never)"]pubfnnever(&mutself) -> &mutExpectation{self.guard.0[self.i].never()}#[doc = r" Just like"]#[doc = r" [`Expectation::once`](struct.Expectation.html#method.once)"]pubfnonce(&mutself) -> &mutExpectation{self.guard.0[self.i].once()}#[doc = r" Just like"]#[doc = r" [`Expectation::return_const`](struct.Expectation.html#method.return_const)"]pubfnreturn_const<MockallOutput>(&mutself,__mockall_c:MockallOutput,) -> &mutExpectationwhereMockallOutput: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)"]pubfnreturn_const_st<MockallOutput>(&mutself,__mockall_c:MockallOutput,) -> &mutExpectationwhereMockallOutput: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)"]pubfnreturning<MockallF>(&mutself,__mockall_f:MockallF) -> &mutExpectationwhereMockallF:FnMut(u32,u32) -> () + 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)"]pubfnreturn_once<MockallF>(&mutself,__mockall_f:MockallF) -> &mutExpectationwhereMockallF:FnOnce(u32,u32) -> () + 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)"]pubfnreturn_once_st<MockallF>(&mutself,__mockall_f:MockallF) -> &mutExpectationwhereMockallF:FnOnce(u32,u32) -> () + '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)"]pubfnreturning_st<MockallF>(&mutself,__mockall_f:MockallF) -> &mutExpectationwhereMockallF:FnMut(u32,u32) -> () + 'static,{self.guard.0[self.i].returning_st(__mockall_f)}#[doc = r" Just like"]#[doc = r" [`Expectation::times`](struct.Expectation.html#method.times)"]pubfntimes<MockallR>(&mutself,__mockall_r:MockallR) -> &mutExpectationwhereMockallR:Into<::mockall::TimesRange>,{self.guard.0[self.i].times(__mockall_r)}#[doc = r" Just like"]#[doc = r" [`Expectation::with`](struct.Expectation.html#method.with)"]pubfnwith<MockallMatcher0:::mockall::Predicate<u32> + Send + 'static,MockallMatcher1:::mockall::Predicate<u32> + Send + 'static,>(&mutself,a:MockallMatcher0,b:MockallMatcher1,) -> &mutExpectation{self.guard.0[self.i].with(a, b)}#[doc = r" Just like"]#[doc = r" [`Expectation::withf`](struct.Expectation.html#method.withf)"]pubfnwithf<MockallF>(&mutself,__mockall_f:MockallF) -> &mutExpectationwhereMockallF:Fn(&u32,&u32) -> 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)"]pubfnwithf_st<MockallF>(&mutself,__mockall_f:MockallF) -> &mutExpectationwhereMockallF:Fn(&u32,&u32) -> 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"]pubstructContext{_phantom:::std::marker::PhantomData<Box<dynFn() + Send>>,}implContext{#[doc = r" Verify that all current expectations for this method are"]#[doc = r" satisfied and clear them."]pubfncheckpoint(&self){Self::do_checkpoint()}#[doc(hidden)]pubfndo_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"]pubfnexpect<'__mockall_lt>(&self) -> ExpectationGuard<'__mockall_lt>{ExpectationGuard::new(get_expectations().lock().unwrap())}}implDefaultforContext{fndefault() -> Self{Context{_phantom: std::marker::PhantomData,}}}implDropforContext{fndrop(&mutself){if::std::thread::panicking(){let _ = get_expectations().lock().map(|mut g| g.checkpoint().collect::<Vec<_>>());}else{Self::do_checkpoint();}}}}#[no_mangle]pubunsafeextern"C-unwind"fnvariadic(a:u32,b:u32, ...){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::variadic({:?}, {:?})",(&&::mockall::ArgPrinter(&a)).debug_string(),(&&::mockall::ArgPrinter(&b)).debug_string())));
res
});{let __mockall_guard = __variadic::get_expectations().lock().unwrap();
__mockall_guard.call(a, b)}.expect(&no_match_msg)}#[doc = "Create a [`Context`](__variadic/struct.Context.html) for mocking the `variadic` method"]pubfnvariadic_context() -> __variadic::Context{
__variadic::Context::default()}#[doc = r" Verify that all current expectations for every function in"]#[doc = r" this module are satisfied and clear them."]pubfncheckpoint(){{let __mockall_timeses = __variadic::get_expectations().lock().unwrap().checkpoint().collect::<Vec<_>>();}}}
The text was updated successfully, but these errors were encountered:
wmmc88
added a commit
to wmmc88/minimal-repros
that referenced
this issue
Nov 20, 2024
I have a bindgen generated ffi function that uses variadic arguments. This is allowed on stable rust for extern C functions. The code that
automock
generates fails to compile for stable rust.Code Example:
Error:
The
error[E0658]: C-variadic functions are unstable
error is actually coming from the macro-generated code, not the original ffi declaration:Expanded macro
The text was updated successfully, but these errors were encountered: