rust-lang-nursery / lazy-static.rs

A small macro for defining lazy evaluated static variables in Rust.
Apache License 2.0
1.91k stars 111 forks source link

Expected struct <FOOBAR>, found <OTHER_LAZY_STATIC_REF> #119

Closed jens1o closed 5 years ago

jens1o commented 6 years ago
lazy_static! {
    static ref FIREFOX_REGEX: Regex = { Regex::new(r"firefox/([\d\.]+)").unwrap() };
    static ref EDGE_REGEX: Regex = { Regex::new(r"edge/(\d{2}\.\d+)").unwrap() };
    static ref BROWSER_LIST: HashMap<&'static str, Regex> = {
        let m: HashMap<&'static str, Regex> = HashMap::new();

        m.insert("Firefox", FIREFOX_REGEX);
        // -----------------^^^^^^^^^^^^^
        // expected struct Regex, found struct FIREFOX_REGEX
        m.insert("Edge", EDGE_REGEX);
        // --------------^^^^^^^^^^
        // expected struct Regex, found struct EDGE_REGEX

        m
    };
}

I don't understand that. I don't understand that.

KodrAus commented 6 years ago

Hi @jens1o! the problem here is that each static ref is actually lying about its type. So FIREFOX_REGEX and EDGE_REGEX aren't Regexes, they're some type that we can dereference to a Regex. To add them to your browser list we need to dereference them. So with some tweaking we can make your example work:

lazy_static! {
    static ref FIREFOX_REGEX: Regex = { Regex::new(r"firefox/([\d\.]+)").unwrap() };
    static ref EDGE_REGEX: Regex = { Regex::new(r"edge/(\d{2}\.\d+)").unwrap() };
    static ref BROWSER_LIST: HashMap<&'static str, &'static Regex> = {
        let mut m = HashMap::new();

        m.insert("Firefox", &*FIREFOX_REGEX);
        m.insert("Edge", &*EDGE_REGEX);

        m
    };
}
jens1o commented 6 years ago

Oh okay. Is it possible to make the error message more clearer? Thanks!

KodrAus commented 6 years ago

It's a bit confusing, isn't it. I think the best way we could improve the error messages here is by requiring the actual type name in the static. That way you know what you're looking at. This is something @matklad's alternative API for statics with complex initialisation does.

KodrAus commented 5 years ago

Thanks again for the input @jens1o!

I'll go ahead and close this one now as something that's solved by #111, depending on what direction that goes in.