Skip to content

[FEATURE] Add resource management operators forget and drop #272

@davidscholberg

Description

@davidscholberg

I've got an idea for a couple of semi-related operators that could improve resource ergonomics.

The first one allows a variable to be "forgotten" such that Zen C will not attempt to call the drop method on it, nor allow it to be used further in the scope in which it is defined. This would be primarily useful if you needed to transfer some resource to a variable of a different type, e.g.:

let b = Bar::new();

// do some stuff with b

let f = Foo::new();
f.x = b.y;
forget b;

// now f owns the resource that b previously owned, and b can no longer be used

The second operator is related to forget but goes a step further; it would immediately call the drop method on the variable, and (like forget) would not allow the variable to be used any further. This is useful if you want to immediately free some resource without having to wait for the enclosing scope to exit, and it'll help to avoid any use-after-free shenanigans. E.g.:

let f = Foo::new();

// do some stuff with f

drop f;

// now f's resources have been freed and f itself can no longer be used

// do some other stuff

Both of these scenarios could be handled by custom methods/functions, but that requires some extra manually-defined infrastructure and gets a little bit clunky when you're dealing with generic types. E.g.:

struct Foo<T> {
    forgotten: bool;
    x: T*;
}

impl Foo<T> {
    fn new() -> Foo<T> {
        return Foo<T> {
            forgotten: false,
            x: acquire_x()
        };
    }

    // Prevent drop method from freeing resource.
    fn forget(self) {
        self.forgotten = true;
    }

    fn drop(self) {
        if !self.forgotten {
            release_x(self.x);
        }
    }
}

// Move variable and immediately drop it.
// Being a generic function, you have to type out the typename of the function arg for each call.
fn drop<T>(v: T) {
    v.drop();
}

Having dedicated operators for forget and drop that work on all Drop types without having to define any extra struct fields, methods, or functions would be a significant ergonomic improvement.

Thoughts on this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions