rusttype-erasureself-reference

Type-erase owner in self-referential crates


I have a struct, and want to define another struct that references its field.

struct Tweet {
  text: Text
}

#[ouroboros::self_referencing]
struct BorrowedText<Owner> {
  owner: Arc<Owner>, // make sure it's not deallocated while borrowing
  #[borrows(owner)]
  borrowed: &'this Text,
}

There can be many types that have Text as a member. To prevent BorrowedText<T> from creating too many types, I would like to erase the owner type.

#[ouroborus::self_referencing]
struct BorrowedText {
  owner: Arc<dyn Any>, // make sure it's not deallocated while borrowing
  #[borrows(owner)]
  borrowed: &'this Text,
}

For this I need to get &Text from owner: Arc<Tweet> and then upcast owner to Arc<dyn Any>. I couldn't make this work with ouroborus or owning_ref API (owning_ref even has dedicated erased-types like ErasedBoxRef).

Is there any way to achieve this with ErasedBoxRef or other API? Or can I just safely do the below without the need for self-referential crates?

BorrowedText { owner: owner.clone(), borrowed: unsafe { (&owner.text) as (*const Text) } }

Solution

  • Manually unsafe-transmuting worked without a cost of dynamic downcast

    fn f(owner: Arc<Tweet>) {
      let borrowed = unsafe { std::mem::transmute::<&'_ _, &'static _>(&owner.text) };
    
      BorrowedText {
        owner: owner as Arc<dyn Send + Sync>,
        borrowed,
      }
    }