Leverage Rusts `Drop` to close scopes automatically and implicitly
Opened this issue · 0 comments
AZWN commented
The regular 'scope ownership'/permission-to-extend is rather similar to Rust's scoping/lifetime rules.
Perhaps, we can leverage the Rust type system to close scopes automatically.
This could look as follows:
struct ScopeRef(u64)
struct ScopeExt<LABEL> { ref: &ScopeRef, lbl: &LABEL, _sg: &ScopeGraph<...> }
where ScopeRef
can be used for querying, but a ScopeExt
is required for extension:
struct NewScope<...> {
ref: ScopeRef,
ext: Vec<ScopeExt>
}
impl ScopeGraph<...> {
pub fn add_scope(&self, data: &DATA, open_edges: &[LABEL]) -> NewScope {
...
}
pub fn get_edges(&self, scope: &ScopeRef, lbl: &LABEL) -> impl Iterator<Item = &ScopeRef> { ... }
pub fn add_edge(&self, ext: &ScopeExt, tgt: &ScopeRef) { ... }
}
The NewScope
type carries all information of the new scope:
- a reference to it (
ref
) - for each edge in
open_edges
, aScopeExt
entry (in the same order).
The trick now is the following. We can implement a custom Drop
for ScopeExt
:
impl Drop for ScopeExt<...> {
fn drop(&mut self) {
self._sg.close(&self.ref, &self.lbl);
}
}
This ensures that a scope is closed when the ScopeExt
is deallocated.
Macro
Perhaps, it would be better to wrap the API in a macro that unpacks the ScopeExt
instances:
let (scope, ext_lex, ext_def) = new_scope!(sg, data, Lbl::Lexical, Lbl::Definition);