-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Add unsized return values. #977
Conversation
+1. I was going to say we should wait for placement new to be accepted, but that already happened, so... :) |
allocation or return a reference to an already deallocated slice. | ||
|
||
(For similar reasons it's not possible to implement the trait on | ||
`&mut Box<[T]>`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm convinced of L144-L145, but not of this. Can't we impl<'a, T> IntoSlice<'a, T> for &'a mut? Box<[T]>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For posterity: discussion on IRC lead to clarification that IntoSlice
is for translating into a slice which owns its contents, so it certainly cannot be implemented for non-owning references of Box<[T]>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but it can be implemented with
&mut Box<[T]>
withmem::replace
.
Let me explain why that does not work. Let's assume again the following signature:
fn into_slice(self) -> &'a [T];
Since the return value doesn't own the memory the slice is stored in (the heap), we cannot replace the whole Box<[T]>
by an empty box:
// does not work
mem::replace(self, box []);
Next we might try to just set the length of the slice in the box to zero and return the real slice:
let slice = &**self;
// transmute *self to raw;:Slice, set length to zero, transmute back
return slice
The reason that this doesn't work is that when the Box<[T]>
is eventually dropped, it sees that the length is zero, which is what we wanted because now the box doesn't drop its elements. However, jemalloc uses sized deallocation which means that Box
must know its real size in order to deallocate itself.
How is this supposed to work? The size of an unsized type is not known until the function returns. Do functions returning unsized values take an implicit allocator argument? When is the allocator called? |
@arielb1 All of your questions are answered in the RFC. |
What allocator API are you using? |
On one hand, this allows us to abstract over box patterns, which is currently not possible, and that is a huge plus. On the other there is a fair amount of magic going on. And I'm sort of disposed to not thinking about this or box placement until we have to tools ( It's a bit ironic that this is somewhat reminiscent to the comments proposing taking unboxed unsized types as an alternative to Don't want to derail, just want to point out that the stuff proposed here isn't only applicable to returning, assuming I understand the situation correctly. And if we add the magic to one, why doesn't the other deserve it too? |
The point of the placement box RFC is that it's not possible to do this efficiently and safely. In the case of unsafe types it's even less possible. |
I think this is a reasonably good idea, but we should postpone it for now, for two reasons:
Therefore, I am going to close this as postponed under issue #990. UPDATE: Sorry, I should have said that this was also the decision reached at the triage meeting. |
That's what the |
We may use |
Add the concept of unsized return values, e.g.,
Rendered