Strange behavior of visibility specifier of `static`s under `fn`'s scope

Consider this code snippet:

use std::sync::OnceLock;

pub(crate) fn get_sixty_nine() -> u64 {
    pub(crate) static SIXTY_NINE: OnceLock<u64> = OnceLock::new();
    *SIXTY_NINE.get_or_init(|| {
        println!("Init-ing");
        69
    })
}

fn main() {
    
    println!("{:?}", get_sixty_nine()); // prints 69
    println!("{:?}", get_sixty_nine()); // prints 69
    
    // Below doesn't compile!
    // println!("{:?}", SIXTY_NINE); 
    // println!("{:?}", crate::SIXTY_NINE);
    
}

Playground

Then, consider this line:

pub(crate) static SIXTY_NINE: OnceLock<u64> = OnceLock::new();

The pub(crate) actually means nothing because there is no way for anywhere in the crate to be able to refer to the static SIXTY_NINE that must exist somewhere (maybe .data segment, whatever, it is not important) but still have visibility specifier specified.

Just wondering if I am missing something here, perhaps there is a use? Or even more shocking, perhaps that there is a way to actually refer to this static SIXTY_NINE outside of get_sixty_nine()'s scope?

1 Like

Items declared inside of a function can't be referenced outside of said function. It doesn't matter what visibility you give it.

1 Like

Yeah, then the syntax pub(crate) should probably raise a warning at least? What do you think?

1 Like

There is a recent request for a clippy lint that warns agains useless visiblity on nested items[1]:


  1. The issue specifically references nested functions, but I don't see why the same lint wouldn't apply to other nested items as well. ↩︎

2 Likes

The existing nursery lint redundant_pub_crate could perhaps be generalized to cover this case as well (and possibly renamed)?

1 Like

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.