Live data from Hacker News

Rust: Box Is a Unique Type

blog.nilstrieb.dev

31–40 of 56 posts

Re: Rust: Box Is a Unique Type

#31
post #15

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.

Is that by design ? I am a novice at rust, but that is sort of how it feels. I could be missing something.

It requires supporting higher-kinded types, and Rust was reluctant to add them (although it’s slowly getting there with higher kinded lifetimes and generic associated types).

Re: Rust: Box Is a Unique Type

#32

Earlier quoted context omitted.

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.

It's trivial to measure code coverage. It's definitely not trivial to achieve 100% code coverage.

This is the sort of "just do things perfectly" nonsense we get from C programmers. I'm surprised to see it from Rust devs, given the whole ethos of Rust is that it acknowledges that programmers are not perfect and helping them avoid bugs as much as possible is a good thing.

Re: Rust: Box Is a Unique Type

#33
post #3

Earlier quoted context omitted.

> 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.

> A box is a pointer AND the storage at the same time.

That's just the way you decide to see it. Most people don't, in fact the actual documentation is quite different:

>> A pointer type that uniquely owns a heap allocation of type T.

This explicitly describes it as a pointer, pointing to a single allocation.

https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html

Re: Rust: Box Is a Unique Type

#34

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…

> It's a high-level object (i.e. not a pointer)

I don't know why so many people in this thread try to pretend that there's no reason to see Box as a pointer, no one has ever called it that, and every user drawing a parallel is confused. The documentation for Box is literally (emph mine):

>> *A pointer type* that uniquely owns a heap allocation of type T.

Until that documentation changes I find the article's point quite valid.

Re: Rust: Box Is a Unique Type

#35

Earlier quoted context omitted.

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

It's trivial to measure code coverage. It's definitely not trivial to achieve 100% code coverage. This is the sort of "just do things perfectly" nonsense we get from C programmers. I'm surprised to see it from Rust devs, given the whole ethos of Rust is that it acknowledges that programmers are not perfect and helping them avoid bugs as much as possible is a good thing.

I agree in general, but if you have unsafe code you should definitely make sure it is covered.

Re: Rust: Box Is a Unique Type

#36
post #34

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…

> It's a high-level object (i.e. not a pointer) I don't know why so many people in this thread try to pretend that there's no reason to see Box as a pointer, no one has ever called it that, and every user drawing a parallel is confused. The documentation for Box is literally (emph mine): >> *A pointer type* that uniquely owns a heap allocation of type T. Until that documentation changes I find the article's point qui…

> The documentation for Box is literally (emph mine):

> >> A pointer type that uniquely owns a heap allocation of type T.

> Until that documentation changes I find the article's point quite valid.

I think there's some confusion here and that it's because the concept of "pointer" is slightly overloaded.

One overload of the meaning is "first-class pointer types": https://doc.rust-lang.org/reference/types/pointer.html

The other overload, the one used in the docs for Box, Rc, and such, is basically "anything that implements Deref". People who say "Box is not a pointer" are referring to the fact that Box is not a first-class pointer type, i.e. it's neither a reference nor a raw pointer.

Re: Rust: Box Is a Unique Type

#37
post #34

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…

> It's a high-level object (i.e. not a pointer) I don't know why so many people in this thread try to pretend that there's no reason to see Box as a pointer, no one has ever called it that, and every user drawing a parallel is confused. The documentation for Box is literally (emph mine): >> *A pointer type* that uniquely owns a heap allocation of type T. Until that documentation changes I find the article's point qui…

I only meant "not a raw pointer" because rust supports read and write operations on raw pointers with very different aliasing semantics.

It is an owned pointer, with emphasis on the "owned". You can have as many raw pointers to the same memory location as you like, you just can't have multiple native rust objects pointing to that same memory alive at once, though. It's also obvious because Box implements Drop, so obviously it's not just something you can pass to a function in lieu of a pointer and if you do pass it to a function, you can no longer make any assumptions about the lifetime or validity of any pointers to the same data.

Re: Rust: Box Is a Unique Type

#38

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.

If you have an object that's !Unpin, then Miri will not apply uniqueness rules to anything containing it [0], including boxes and &mut references. (In the example code, replacing the PhantomPinned with a () will make Miri complain again.) This is considered a temporary (if long-lived) measure to allow async executors to manipulate pinned futures without invalidating all their internal borrows. Thus, it might be seen as undetected UB, in lieu of a permanent solution.

[0] https://play.rust-lang.org/?version=stable&mode=debug&editio...

Re: Rust: Box Is a Unique Type

#39
post #33

Earlier quoted context omitted.

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.

> A box is a pointer AND the storage at the same time. That's just the way you decide to see it. Most people don't, in fact the actual documentation is quite different: >> A pointer type that uniquely owns a heap allocation of type T. This explicitly describes it as a pointer, pointing to a single allocation. https://doc.rust-lang.org/nightly/std/boxed/struct.Box.html

“A pointer type that owns a heap allocation” is a more broad definition to me than specifically “a pointer pointing to a single allocation”

Re: Rust: Box Is a Unique Type

#40
There’s magic in the Box: ability to partially move content out of it, where any other type with Drop couldn’t handle it. You can implement traits for Box even when Othertype wouldn’t be allowed.

But noalias is not very special for Rust. &mut and & have a bunch of limitations too.

But there’s no need to give up on them, because Rust has the UnsafeCell wrapper type for doing crimes with pointers. It selectively disables noalias, thread safety, etc. Instead of weakening guarantees of Box in general for all types, just insert UnsafeCell where you need to be clever with pointers.

Post reply on HN