I'd like to understand better the motivation behind inline const expressions, in particular its intersection with const fn.
From what I understand, inline const expressions allow to execute the context of the block at compile time. While, const fn
enables to call free function in a constant context, and therefore also allows to evaluate the context at compile time.
Now taking into consideration the 2 examples from the RFC.
The first example:
fn foo() -> &'static i32 {
&const {
let x = 4i32;
x.pow(5)
}
}
Assuming pow
can be evaluated at compile time, I should be able to write an equivalent version using const fn
:
#![feature(const_fn)]
#![feature(const_int_pow)]
const fn foo(x: i32) -> i32 {
x.pow(2)
}
But if I try to return a 'static
reference I get:
const fn foo(x: i32) -> &'static i32 {
&x.pow(2)
}
error[E0515]: cannot return reference to temporary value
--> src/main.rs:5:5
|
5 | &x.pow(2)
| ^--------
| ||
| |temporary value created here
| returns a reference to data owned by the current function
even thogh, if this was possible with the inline const version, then it should be in theory also possible with the const fn
version, and if that is the case (compilers are not my field of expertise so I may be completely wrong), the const fn
version achieves the same result by being much less verbose.
Regarding the second example:
fn main() {
match *x {
0 ..= const { u32::MAX / 2 } => println!("low"),
const { u32::MAX / 2 + 1 } ..= u32::MAX => println!("high"),
}
}
What makes me wonder is the need for const { u32::MAX / 2 + 1 }
, since I would assume that by default, when dealing with const
and litterals, the compiler should be able to evaluate the expression at compile time by default, without the need for a const inline block.
Are my assumption and/or my conclusions wrong? What is the need for const inline expression if compile time evaluation could be in theory be achieved via const fn
?