3 ms·
The biggest annoying magic I found with respect to Box (and other std containers like Rc) is that they’re the only ones capable of storing fat dyn pointers. You
by vlovich123 3y ago
The biggest annoying magic I found with respect to Box (and other std containers like Rc) is that they’re the only ones capable of storing fat dyn pointers. You can’t construct a hybrid_rc::Rc<dyn Trait> like you can with Box/Rc.
It’s annoying magic like that that bothers me.
Another example is async lifetimes - it’s frequently hard to properly express the lifetime of a borrow resulting in choices of an unnecessary Box::pin, unsafe or even both. Here’s an example i ran into recently and the author’s challenges there are similar to the one’s I’ve ran into in my own codebase [1]
Or how about bridging poll-based futures and async (eg if within my poll interface I want to call an async method). It’s weird how there’s a world of difference between the implicit future generated by async and an explicit type implementing Future. I understand the similarity to named function vs closure but I’m finding the distinction to have far more annoying sharp edges than I’ve experienced with closures.
The tooling around non-trivial programs is also unfortunate - working with an io_uring async runtime and Miri fails to start (noted limitation). Valgrind deadlocks for some reason as well which means that only asan’s more limited techniques are usable.
My point is that soundness issues writing unsafe code is important but a niche topic vs what I’ve experienced writing a substantial program in Rust (~40k lines of code so far). It’s doable but I find myself still fighting with the language just a bit too much.
Hopefully it’s completely different teams responsible for these kinds of work but, if not, I’d vote for stabilizing some of the ergonomic magic that std has access to and improving the borrow checker to recognize more definitely safe constructs so that users don’t need to do annoying hoop jumping. I know the std magic I referenced is being worked on but as with all things rust it’s impossible to predict what actually gets stabilized and when with the exception of marquee tentpole features they talk about on the blog.
[1] https://github.com/someguynamedjosh/ouroboros/issues/112 https://github.com/someguynamedjosh/ouroboros/issues/112
- LegionMammal978 3y ago> The biggest annoying magic I found with respect to Box (and other std containers like Rc) is that they’re the only ones capable of storing fat dyn pointers. You can’t construct a hybrid_rc::Rc<dyn Trait> like you can with Box/Rc. It's perfectly possible to make a container capable of storing trait objects: just define the type parameter as <T: ?Sized>. The main issue is that unlike Box/Rc, the compiler won't give you an automatic coercion from MyRc<Type> to MyRc<dyn Trait>, so you have to write a method to explicitly perform that cast. It just isn't common for many existing third-party containers to support !Sized objects, since it takes tedious unsafe code to manipulate them in memory.
- vlovich123 3y agoSorry - that's exactly what I meant. The automatic conversion from <T> to <dyn Trait>.
- mjw1007 3y agoImproving this is the subject of RFC #3621 [1], which appeared today. [1]: https://github.com/Darksonn/rfcs/blob/derive-smart-pointer/text/3621-derive-smart-pointer.md https://github.com/Darksonn/rfcs/blob/derive-smart-pointer/t...
- gpm 3y ago> The biggest annoying magic I found with respect to Box (and other std containers like Rc) is that they’re the only ones capable of storing fat dyn pointers. You can’t construct a hybrid_rc::Rc<dyn Trait> like you can with Box/Rc. Anything can store fat dyn pointers, they're just like any other type in that regards. Constructing them for a specific trait is easy and possible on stable (e.g. adding a `as_debug(MyBox<T>) -> MyBox<dyn Debug>` method). Making it possible to construct them for any trait is special to the built in pointers... on stable. On nightly with unstable features it's possible (and easy) to make any smart pointer type do this. Code examples: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=666ddb5abc3902867ac179c148cb22d4 https://play.rust-lang.org/?version=nightly&mode=debug&editi...
- vlovich123 3y agoI should have taken more time on that and miswrote. Converting MyBox<T> to MyBox<dyn Trait> for arbitrary traits is only possible on nightly.