"A non-empty glob must import something with the glob's visibility" - uhhh, okay, but why?

This error message is exactly what it says on the tin.

mod module {
    // okay;  it's an empty glob
    pub use self::a::*;
    mod a {
        fn foo() {}
    }

    // ERROR: A non-empty glob must import something with the glob's visibility
    pub use self::b::*;
    mod b {
        fn foo() {}
        pub(super) fn bar() {}
    }

    // okay: there's a pub item
    pub use self::c::*;
    mod c {
        fn foo() {}
        pub(super) fn bar() {}
        pub fn baz() {}
    }
}

Is it just me or does this seem like, really arbitrary?


Encountered while trying to make a wrapper around a proc-macro-hack item macro that lets it be used multiple times.

#[macro_export]
macro_rules! unbox {
    (
        #![unbox(unique_id($unique_id:ident))]
        $($tt:tt)*
    ) => {
        // re-export whatever the user defines with the same visibility
        #[allow(unused)]
        pub use self::$unique_id::*;
        mod $unique_id {
            #[allow(unused)]
            use super::*;

            unbox_hack!{ $($tt)* }

            // HACK for "error: A non-empty glob must import something
            //  with the glob's visibility" in case the user didn't define
            //  anything that is `pub`
            #[doc(hidden)]
            #[allow(non_snake_case)]
            pub fn __a_thing_that_is_pub() { }
        }
    };
}
3 Likes

I also wonder what is the reason of this error.

This is indeed arbitrary. It could be a lint instead (allow-by-default, I think) against empty blob imports: triggering for both the first and second cases.

1 Like

Well, I think it's actually a valid error; there is a pub(crate) modifier on bar, so therefore it will try to expose it to mod module, but when you try to expose it to module::super, you end up getting an error because pub use exposes to ::self (module) and to ::self::super (whatever_is_outside), meaning that it has a conflicting requirement.
It can either expose to self (module) or to self::super (whatever_is_outside), but not both because it (bar) cannot be exposed to anyone outside of b::super (module). Therefore, we have an error.

But, truth be told, it is pretty odd that it doesn't just ignore it like it does in example c. Perhaps it is like @Yandros said and is more like a lint, except it's treated like an error by the compiler?