If you're committed to this being build time, there's the hack option of generating the table as rust source code in build.rs, then the hilariously overkill option of using a procedural macro. The former is very self explanatory once you know what build.rs is, the latter is rather too much to explain here!
With great surprise I have realized that none of the floating-point functions are const. Moreover, they aren't even unstably const, which is very unexpected. Is it because they delegate to libc, which can set ERRNO?
I would still expect to have some sort of "default sin/cos", which would be usable in const context. Strictly speaking, all calculations of constants are performed by the Rust's const evaluation engine rather than directly by the processor, so it can use whatever semantics it desires. The intrinsics for floating point functions could even evaluate to different functions depending on the context, i.e. have some strict mode of evaluation when called as a const, or lower directly to the libc functions during runtime.
A counterargument would be that it is a footgun if a function have different behaviour depending on the surrounding context. That's true, but I suppose there wouldn't be any significant difference anyway, i.e. it would be on the order of floating point precision. I don't know the FP standard enough to definitely make a case, though.
Floating point calculations are deterministic. Even ones involving NaN. The issue as I understand it (I asked maybe a month ago) is that the software implementation does not do everything exactly as the hardware does, leading to inconsistent/unexpected results. This isn't because the software is wrong. On the contrary, the hardware returns the wrong value in some situations. There is a fully spec-compliant implementation of floating point arithmetic in rustc, and it is used by MIRI for the unstable methods. There is nothing preventing additional floating point methods from being made unstably const.
After some research, my current understanding of the situation is:
const fns are evaluated at compile time
regular fns are evaluated at runtime
Rust requires that const fns have the same result regardless of if they are evaluated at compile time or runtime
This is hard to guarantee, as arch compiled on can be different from arch code is run on; in fact, the arch the code is run on might not even have a FPU unit
Depending on the resolution and hence size of your sin/cos lookup tables and depending on what floating point hardware you have available it may well be faster to let the FPU calculate sin/cos for you rather than doing a table look up.
Why? Because tables live in memory, that memory access may well cause cache misses and take 100s or 1000's of times longer than when there is no cache miss.
If performance is the name of the game it might be wise to benchmark this.
Good correction. I think this is precisely the issue: Rust has an expectation that a fn, whether evaluated at compile time or run time, if given the same args, produce the same response. Doesn't sound too unreasonable.
Unfortunately, when the compile arch and runtime arch differ, who knows how f32's behave.
TL/DR: The nice monotonic stuff (addition, exp, ...) we can probably make const once we figure out how to deal with NANs. Things where efficient ½ULP accuracy -- and thus portably consistent behaviour -- is fundamentally harder (sin, cos, tan, ...) might never be const, though.