Analyzing unsized variables in Rust

Discussion on r/rust

5 Likes

In retrospect, the RFC was probably too ambitious given the current state of the compiler. It relies on Guaranteed Copy Ellision (GCE), which isn’t yet implemented, and “separating a function in two”, which would be feasible with generators but probably come with a ton of follow-up problems.

I don't think it requires generators. It could be a function that returns the required allocation size and a closure:

fn return_dynamic(n: usize) -> [i32] {
    [42; n * 2]
}
// desugars to
fn returns_dynamic(n: usize) -> (usize, impl FnOnce(&mut [MaybeUninit<i32>])) {
    let content = 42;
    let size = n * 2;

    (size, move |slice| {
        for item in slice {
            item.write(content);
        }
    }
}

However, there's a limitation: The function can only have 1 return point (if it returns Result<[i32], X>, it can have at most 1 successful return point). The good thing is that this could already be implemented with procedural macros in stable Rust :slight_smile:

3 Likes

I also wonder if the unsized params might benefit from a compiler-internal concept of &move... since that's basically what unsized params are, just transparently, with the reference added as part of the ABI.

(I do not know how they're actually handled, nor what MCPs/eRFCs have been proposed around &move.)

But this field (unsized params and returns) definitely ties strongly into the async vision, async trait, and especially dyn async trait.

There was the same debate on the zulip thread I made when researching for this article.

The short version is, a &move T type probably wouldn't bring much to the table; implementing it would make unsized params easier; but implementing it would probably be much harder than implementing unsized params directly.

2 Likes

Can we leverage drop glue for deallocating memory behind unsized values?

Like, make the repr of unsized data to always be a pointer (as it is now?) (and metadata) to an actual object; move responsibility of deallocating memory into drop glue of such values?

alloca allocated stack variables can't be deallocated in any way. There is no memory allocator that can do accounting to determine which parts of the stack are used and which are not. Deallocation has to happen in the reverse order in which the stack is allocated. One stack frame at a time.

make the repr to also contain a dealloc routine pointer? and make it a no-op for alloca originating values.