ekzhang / crepe

Datalog compiler embedded in Rust as a procedural macro
Apache License 2.0
453 stars 16 forks source link

Lifetime parameters in relations #2

Closed ekzhang closed 3 years ago

ekzhang commented 4 years ago

Right now, Crepe recommends that you pass references to types like Strings in relations, rather than values. This is for efficiency reasons, as relations are required to implement the Copy trait. For example, the following code is valid:

use crepe::crepe;

crepe! {
    @input
    struct Edge(&'static str, &'static str);

    @output
    struct Reachable(&'static str, &'static str);

    // Transitive closure
    Reachable(n, m) <- Edge(n, m);
    Reachable(n, m) <- Edge(n, k), Reachable(k, m);
}

fn main() {
    let mut runtime = Crepe::new();
    runtime.extend(&[
        Edge("hello", "world"),
        Edge("world", "foo"),
        Edge("world", "bar"),
    ]);

    let (reachable,) = runtime.run();
    println!("Reachable: {}", reachable.len());
    for Reachable(x, y) in reachable {
        println!("edge: {} -> {}", x, y);
    }
}

However, with non-'static lifetimes, Rust requires that the struct declaration be generic over the lifetime parameter. Currently Crepe does not check for this, but it would be useful to write code with non-static lifetimes such as:

use crepe::crepe;

crepe! {
    @input
    struct Edge<'a>(&'a str, &'a str); // does not compile currently

    @output
    struct Reachable<'a>(&'a str, &'a str); // does not compile currently

    // Transitive closure
    Reachable(n, m) <- Edge(n, m);
    Reachable(n, m) <- Edge(n, k), Reachable(k, m);
}

fn main() {
    let dyn_string = String::from("dynamic");

    let mut runtime = Crepe::new();
    runtime.extend(&[
        Edge("hello", "world"),
        Edge("world", "foo"),
        Edge("world", "bar"),
        Edge("world", &dyn_string),
    ]);

    let (reachable,) = runtime.run();
    println!("Reachable: {}", reachable.len());
    for Reachable(x, y) in reachable {
        println!("edge: {} -> {}", x, y);
    }
}