I have an API where a user provided callback must depend only on its arguments, so that I can reliably rerun it when its dependencies change. Essentially I need to prevent it from accessing `'static'. Is there a way to enforce this in the type system?
I've been trying to make GhostCell style invariant lifetime trickery work with something like Fn(T) + 'id, but I haven't found a way that works yet. Can this be done?
No, I don't believe this is possible.
But I also believe to read an immutable static string is ok for a pure function. So I do not understand your use case.
There is no way to enforce that a function is a pure function. Lifetimes don't help because a Fn can have an Arc in it — and even a fn can call a system call to read the clock or file system.
In Rust it isn't possible to enforce function purity. A simple counterexample is that you can put a println!() in pretty much any fn and it'll compile fine.
Technically I have no problem with println!() style leakage. My goal is to have a set callbacks that get recomputed when their dependencies change, so I want to be able to know all of their dependencies.
Oh well, I guess documentation (and maybe a custom lint if I care enough) is the best I can do for now. It feels like a safety hole in the API, but I can live with it. Thanks.
I believe that documenting it is what has generally been done, for e.g. salsa if you want to go beyond documentation, you'll need to use an external checker/pure marker attribute. I know that at least prusti has this Pure functions - Prusti user guide but perhaps other checkers as well.
Edit: I guess I should mention that while I don't believe it is possible to add trait bound like Fn(T) + Pure you could maybe wiggle a FnPure(T) with an f: Fn(T) field I haven't tried though.
In practice there is quite a bit of overlap between the abstract notion of purity and the actual mechanics behind const; so one can, for instance, require that something be pure by making the even more restrictive check of requiring it be const, currently by using a macro API which will feed the received body to an anonymous const or something
Maybe in the future impl const Fn… may, on the other hand, be a more serious approach to this idea