Skip to content

static scope-shadowing restriction #11

@dherman

Description

@dherman

If we think of storing locals as "updating" a scope, we can rationalize changing the APIs to take an &mut impl Scope instead of an &impl Scope. From there we can use the borrow checker rules to "freeze" a scope when we shadow it with .nested and .chained, which lets us enforce most of the invariants of v8's HandleScope abstraction statically. For example:

    realm.scoped(|outer| {                  // &mut impl Scope
        let mut x = Integer::new(outer, 0); // Integer::new() takes an &mut outer
        outer.nested(|_| {                  // .nested() takes a frozen &outer
            x = Integer::new(outer, 666);   // borrow error: outer is frozen
        });
    });

The only thing it doesn't prevent statically is shadowing a frozen scope:

    realm.scoped(|outer| {
        outer.nested(|_| {      // .nested() takes a frozen &outer
            outer.nested(|_| {  // needs to be a dynamic error
                // ...
            });
        });
    });

The dynamic checks could be implemented with the same approach as today, but they would be rarer and possibly quite a bit less costly: instead of an extra branch on every creation of a local, they only have an extra branch on every shadowing of a scope.

One final thought: I wonder if this whole API is a fit for the future emplacement syntax.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions