Pain-free self-referential pinned types - selfref (nightly only)

Thanks to GATs, we were able to make a safe and fairly painless wrapper around self-referential pinned types. With a few ergonomics tradeoffs, due to current rust limitations.

https://crates.io/crates/selfref

We've been using them ourselves and, they are pretty cool, tho the lifetimes do have a tendency to propagate. So you end up with struct Plugin<'plugin, 'plugin_host, 'app> { ... } fairly easily.

Features:

  • #![no_std]. Additionally: no alloc.
  • Supports &'a Cell<SelfRef<'a>>, &'a RefCell<SelfRef<'a>>, &'a UnsafeCell<SelfRef<'a>>. This is unlike most/every other solution(s) out there, which don't even work with &'a SelfRef<'a>.
  • Attempts to prevent UB. (This seems to be correct so far.)
  • Uses the fairly modern Pin stuff.
  • Accepts arbitrary lifetimes, and even nested self-referential structs (where the inner one contains a direct reference to the outer one).
  • Only 126 LLOC, at up to 80 columns each. (The published code as of 0.1.2 is 123 LLOC but contains 2 lines that exceed 80 columns. This expands to 126 LLOC when following the 80 columns guideline.)

Drawbacks:

  • Depends on unstable GATs. (&'a Cell<SelfRef<'a>> doesn't even work with nightlies from a month ago!)
  • Somewhat more verbose than alternatives.
  • Doesn't have as much real-world stress-testing as alternatives.

Some comparisons with other self-referential crates:

Benefits of selfref against ouroboros:

  • Far simpler.
  • No proc macros.
  • No std.
  • Self-ref fields can borrow multiple fields.
  • Self-ref fields can borrow the whole struct.

Benefits of selfref against self_cell:

  • No alloc.
  • Still far simpler, somehow.
  • Self-ref fields can borrow the whole struct.

Benefits of selfref against rental:

  • selfref is maintained.
  • No proc macros.
  • Once again, selfref is far simpler.
  • Ability to take completely arbitrary lifetimes. In fact, selfref pretty much has none of the limitations of rental - with a few ergonomics caveats.
  • Self-ref fields can borrow the whole struct.

Real world example:


This crate is MIT/Apache2 but we ask that you run your own GAnarchy instance if you choose to use this crate.

2 Likes

lmao we write all this up just to find we don't even need trait SelfRef. yay more LLOC shaving!

Heads up to everyone who wants to use this crate. It is licensed as GPLv3+.

6 Likes

we'd love to get this into std tbh.

Yeah, that's a deal-breaker to a very large number of people, including probably all companies.

So? It's open source.

Your comment sounds pejorative. Perhaps just warn users who want to distribute applications, but don't want their code to be open source?

And the ones who want to distribute their libraries under MIT or Apache license, too.

This is true, but lots of open source licenses have varying degrees of interoperability. Singling out GPL3 as something to be extra wary of smacks of FUD to me. Understanding the licensing implications of the code one uses is kind of fundamental to writing and distributing software.

I don't begrudge anyone releasing their software under any license they choose, although I much prefer copyleft licenses. Not that they do much to deter the corporate parasitism they were intended to combat. Large companies just take and use whatever they want anyway because they have armies of lawyers to prevent any real consequences of their actions.

I'm not sure if it was intended as "singling out GPL3". For me, it's more like "be wary - although most Rust crates are MIT/Apache, this one is more restrictive".

This, or there's just no one who at least attempts to prove them wrong in some specific cases?

6 Likes

I think the intent was to mostly guard people from accidental liability, or being accidentally forced to open up (in case of proprietary) or relicense their projects. Key word being accidental.
If so, that's why GPL was "singled out": it has that viral copyleft property. Like anything technological, I don't think that's good or bad in essence — but it is definitely something important to be aware of.

3 Likes

It's hard to say whether one would need to comply with the GPL when using this crate. After all, the whole crate gets optimized away when you build it, and crates that use it don't have to be GPL themselves (tho they do have to be GPL-compatible).

Nevertheless, we don't think anyone here is a lawyer.

It is also no longer GPL. Tho we'd appreciate if you ran your own GAnarchy instance when using this.