error[E0015]: cannot call non-const function `my_func` in constants

error[E0015]: cannot use `for` loop on `std::ops::RangeInclusive<u32>` in constant functions

const 文脈で非 const 関数を使用した。

パターン

パターン A

基本形

単純に const 文脈で非 const 関数を使用している。

サンプル


fn main() {
    const VAL: i32 = my_func(3, 2);
    assert_eq!(VAL, 5);
}

fn my_func(x: i32, y: i32) -> i32 {
    x + y
}

error[E0015]: cannot call non-const function `my_func` in constants
 --> src\main.rs:2:22
  |
2 |     const VAL: i32 = my_func(3, 2);
  |                      ^^^^^^^^^^^^^
  |
  = note: calls in constants are limited to constant functions, tuple structs and tuple variants

パターン B

for ループ

const 文脈中で for ループ構文を使用している。

これは不可能である。なぜなら、for ループ構文の in の対象には IntoIterator トレイトを実装した型が必要になる。そして、IntoIterator の各メソッドは const 関数ではない。

サンプル

以下では、5 の階乗を計算している。


fn main() {
    assert_eq!(fact(5), 120);
}

const fn fact(n: u32) -> u32 {
    let mut ret = 1;
    for i in 1..=n {
        ret *= i;
    }
    ret
}

error[E0015]: cannot use `for` loop on `std::ops::RangeInclusive<u32>` in constant functions
 --> src\main.rs:7:14
  |
7 |     for i in 1..=n {
  |              ^^^^^
  |
  = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants

解決策

for 構文は使えないが、whileloop は使える。


fn main() {
    assert_eq!(fact(5), 120);
}

const fn fact(n: u32) -> u32 {
    let mut ret = 1;
    let mut i = 1;
    while i <= n {
        ret *= i;
        i += 1;
    }
    ret
}