Using mockall to return a boxed reference

Hi guys,

I'm new to Rust but have been really appreciating mockall's automock capabilities. I have however run into a stopping point where I can't seem to work out how to have automock return a boxed reference to another object (at least in this specific instance).

Reading the manual I believe I'm supposed to use return_const and so have something like this:

let mut compiler = get_compiler();
let literal_symbol = MockSymbol::new();
compiler.expect_symbol_ref().return_const(|symbol_id| Box::new(&literal_symbol) );

#[cfg_attr(test, automock)]
pub trait CompilerControls {
fn symbol_ref<'a>(&'a self, id: &str) -> Box<&'a dyn Symbol>;

I'm however receiving the following error:

the trait bound Box<&dyn traits::Symbol>: >From<[closure@src\compiler\ 367:88]> is not satisfied
the following implementations were found:
<Box<(dyn std::error::Error + 'a)> as From>
<Box<(dyn std::error::Error + 'static)> as From<&str>>
<Box<(dyn std::error::Error + 'static)> as From<Cow<'a, str>>>
<Box<(dyn std::error::Error + 'static)> as From>
and 25 others
required because of the requirements on the impl of Into<Box<&dyn traits::Symbol>>

Any idea what this means and how to resolve?

Many thanks

The error is saying that the compiler can't find a way to convert the closure into a Box, since return_all expects a value rather than a closure. To use a closure, use returning, i.e.:

compiler.expect_symbol_ref().returning(|symbol_id| Box::new(&literal_symbol) );

Also, there's no need to put a reference in a Box. Without it, you could do:


#[cfg_attr(test, automock)]
pub trait CompilerControls {
    fn symbol_ref<'a>(&'a self, id: &str) -> &'a dyn Symbol;

Thank you, sadly this still didn't work because the compiler was unable to cast the Box containing the concrete object to a Box containing the trait object. I instead pushed the issue onto the trait implementor by using the return type &Box<dyn Symbol>; instead.

Many thanks

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.