Shared access: both as concrete type and as trait

#1

Hello. I have a trait T and a Struct S implementing T. I also have an instance of S, s, which I’m accessing as Arc<RwLock<Box<dyn T>>. Can I somehow simultaneously access it as Arc<RwLock<S>>? Some of the accesses know the concrete type, and some don’t. In a sense I want to share the lock, but allow access both as trait and concrete type. I can’t figure out how to do it. I guess I could use downcasting à la https://stackoverflow.com/questions/33687447/how-to-get-a-reference-to-a-concrete-type-from-a-trait-object, but that feels like a workaround when some code paths already know the concrete type.

0 Likes

#2

A Arc<RwLock<S>> can coerce into a Arc<RwLock<dyn T>>, so you can just store the concrete version and if needed pass it to a function that needs the dyn version and it will coerce to the dyn version for you.

0 Likes

#3

@KrishnaSannasi Oh, that’s great! I can’t seem to get it to work though, could you help out? My naive attempt: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8bcf3954d727fcdec1f1ee965af930f2

0 Likes

#4

Remove the Box, sorry I made a mistake when copying. Fixed it now. A Arc<RwLock<S>> can coerce into a Arc<RwLock<dyn T>>, not a Arc<RwLock<Box<dyn T>>>

0 Likes

#5

Thank you. That works. So one doesn’t need Box anymore now with dyn?

0 Likes

#6

No, it’s just that RwLock, like many other pointer lile types in Rust have a ?Sized bound on its generic parameter, this means that it can handle unsized types like trait objects.

Other notable examples include Arc, Rc, Box, Cell, RefCell, Mutex, & and &mut. And you can even coerce nested pointer like types.

1 Like

#7

Interesting. I’ll investigate. Thank you!

1 Like

#8

Worth noting that RwLock isn’t a pointer type. It stores its data directly inside the struct, so if T is unsized, so is RwLock<T>. The only reason Arc<RwLock<dyn Trait>> works is because Arc is a pointer type, so it can handle the unsized RwLock<dyn Trait>.

1 Like

#9

Yes, I forgot about that, same thing with Mutex, Cell, and RefCell, they can only be used in conjunction with a pointer like type

0 Likes