rust-lang / wg-allocators

Home of the Allocators working group: Paving a path for a standard set of allocator traits to be used in collections!
http://bit.ly/hello-wg-allocators
211 stars 9 forks source link

Ban zero-sized allocations #16

Closed TimDiekmann closed 4 years ago

TimDiekmann commented 5 years ago

From https://github.com/rust-lang/rust/issues/32838#issuecomment-471610560:

For me, an important constraint is that if we ban zero-sized allocations, the Alloc methods should be able to assume that the Layout passed to them is not zero-sized.

There are multiple ways to achieve this. One would be to add another Safety clause to all Alloc methods stating that if the Layout is zero-sized the behavior is undefined.

Alternatively, we could ban zero-sized Layouts, then Alloc doesn't need to say anything about zero-sized allocations since these cannot safely happen, but doing that would have some downsides.

For example, , some types like HashMap build up the Layout from multiple Layouts, and while the final Layout might not be zero-sized, the intermediate ones might be (e.g. in HashSet). So these types would need to use "something else" (e.g. a LayoutBuilder type) to build up their final Layouts, and pay for a "non-zero-sized" check (or use an _unchecked) method when converting to Layout.

Making Layout only accept non-zero size is not possible anymore as it's stable. But banning zero-size allocation would simplify the safety clause on Alloc.

This would also unlock to move helper methods to an extension trait.

This change could easily be reverted in the future if actual use cases appear. Currently I don't see any, because we cannot rely on an implementation to allow zero-sized allocations, thus we have to check size_of::<T>() == 0 in any way.

Lokathor commented 4 years ago

I like the NonZeroUsize approach because a person can use NonZeroUsize::new_unchecked if they want to on their end, and then that keeps that particular bit of unsafety outside of the allocators.

Wodann commented 4 years ago

I can see it happening mostly for

for?

  1. Add #[inline(always)] to alloc

Sounds reasonable.

  1. What's the reason you marked alloc and alloc_zero_sized_type as unsafe? Only because alloc_zero_sized_type doesn't work when passing 0? If so you can use NonZeroUsize

That's a good point. I can make alloc_zero_sized_type safe by making the type NonZeroUsize. Thanks!

alloc can still be unsafe, since align could be zero. There's no easy way to fix that, unless we make Layout::align a NonZeroUsize

Lokathor commented 4 years ago

more than just non-zero, it has to be power-of-two.

Wodann commented 4 years ago

I checked the docs. The is_power_of_two guarantee that Layout provides is enough to warrant making alloc safe too.

Wodann commented 4 years ago

I was preparing my proposal, but found an issue with Layout. Currently, safe ways of initializing a Layout forbid the usage of zero. If we are saying that it is safe to allocate a zero-sized type by including a default implementation in alloc, I feel that we should also make it safe to initialize a Layout with zero.

Do we want to make this a change to Layout::from_size_align or introduce a new function?

Edit: striking through my comment, as my question was based on a wrong conclusion.

petertodd commented 4 years ago

What do you mean "forbid the usage of zero"?

size is allowed to be zero; only align must be nonzero (and a power of two).

On February 3, 2020 8:23:42 AM EST, Wodann notifications@github.com wrote:

I was preparing my proposal, but found an issue with Layout. Currently, safe ways of initializing a Layout forbid the usage of zero. If we are saying that it is safe to allocate a zero-sized type by including a default implementation in alloc, I feel that we should also make it safe to initialize a Layout with zero.

Do we want to make this required change to Layout::from_size_align?

-- You are receiving this because you commented. Reply to this email directly or view it on GitHub: https://github.com/rust-lang/wg-allocators/issues/16#issuecomment-581411561

Wodann commented 4 years ago

You are so right. Sorry about that..

petertodd commented 4 years ago

No worries. I had to read it twice myself to be sure. :)

On February 3, 2020 8:42:35 AM EST, Wodann notifications@github.com wrote:

You are so right. Sorry about that..

-- You are receiving this because you commented. Reply to this email directly or view it on GitHub: https://github.com/rust-lang/wg-allocators/issues/16#issuecomment-581419331

TimDiekmann commented 4 years ago

I close this in favor of #38