Arc-or-&'static reference

There are a number of places in my code where it would be useful to have a pointer type that is both

  • refcounted, and
  • able to be constructed as a static value.

That is, it could be defined as the Cow-like type

enum Ptr<T: ?Sized> {
    Static(&'static T),
    Arc(alloc::sync::Arc<T>),
}

or, perhaps more efficiently, an Arc-like that internally allows for static pointers via some sort of “refcount = ∞” state.

Obviously the enum form is fairly simple to write, but is there a library that provides something like this type already, so I don't have to? The library must be no_std compatible. (Yes, Arc exists outside of std.)

I'm just leaving this here, please don't use it Rust Playground

1 Like

I don't know of a crate that does this, but I like the idea in theory.

It seems like any API to interact with the pointee will inevitably have to return Arc<T>, though. So, there might not be any benefit to the enum over just using Arc.

Ptr::try_static() -> Option<&'static T> is a counterexample that shows returning Arc<T> (or something that can be transformed into Arc<T>) is not necessary, but it's of limited use AFAICT.

My use cases involve things like used-only-as-immutable results from lookups that might be large complex data (though in other cases it might be just str). So, typically there is no mutation creating new Arcs; it's pure functions returning existing ones, and field accesses into the pointees. For example:

static OUT_OF_BOUNDS_FOO: Ptr<Foo> = Ptr::static(Foo { ... });

pub fn get_foo(&self, index: usize) -> &Ptr<Foo> {
    if let ... {
        // return an arc-type `Ptr` from internal storage
    } else {
        &OUT_OF_BOUNDS_FOO
    }
}

This way the caller can clone() the Ptr if they want to keep it longer than the self lifetime.

:eyes:

Yeah, looks good to me! Rust Playground

Folks, I'm looking for library recommendations (or alternatives), not “yes this idea will work”. I'm trying not to have to reinvent another wheel.

To be clear, I never suspected it would not work. But I still don't know of such a library that already exists. Sorry to derail your thread.

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.