9

This:

const fn pow2(exp: u32) -> u32 {
    u32::pow(exp, 2)
}

Results in a compiler error:

error[E0015]: calls in constant functions are limited to constant functions, struct and enum constructors

Is there a way to do this?

I'd like to do:

pub const MY_BITMASK: u32 = pow2(4);
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
marathon
  • 7,881
  • 17
  • 74
  • 137
  • 3
    because pow is not constant ? – Stargateur Jul 22 '17 at 00:54
  • 1
    There's no such concept in Rust as a "static fn", there is only "const fn". – Shepmaster Jul 22 '17 at 12:25
  • @Shepmaster In some literature, I see Thing::method() referred to as "static methods", e.g. https://rustbyexample.com/fn/methods.html – marathon Jul 23 '17 at 17:00
  • 1
    @marathon thank you for pointing that out. Those are called [associated functions](https://doc.rust-lang.org/stable/book/second-edition/ch05-03-method-syntax.html#associated-functions). I'll see about a PR to fix that. – Shepmaster Jul 23 '17 at 17:17

1 Answers1

17

A const function cannot call a non-const function. This is because const functions need to be able to run during compilation, so they can't call a non-const function which can only be evaluated at runtime. Since u32::pow is not a const function, you can't call it from a const function.

The question now becomes: Why isn't u32::pow a const function? And the reason for that is a current limitation of const functions: They can only contain a subset of the language. Notably, they can't contain loops or assignments. Since u32::pow uses both of these, it can't be marked as const and therefore can't be called from const functions.

Note that there isn't any limitation of calling associated functions from const functions, as long as the associated function is marked const. And u32::pow is not an associated function in any case: you can call it as e.g. x.pow(y).

Update: Const functions gained a lot more language features they can use in Rust 1.46 (including if, while, &&, etc.), and the integer types' pow functions were made const in Rust 1.50.

interjay
  • 107,303
  • 21
  • 270
  • 254
  • Update on this: hopefully as Miri is integrated into rustc more, more things will become possible and many more functions will be able to be marked `const` – Isaac Woods Feb 03 '18 at 13:37