Is there anything in type system fundamentally preventing global variables passed as parameters through enclosing function to be captured by function pointers fn(...) -> ...?
I know that current implementation forbids such behavior, however given a very first line of static definition
A static item is a value which is valid for the entire duration of your program (a 'static lifetime).
It makes me wonder why i can't have a program like this:
closures can only be coerced to fn types if they do not capture any variables
Capturing of op and zero params leads to this error no matter of their 'static lifetime.
So I either have to use ZERO_ADD and ADD directly in the fn pointer body or switch to closure and return Box<dyn Fn(&Vec<i32>) -> i32 + Send + Sync + 'static>.
I'm unable to realize any fundamental blockers for the compiler to accept such programs.
The problem is not with lifetimes, the problem is with what a function pointer is. A function pointer is just that – a function pointer. It's not a function pointer plus some other data. There's no place to store the captured data inside it. What you are describing is not a bare function pointer, it's exactly a full-fledged closure.
How it is different when additional layer of indirection through enclosing function parameters is added? I'm speaking precisely about references to statics with 'static lifetime, not the arbitrary parameters.
Again, lifetimes have nothing to do with this. A reference to a 'static item is still a reference, it's still additional data that has to be stored somewhere.
If you invoke whatever through a function pointer, then that might be dynamic, as far as the compiler is concerned. The bad_binop_fold_fn_ptr() function would have to work no matter what op is pointing to. It's not statically knowable (based on only function-local analysis) that it can only be X or Y function that you happen to have specified.
This is not the case when you directly refer to an item, because then it is 100% sure that the item is whatever it is, it can't be anything else, and so dynamism doesn't need to be accounted for.
It seems that you expect that references with 'static lifetime should somehow always be "constants" in the program, so that a closure which captures only such variables can avoid storing those references entirely by generating a unique function pointer type for every combination of arguments.