#rc #arc #reference-counting #no-std

no-std archery

Abstract over the atomicity of reference-counting pointers

6 releases (breaking)

0.4.0 Jun 22, 2020
0.3.0 Sep 2, 2019
0.2.1 Mar 4, 2019
0.1.0 Feb 25, 2019
0.0.0 Feb 20, 2019

#216 in Concurrency

Download history 3322/week @ 2022-10-09 3316/week @ 2022-10-16 3221/week @ 2022-10-23 3545/week @ 2022-10-30 3596/week @ 2022-11-06 3245/week @ 2022-11-13 3161/week @ 2022-11-20 3825/week @ 2022-11-27 3206/week @ 2022-12-04 3134/week @ 2022-12-11 2233/week @ 2022-12-18 1029/week @ 2022-12-25 1771/week @ 2023-01-01 3568/week @ 2023-01-08 3511/week @ 2023-01-15 4110/week @ 2023-01-22

13,015 downloads per month
Used in 31 crates (4 directly)

MPL-2.0 license

876 lines

Build Status Code Coverage crates.io Downloads Github stars Documentation License


Archery is a rust library that offers a way to abstraction over Rc and Arc smart pointers. This allows you to create data structures where the pointer type is parameterizable, so you can avoid the overhead of Arc when you don’t need to share data across threads.

In languages that supports higher-kinded polymorphism this would be simple to achieve without any library, but rust does not support that yet. To mimic higher-kinded polymorphism Archery implements the approach suggested by Joshua Liebow-Feeser in “Rust has higher kinded types already… sort of”. While other approaches exist, they seem to always offer poor ergonomics for the user.


To use Archery add the following to your Cargo.toml:

archery = "<version>"

Using Archery

Archery defines a SharedPointer that receives the kind of pointer as a type parameter. This gives you a convenient and ergonomic way to abstract the pointer type away.


Declare a data structure with the pointer kind as a type parameter bounded by SharedPointerKind:

use archery::*;

struct KeyValuePair<K, V, P: SharedPointerKind> {
    pub key: SharedPointer<K, P>,
    pub value: SharedPointer<V, P>,

impl<K, V, P: SharedPointerKind> KeyValuePair<K, V, P> {
    fn new(key: K, value: V) -> KeyValuePair<K, V, P> {
        KeyValuePair {
            key: SharedPointer::new(key),
            value: SharedPointer::new(value),

To use it just plug-in the kind of pointer you want:

let pair: KeyValuePair<_, _, RcK> =
    KeyValuePair::new("António Variações", 1944);

assert_eq!(*pair.value, 1944);


Currently it is not possible to have unsized types inside a SharedPointer. As a workaround you can put the unsized type inside a Box.

Alternative approaches

An alternative to the approach taken by Archery is to use traits with associated types to encode type-level functions. This has been suggested multiple times, but offers ugly ergonomics (see here and here).