Rust: Box Is a Unique Type
blog.nilstrieb.dev
Rust: Box Is a Unique Type
1–10 of 56 posts
Re: Rust: Box Is a Unique Type
#2Now, as for the article, I don't really follow their argument. Box owns its contents. Hence why it drops its contents afterwards, unlike &T. If someone needs this aliasable box type, they should define a different DropPtr. "It's just a pointer" can also be said of `&T` & `&mut T` (where T: Sized)
Re: Rust: Box Is a Unique Type
#3First, Box lacks some ergonomics, it's a pain dealing with when matching Now, as for the article, I don't really follow their argument. Box owns its contents. Hence why it drops its contents afterwards, unlike &T. If someone needs this aliasable box type, they should define a different DropPtr. "It's just a pointer" can also be said of `&T` & `&mut T` (where T: Sized)
But that's the point: you can assign your &T to a pointer and know that it won't be invalidated by merely moving the &T. That is not true for Box.
Re: Rust: Box Is a Unique Type
#4First, Box lacks some ergonomics, it's a pain dealing with when matching Now, as for the article, I don't really follow their argument. Box owns its contents. Hence why it drops its contents afterwards, unlike &T. If someone needs this aliasable box type, they should define a different DropPtr. "It's just a pointer" can also be said of `&T` & `&mut T` (where T: Sized)
Agreed, but this should become better once box_patterns is stable
https://doc.rust-lang.org/beta/unstable-book/language-featur...
Re: Rust: Box Is a Unique Type
#5> While it can be argued that box is like a T, but on the heap, and therefore moving it should invalidate pointers, since moving T definitely has to invalidate pointers to it, this comparison doesn’t make sense to me. While Box usually behaves like a T, it’s just a pointer.
The "it's just a pointer" argument is moot (and pointers have nothing to do with the issue, it's a question of exclusive ownership and nothing more). It's a high-level object (i.e. not a pointer) to which rust's very clear aliasing and single name rules apply. Thou shalt not have multiple live T that point to the same memory address. QED.
It's the same reason this code is unsafe:
struct Foo;
impl Foo {
fn bar(&mut self) { ... }
fn baz(&self) { ... }
}
fn get_foo() -> &mut Foo {
unsafe { static mut FOO_SINGLETON: Foo = Foo; }
unsafe { &mut FOO_SINGLETON }
}
Here we don't even have a pointer, only statically allocated data stored in .TEXT. We don't even create a second top-level instance of Foo, only an &mut reference to it. But it's unsafe because the compiler can't know whether or not it has exclusive access.(As a refresher, in terms of "strength" of ownership from the most exclusively owned to the least so, it would go T -> &mut T -> &T.)
Re: Rust: Box Is a Unique Type
#6First, Box lacks some ergonomics, it's a pain dealing with when matching Now, as for the article, I don't really follow their argument. Box owns its contents. Hence why it drops its contents afterwards, unlike &T. If someone needs this aliasable box type, they should define a different DropPtr. "It's just a pointer" can also be said of `&T` & `&mut T` (where T: Sized)
> First, Box lacks some ergonomics, it's a pain dealing with when matching Agreed, but this should become better once box_patterns is stable https://doc.rust-lang.org/beta/unstable-book/language-featur...
Re: Rust: Box Is a Unique Type
#7Earlier quoted context omitted.
> First, Box lacks some ergonomics, it's a pain dealing with when matching Agreed, but this should become better once box_patterns is stable https://doc.rust-lang.org/beta/unstable-book/language-featur...
That feature is almost assuredly not going to land on stable but the more general "deref_patterns" which would allow matching on boxed values, as well as on `Vec`s and `String`s will. It is not anywhere close to finished, but I am convinced it will land.
Re: Rust: Box Is a Unique Type
#8Earlier quoted context omitted.
> First, Box lacks some ergonomics, it's a pain dealing with when matching Agreed, but this should become better once box_patterns is stable https://doc.rust-lang.org/beta/unstable-book/language-featur...
That feature is almost assuredly not going to land on stable but the more general "deref_patterns" which would allow matching on boxed values, as well as on `Vec`s and `String`s will. It is not anywhere close to finished, but I am convinced it will land.
Here's the proposal for anyone else who's curious https://hackmd.io/4qDDMcvyQ-GDB089IPcHGg
Re: Rust: Box Is a Unique Type
#9It feels like the Rust team is a bit wary of introducing other optimizations for fear of breaking unsafe code that has lurking UB, but it's better to start working on fixing these problems _now_ rather than get stuck in the present state of limbo. It's only going to get harder to fix incorrect code (which we see an example of in this particular post).
Honestly Miri is a superpower and it needs to be the priority of the Rust team to stabilize it. There's nothing inherently wrong with unsafe code: it's unsound code that's the problem, and we have the tools to prevent this exact problem from the article.
Re: Rust: Box Is a Unique Type
#10It’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