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.
That's true, a static string is ok. But e.g. reading from
static foo: AtomicU32 = AtomicU32::new(0); isn't.
Yeah that makes sense, although it's unfortunate. So is is not possible to do any better than documenting that a passed closure should be pure?
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.
That's correct, at least at this point in time.
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
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.