allocator: refactor for stabilisation#157428
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| /// - the allocator is mutated through public API taking `&mut` access (notably, | ||
| /// running the allocator's destructor is such a mutation), or |
There was a problem hiding this comment.
This guarantee seems fine on the surface, but I'm trying to wrap my head around what's actually being guaranteed here. Like, clearly, it'd be wildly unsafe to offer an invalidate_everything method on an allocator that just deletes the backing memory without requiring any of the things that are using it to be dropped, but this feels like it's opening the door for that kind of method "as long as you're careful" which, doesn't make a lot of sense.
Like, I'm trying to gauge what value is being gained by this guarantee and it mostly just feels like it's making things more confusing without actually helping.
There was a problem hiding this comment.
we're saying that such an invalidate_everything method is allowed to exist, and you can't rely on the allocator having not yet been dropped for soundness. in other words, so long as you hold a &alloc (thus preventing a &mut alloc from being created), you can trust the memory you have is fine; but if you lose the &alloc and get a new one back, your memory might have been scribbled over and you must act as such
There was a problem hiding this comment.
Okay, but wouldn't that be the same thing as the lifetime expiring as before? Technically, even though both of them are written as &A, you've gotten a new &A lifetime in that case.
There was a problem hiding this comment.
i think the extra guarantee here is that if you do hold a &mut alloc, you can call methods that take alloc by-shared-ref without worry but you can't pass the actual &mut to an untrusted function and expect your allocator to be okay at the end. but i agree that's not obviously guaranteed
There was a problem hiding this comment.
Isn't that just totally breaking the aliasing guarantees, though? Since that &mut reference wouldn't be unique.
There was a problem hiding this comment.
...you know, you make a good point. i'll revisit the reasoning for this, i recall adding this in response to something being brought up
There was a problem hiding this comment.
nvm, i'm being stupid. the following is the reason:
let mut alloc = SomeAllocator::new();
let ptr = alloc.allocate(...);
alloc.something_by_shared_ref();
// ptr is still guaranteed to be valid
alloc.trusted_method_by_unique_ref();
// ptr is still valid because we know for sure the method is trusted not to mess w/ allocator state
alloc.untrusted_method_by_unique_ref();
// ptr must be assumed to be maybe-invalid even if the lifetime of alloc is not expired and ptr hasn't yet been deallocatedThere was a problem hiding this comment.
I guess that I was technically thinking of Box whose lifecycle is intrinsically tied to the lifetime of the allocator parameter, whereas in this case if you just call alloc and dealloc manually the "lifetime" is not really tracked at all. So, yes, mutable borrows can happen on the allocator and it's fine, and you guarantee this doesn't happen by taking a non-mutable borrow.
There was a problem hiding this comment.
Seeing this thread from @RalfJung: #157428 (comment)
I think we probably also need to be careful about how we define the relationship between these rules and StaticAllocator, since "lifetime expiration" in those cases refers to the allocator value and not references in that case.
|
@rustbot author (mostly so you can more clearly signal when you think things are ready; I've commented here already so I'll see any additional changes for review as they're made) |
| /// | ||
| /// [`Pin`]: ../../core/pin/struct.Pin.html | ||
| #[unstable(feature = "allocator_api", issue = "32838")] | ||
| pub unsafe trait StaticAllocator: Allocator {} |
There was a problem hiding this comment.
I dropped the 'static bound here (and thus implicitly in Box::pin_in, etc.); since this trait is about being able to be lifetime-subtyped safely, it would mean that you need to be able to coerce to a StaticAllocator + 'a so the whole guarantee about "this is Actually Static I Promise" has weight. cc @rust-lang/opsem in case i did a bad here
There was a problem hiding this comment.
That's more of a @rust-lang/types question
This comment has been minimized.
This comment has been minimized.
7a5e03d to
354678d
Compare
|
This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
|
per discussion on zulip, i changed the unwinding bit to a hard requirement; we may change it in the future so that an unwind out of following last week's libs-api meeting, we also got the go-ahead to keep the slice return type so long as we have that extra doc comment making it clear that this shouldn't always be done. @rustbot ready |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
63e2672 to
0fca0d1
Compare
This comment has been minimized.
This comment has been minimized.
|
Just trying to get a handle on the current status here, are we waiting for the (presumably imminent) FCP on the decision of dyn-compatibilty (#156906) to conclude before proceeding here? Does this PR here supersede the prior stabilization PR (#156882), or is this one a prerequisite that that one is waiting on? Which issue should people prefer to watch in order to catch the eventual Allocator trait FCP with the proposed final design, and could that issue be mentioned in the original tracking issue (#32838) in order to advertise it more broadly? |
|
good question! this PR is laying the groundwork for stabilisation, which should be happening Very Soon(tm). i intend to update the design doc in #156882 as soon as this is r+'d and reopen that PR (which should be just stability attr changes). the design points have been discussed on zulip and we had been in the situation of there being multiple mutually-exclusive possible designs (see: dyn allocator vs having an associated error type) where we just have to Pick One, and that's what we've been doing in the libs-api meetings over the past couple of weeks. the only outstanding point i believe is confirming the decision w.r.t. |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as resolved.
|
Here's some unsoundness caused by a panicking drop. Have fun! :) |
|
|
|
Alright, I think that I went through all mutable accesses of the length field in There might be another one in |
View all comments
Adds my current proposal per the doc in #156882 and follow-up Zulip conversations (notably for dyn-compat) unstably.
r? libs