|
| 1 | +# promotable_const_fn |
| 2 | + |
| 3 | +The tracking issue for this feature is: None. |
| 4 | + |
| 5 | +The `#[promotable_const_fn]` attribute can be used if the `promotable_const_fn` feature gate is |
| 6 | +active. |
| 7 | +While there are no checks on where it can be used, it only has an effect if applied to a `const fn`. |
| 8 | +Since this attribute is never meant to be stabilized, this seems like an ok footgun. |
| 9 | + |
| 10 | +The attribute exists, so it is possible to stabilize the constness of a function without stabilizing |
| 11 | +the promotablity of the function at the same time. We eventually want to have a better strategy, |
| 12 | +but we need to hash out the details. Until then, any const fn that is doing anything nontrivial |
| 13 | +should not be marked with `#[promotable_const_fn]`. Even better: do not mark any functions with the |
| 14 | +attribute. The existing "promotable on stable" functions were marked, but we could simply not |
| 15 | +stabilize the promotability of any further functions until we have figured out a clean solution |
| 16 | +for all the issues that come with promotion. |
| 17 | + |
| 18 | +The reason this attribute even exists are functions like |
| 19 | + |
| 20 | +```rust,ignore |
| 21 | +#![feature(const_fn)] |
| 22 | +
|
| 23 | +fn main() { |
| 24 | + let x: &'static bool = &foo(&1, &2); |
| 25 | +} |
| 26 | +
|
| 27 | +union Foo<'a> { |
| 28 | + a: &'a u8, |
| 29 | + b: usize, |
| 30 | +} |
| 31 | +
|
| 32 | +const fn foo(a: &u8, b: &u8) -> bool { |
| 33 | + unsafe { Foo { a: a }.b == Foo { a: b }.b } |
| 34 | +} |
| 35 | +``` |
| 36 | + |
| 37 | +Where this would be perfectly fine at runtime, but changing the function to a const fn would cause |
| 38 | +it to be evaluated at compile-time and thus produce a lint about not being able to compute the value |
| 39 | +and then emitting a llvm `undef` because there is no value to place into the promoted. |
| 40 | + |
| 41 | +This attribute patches this hole by not promoting functions without the attribute and at the same |
| 42 | +time preventing functions with the attribute from using unions or calling other functions that do |
| 43 | +not have said attribute. |
0 commit comments