Live data from Hacker News

Rust: Box Is a Unique Type

blog.nilstrieb.dev

21–30 of 56 posts

Re: Rust: Box Is a Unique Type

#21
post #17

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 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, un…

> 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 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 ) -> MyBox…

I should have taken more time on that and miswrote. Converting MyBox to MyBox for arbitrary traits is only possible on nightly.

Re: Rust: Box Is a Unique Type

#22

>While we are many missing language features away from this being the case, the noalias case is also magic descended upon box itself, with no user code ever having access to it. I'm not sure why the author thinks there's magic behind Box. Box is not a special case of `noalias`. Run this snippet with miri and you'll see the same issue: https://play.rust-lang.org/?version=stable&mode=debug&editio... You don't see an as…

Well, they work on the compiler, so that's one reason I guess. Also the fact that it's magic is no secret and this is not the only way in which it is (the most important is probably the DerefMove behaviour that's mentioned in the article, too). There's been many discussions around this in the past

Re: Rust: Box Is a Unique Type

#23
post #9

I strongly disagree with this article. Perhaps in the days before Miri it might have made sense, but it's pretty trivial right now to discover UB in unsafe code with a simple `cargo +nightly miri test` run. It 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 st…

This is why I firmly argue (and pretend) that references are not pointers. "References are pointers" results in the belief that references will behave like C pointers and results in things like this article.

At best they are a cousin of pointers.

I consider the fact that they are pointers an implementation detail, just like Box is a value with 'static samantics.

Re: Rust: Box Is a Unique Type

#24

One of the biggest struggles I have (and others have, judging from Stack Overflow) is how to generically handle accepting types of Box , Rc , T, Pin , &T, &mut T, etc etc. Of course you can write a function that is generic on > or something, but the moment you introduce function-coloring stuff like async, object safety, etc, things explode.

You just write an &T version and let everyone coerce their smart pointer into a reference on call?

Worst case you write your generic asref function and then immediately delegate to the &T version

Re: Rust: Box Is a Unique Type

#25

Earlier quoted context omitted.

Miri can't detect all UB, so I think it's still sensible to reduce the chance of writing it in the first place.

I'm not aware of any UB that can 1) be caused by unique pointer violations from Box and 2) are undetectable by Miri (assuming good code coverage), but I might be wrong about this.

Well for a start, if your tests don't cover that code then it can't possibly detect it.

Re: Rust: Box Is a Unique Type

#26
post #3
post #2

First, 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)

> It's just a pointer" can also be said of `&T` & `&mut T 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 .

Except is not the same thing? You can copy a reference, you can't copy a box (without having the T be copy as well).

A box is a pointer AND the storage at the same time. To move it means to move the storage as well, unlike a regular reference.

Re: Rust: Box Is a Unique Type

#27

Earlier quoted context omitted.

I'm not aware of any UB that can 1) be caused by unique pointer violations from Box and 2) are undetectable by Miri (assuming good code coverage), but I might be wrong about this.

Well for a start, if your tests don't cover that code then it can't possibly detect it.

This is trivially solved by putting code coverage and Miri into the same project, however.

Re: Rust: Box Is a Unique Type

#28

I have to disagree with the entire premise of the article. It's the fact that Box isn't unique that gives it this behavior. The author even says as much, but dismisses it because it gets in the way of their point: > 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 s…

The problem with this, as the article argues in detail, is that it leaves a hole in functionality that people need but offers no clear benefit in return.

A movable owning pointer that exposes its pointer-ness in its semantics is a useful tool when you're doing lower-level, sometimes-unsafe stuff with memory layout. The author points out that, because Box does not currently provide this functionality, there are crates in the ecosystem that step in to provide it instead. This middle ground between "raw pointers for everything" and "aliased XOR mutable" is an important thing to support.

This might be acceptable if there were some benefit to Box behaving this way. Perhaps if it actually made a difference for the optimizer? The benchmarks the author did seem to suggest otherwise- many mutations wind up going through a reborrowed `&mut T` anyway. Perhaps the conceptual model of "like a T but on the heap" is enough of a benefit? But being more permissive here doesn't change that model for safe code anyway.

The author dismissed this for much more concrete reasons than "it gets in the way of their point."

Re: Rust: Box Is a Unique Type

#29

Earlier quoted context omitted.

> 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 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 . The main issue is that unlike Box/Rc, the compiler won't give you an automatic coerci…

Sorry - that's exactly what I meant. The automatic conversion from to .

Improving this is the subject of RFC #3621 [1], which appeared today.

[1]: https://github.com/Darksonn/rfcs/blob/derive-smart-pointer/t...

Re: Rust: Box Is a Unique Type

#30
post #23
post #9

I strongly disagree with this article. Perhaps in the days before Miri it might have made sense, but it's pretty trivial right now to discover UB in unsafe code with a simple `cargo +nightly miri test` run. It 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 st…

This is why I firmly argue (and pretend) that references are not pointers. "References are pointers" results in the belief that references will behave like C pointers and results in things like this article. At best they are a cousin of pointers. I consider the fact that they are pointers an implementation detail, just like Box is a value with 'static samantics.

> This is why I firmly argue (and pretend) that references are not pointers. "References are pointers" results in the belief that references will behave like C pointers and results in things like this article.

This is my usual mental model as well. My thinking is that if tomorrow a new Rust version came out that used some other magical implementation of references that didn't use pointers under the hood, my code should still be correct. Maybe converting between references and raw pointers would be less efficient, but the semantics of my code shouldn't change.

Post reply on HN