salsa-rs / salsa

A generic framework for on-demand, incrementalized computation. Inspired by adapton, glimmer, and rustc's query system.
https://salsa-rs.netlify.app/
Apache License 2.0
2.09k stars 142 forks source link

Support results with internal references #498

Open nikomatsakis opened 2 months ago

nikomatsakis commented 2 months ago

A common need is to have a more complex data structure that has internal references. This can be modeled with vectors or arcs but it would be nice to have a way to create a ref-counted arena specific to each function and allocate memory from there. This is meant to model things like MIR, where we have some data structure that represents a function, and to allow it to go through phases where it is changed and updated, but without requiring everything to be in vectors nor requiring everything to be cloned constantly. I'm not sure the ergonomics exactly but the idea is roughly that you can declare a struct with two lifetimes...

#[in_arena(AstRoot)]
struct Ast<'ast, 'db: 'ast> {
   data: AstData<'ast, 'db>,
   children: Vec<&'ast Ast<'ast, 'db>>,
}

...and the procedural macro will create a type AstRoot that "hides" the first one:

struct AstRoot<'db> {
    arena: Arc<MemoryArena>,
    root: &'static Ast<'static 'static>, // <-- the lifetimes here are obviously lies
}

Later you can do root.open(|r| { .. }) to work with the data. One of the goals is that you can create new, derived values based on the same arena that have different pointers -- so e.g. it should be possible to extra subvalues from the tree. Each of them would carry a reference count to the same base arena.

_Originally posted by @nikomatsakis in https://github.com/salsa-rs/salsa/pull/490#discussion_r1641000198_