2021年でconst文脈でできるようになったこと

この記事はRust Advent Calendar 2021 2の20日目の記事です。

---

2021年(1.50.0 ~ 1.57.0)に`const`文脈でできるようになったことを書いていきます。また`const`の話です。
英語が得意ではないのでミス、抜け漏れなどがあれば指摘していただけるとありがたいです。
内容は[rust-lang/rustリポジトリのREADME.md](https://github.com/rust-lang/rust/blob/master/RELEASES.md)を参考にしています。

---

## 1.50.0 (2021-02-11)
### You n now use const values for x in [x; N] array expressions. This has been technically possible since 1.38.0, as it was unintentionally stabilized.
`[x; N]`の`x`部分に`const`な値を入れられるようになったというものです。

This has been technically possible since 1.38.0, as it was unintentionally stabilized.
意訳: これは1.38からできたけど意図せず安定していた
とあるのでおそらく既にコンパイルが通っていたが規格として決めていなかったものを決めたものだと思います。

## 1.51.0 (2021-03-25)
### You can now parameterize items such as functions, traits, and structs by constant values in addition to by types and lifetimes. Also known as "const generics" E.g. you can now write the following. Note: Only values of primitive integers, bool, or char types are currently permitted.
Genericsに`const`な値を渡せるようになる、つまり`const generics`です。
これについては[去年のアドカレの記事](https://qiita.com/block/items/85d015f9977371aa4a1f)があるのでそちらを読んでいただければどんな機能かわかると思います。

### rustc no longer promotes division, modulo and indexing operations to const that could fail.
0除算や配列の範囲外へインデックスアクセスするのをエラーにします。

## 1.52.0 (2021-05-06)
### All integer division and remainder operations are now const.
整数型の除算と余りの計算をする関数(`i*::checked_div`など)を`const`にする。
<details><summary>関数一覧</summary><div> 

- i*::checked_div
- i*::checked_div_euclid
- i*::checked_rem
- i*::checked_rem_euclid
- i*::div_euclid
- i*::overflowing_div
- i*::overflowing_div_euclid
- i*::overflowing_rem
- i*::overflowing_rem_euclid
- i*::rem_euclid
- i*::wrapping_div
- i*::wrapping_div_euclid
- i*::wrapping_rem
- i*::wrapping_rem_euclid
- u*::checked_div
- u*::checked_div_euclid
- u*::checked_rem
- u*::checked_rem_euclid
- u*::div_euclid
- u*::overflowing_div
- u*::overflowing_div_euclid
- u*::overflowing_rem
- u*::overflowing_rem_euclid
- u*::rem_euclid
- u*::wrapping_div
- u*::wrapping_div_euclid
- u*::wrapping_rem
- u*::wrapping_rem_euclid

</div><details>

## 1.53.0 (2021-06-17)
### Add the BITS associated constant to all numeric types.
数値型(`i32`や`f64`)に`BITS`という定数が追加されました。

## 1.54.0 (2021-07-29)
### You can now cast between unsized slice types (and types which contain unsized slices) in const fn.
サイズが不明なsliceからサイズが不明なsliceに変換可能になります
↓こういうことができるようになるらしいですが何に使えるのかよくわかってないです。

```rust
const fn test() {
    let _x = NonNull::<[i32; 0]>::dangling() as NonNull<[i32]>;
}
```

## 1.55.0 (2021-09-09)
### The following previously stable functions are now const.
以下の関数が`const fn`になりました

- `str::from_utf8_unchecked`

```rust
fn main() {
    const SPARKLE_HEART_ARRAY: [u8; 4] = [240, 159, 146, 150];
    const SPARKLE_HEART: &str = unsafe { std::str::from_utf8_unchecked(&SPARKLE_HEART_ARRAY) };

    assert_eq!("💖", SPARKLE_HEART);
}
```
[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=fn%20main()%20%7B%0A%20%20%20%20const%20SPARKLE_HEART_ARRAY%3A%20%5Bu8%3B%204%5D%20%3D%20%5B240%2C%20159%2C%20146%2C%20150%5D%3B%0A%20%20%20%20const%20SPARKLE_HEART%3A%20%26str%20%3D%20unsafe%20%7B%20std%3A%3Astr%3A%3Afrom_utf8_unchecked(%26SPARKLE_HEART_ARRAY)%20%7D%3B%0A%0A%20%20%20%20assert_eq!(%22%F0%9F%92%96%22%2C%20SPARKLE_HEART)%3B%0A%7D%0A)

## 1.56.0 (2021-10-21)
### Union field access is permitted in `const fn`.
`const fn`の中で`Union`のフィールドにアクセスできるようになりました。

### These APIs are now usable in const contexts:
下記の関数が`const`文脈で使用可能になりました。

- `std::mem::transmute`
- `[T]::first`
- `[T]::split_first`
- `[T]::last`
- `[T]::split_last`

## 1.57.0 (2021-12-02)
### `Allow panicking in constant evaluation.`
`const`文脈の中で`panic!`マクロが使用できるようになりました。

```rust
const fn div(a: i32, b: i32) -> i32 {
    if b == 0 { panic!("b is 0"); }
    a / b
}

fn main() {
    const V1: i32 = div(10, 5);
    const V2: i32 = div(1, 0);  // panic
}
```
`panic!`に渡した文字列もコンパイルエラーのメッセージに表示されます。
[Rust Playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&code=const%20fn%20div(a%3A%20i32%2C%20b%3A%20i32)%20-%3E%20i32%20%7B%0A%20%20%20%20if%20b%20%3D%3D%200%20%7B%20panic!(%22b%20is%200%22)%3B%20%7D%0A%20%20%20%20a%20%2F%20b%0A%7D%0A%0Afn%20main()%20%7B%0A%20%20%20%20const%20V1%3A%20i32%20%3D%20div(10%2C%205)%3B%0A%20%20%20%20const%20V2%3A%20i32%20%3D%20div(1%2C%200)%3B%20%20%2F%2F%20panic%0A%7D)

### These APIs are now usable in const contexts:
下記の関数が`const`文脈で使用可能になりました。

- `hint::unreachable_unchecked`


## まとめ
多くの関数や機能が`const`文脈で使えるようになってきました。
この調子でどんどん実行時にできることと`const`文脈でできることの差を縮めて欲しいです。
`impl const Trait for Ty`とか早く使えるようになると嬉しいです。