Lazy_static!() macro does not compile when using Self type parameter

How to fix the following program? This error originates inside the macro expansion: use of generic parameter form outer function. Self parameter seems to be causing it, but I do not see any way to avoid it. Any ideas?

#[macro_use]
extern crate lazy_static;

trait Core {
    fn foo() -> &'static str {
        "foo"
    }
}

trait Wrap : Core {
    fn foo() {
        lazy_static! {
            // the following line works, for example
            // static ref succeeds : String = format!("[{value}]", value = "foo");
            static ref fails : String = format!("[{value}]", value = <Self as Core>::foo());
        }
    }
}

struct Type {}
impl Core for Type {}
impl Wrap for Type {}

fn main() {
    <Type as Wrap>::foo()
}

The problem is than a static inside a function or impl can't depend on generic parameters to the outer function or impl. The same is also true for other inner items.

One workaround would be to implement Wrap::foo separately for each type that implements Wrap, perhaps using a macro. It's not great, but I'm not aware of a better way.

Past discussion of a similar problem:

I have stripped the expanded macro to only use the generic Lazy struct that internally delegates to spin::Once. By avoiding nested structs, which are completely isolated from the outer variables, I lost some of the functionality provided by lazy_static! out of the box, but seems like I got what I wanted :smile:

  • I used Self to delegate to Core implementation;
  • on first call to Wrap::foo the closure that I am using inside the get() method of the Lazy struct is used to initialize a spin::Once. On further calls, Lazy returns the initialized instance.
trait Core {
    fn foo() -> &'static str {
        "foo"
    }
}

trait Wrap : Core {
    fn foo() -> &'static str {
        static LAZY: ::lazy_static::lazy::Lazy<String> =
            ::lazy_static::lazy::Lazy::INIT;
        &*LAZY.get( || {
            format!("{}", <Self as Core>::foo())
        })
    }
}