Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify unsafe requirements of AllocRef #65

Open
HeroicKatora opened this issue Aug 1, 2020 · 11 comments
Open

Clarify unsafe requirements of AllocRef #65

HeroicKatora opened this issue Aug 1, 2020 · 11 comments
Labels
A-Alloc Trait Issues regarding the Alloc trait A-Docs

Comments

@HeroicKatora
Copy link

The Safety section currently uses a number of non-standard terms and is rather small. The biggest pain point might be:

  • Memory blocks returned from an allocator must point to valid memory and retain their validity until the instance and all of its clones are dropped,

This leaves a number of important requirements open. The term 'valid memory' isn't used anywhere else in the standard library documentation. It isn't even decided what the validity of a [u8] requires (see ucg-71). The wording doesn't make it clear that the caller must be allowed to write any contents to it, including uninitialized memory. It should also be mentioned that no other reference pointing to the memory region must be used while the block is allocated. Both of these requirements are already necessary to implement Box in terms of an AllocRef impl.

In comparison, MaybeUninit is arguably simpler and safer to use and has a far more extensive documentation.

@petertodd
Copy link

petertodd commented Aug 3, 2020 via email

@SimonSapin
Copy link
Contributor

Returning &'static mut is unsound since the reference becomes invalid after dealloc is called. The actual life time of heap allocations cannot be encoded statically in the borrow checker.

I think MaybeUninit is worth considering, and perhaps worth a dedicated thread (since this issue is to some extent about documentation).

@petertodd
Copy link

petertodd commented Aug 3, 2020 via email

@Lokathor
Copy link

Lokathor commented Aug 3, 2020

point of order: it's not unsound it's just a footgun.

Because it's not wrong: the memory is static. It would be up to the dealloc caller to prove that all references had ended. Since dealloc is unsafe, soundness is preserved.

@SimonSapin
Copy link
Contributor

That’s not my understanding of what 'static means, but I don’t know what the exact formal definition is or whether we have one.

@Lokathor
Copy link

Lokathor commented Aug 3, 2020

Static means "lives until the end of the program", but it doesn't have to be a compile time value. That's how Box::leak works.

@sollyucko
Copy link

  1. If dealloc where to accept mutable AKA unique reference, the caller shouldn't be able to continue using the reference, right?
  2. Another possibility is to have something implementing Drop, so that dealloc is also safe (see Crazy idea: Raw(Box/Vec/Deque)Impl<T> traits #63).

@TimDiekmann
Copy link
Member

Another possibility is to have something implementing Drop, so that dealloc is also safe (see #63).

This will not work, as this is not the issue, why dealloc is unsafe. Leaking memory is not unsafe, but the caller have to ensure, that the provided pointer and layout are valid. We can't do much here to reduce the unsafeness, as allocators are a very low level API. Only a few user will ever need to use this API directly.

@TimDiekmann
Copy link
Member

TimDiekmann commented Aug 4, 2020

and my apologies if the MaybeUninit possibility has been argued already! I may have missed that

I think I have proposed it a while ago, but I can neither remember where nor can find it. I opened #66 for this. Possibly I also tried it out in one of my dozend branches at the alloc-wg crate 😄

@HeroicKatora
Copy link
Author

HeroicKatora commented Aug 4, 2020

Returning &'static _ would be a footgun for the use and implementation non-global allocators. The current requirement is for memory to be valid 'until the instance and all of its clones are dropped' which may in fact happen sooner than 'static. Since this inherently is not a scoped requirement but instead memory belongs to some owned AllocRef instance that is not borrowed from I don't think having a lifetime in the returned value is a good clarification. (It would nevertheless be sound, lifetimes have no semantic effect and the unsafe trait could require the caller to know).

@zakarumych
Copy link

Box::leak returns reference with arbitrary lifetime and it is safe to convert it back, provided that no other references to the value left.
So &'arbitrary mut [MaybeUninit<u8>] communicate guarantees better than NonNull<u8>.
However I must agree that code receiving this reference can be confused by lifetime. i.e. footgun.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Alloc Trait Issues regarding the Alloc trait A-Docs
Projects
None yet
Development

No branches or pull requests

7 participants