この記事はRust Advent Calendar 2022の18日目の記事です。
昨日は @MaaSaHero さんのRustでAmazon商品URLの不要部分削除するCLI作ったでした。
去年に続き2022年のconst関係の更新をまとめました。
英語がそれほど得意ではないので抜け漏れ間違いがあれば指摘いただけると助かります。
内容はリリースノートを参考にしており確認しているバージョンは 1.58.0 (2022-01-13)から1.66.0 (2022-12-15)までです。
Language
1.58.0
*const T pointers can now be dereferenced in const contexts.
定数文脈で*const T
を逆参照できるようになった。
ただし*mut T
のようなミュータブルな参照は逆参照できない。
1.59.0
Stabilize default arguments for const parameters and remove the ordering restriction for type and const parameters
- const genericsのデフォルト値を設定できるようなった
- genericsパラメーターの順番がライフタイム→型→定数と固定だったのをライフタイム→型or定数とできるようになった
1.61.0
const fn signatures can now include generic trait bounds
const fn
の中で関数ポインタの作成、返却、キャストを可能にした。
関数ポインタから整数型へ変換や関数ポインタの呼び出しは不可。
作成と返却
const fn get_function() -> fn() {
fn foo() {
println!("Hello, World!");
}
foo
}
キャスト
const fn get_function() -> fn() {
unsafe {
std::mem::transmute(0x1234usize)
}
}
ただし以下のような関数ポインタから整数への変換はできない
const fn fn_to_usize(f: fn()) -> usize {
f as usize //~ pointers cannot be cast to integers during const eval
}
以下のような関数ポインタの呼び出しもできない
const fn call_fn_ptr(f: fn()) {
f() //~ function pointers are not allowed in const fn
}
const fn signatures can now use impl Trait in argument and return position
const fn
の中でtrait bounds(ジェネリクス境界)を使用できるようになりdyn Trait
オブジェクトの受け渡しが可能になった。
const fn do_thing<T: Foo>(_x: &T) {
// ...
}
ただしTraitの関数をconst fn
として定義できないためTraitの関数呼び出しはできない。
Function pointers can now be created, cast, and passed around in a const fn
const fn
の引数と戻り値でimpl Trait
が使用可能になった。
const fn do_thing(x: impl Foo) -> impl Foo {
x
}
ただし関連型や関連定数にアクセスする以上のことはできない。
1.62.0
Fix constants not getting dropped if part of a diverging expression
特定の条件でdropが呼ばれないことがあったが修正された。
以下のコードはcba
と出力されるが修正前はca
と出力されていた。
struct Print(&'static str);
impl Drop for Print {
fn drop(&mut self) {
println!("{}", self.0);
}
}
const A: Print = Print("a");
const B: Print = Print("b");
fn main() {
loop {
std::mem::forget(({A}, B, Print("c"), break));
}
}
const functions may now specify extern "C" or extern "Rust"
以下のようにconst fn
にextern
, extern "C"
, extern "Rust"
をつけた定義ができるようになった。
const extern fn foo1() {}
const extern "C" fn foo2() {}
const extern "Rust" fn foo3() {}
const unsafe extern fn bar1() {}
const unsafe extern "C" fn bar2() {}
const unsafe extern "Rust" fn bar3() {}
1.66.0
Change constant evaluation errors from a deny-by-default lint to a hard error
定数文脈の評価時のエラーをリントのdenyからコンパイルエラーに変更した。
Stabilized APIs
以下のAPIが安定化した。
1.65.0
These APIs are now usable in const contexts:
以下のAPIが定数文脈で使用可能になった。
1.58.0
Duration::new
Duration::checked_add
Duration::saturating_add
Duration::checked_sub
Duration::saturating_sub
Duration::checked_mul
Duration::saturating_mul
Duration::checked_div
1.61.0
<*const T>::offset
and<*mut T>::offset
<*const T>::wrapping_offset
and<*mut T>::wrapping_offset
<*const T>::add
and<*mut T>::add
<*const T>::sub
and<*mut T>::sub
<*const T>::wrapping_add
and<*mut T>::wrapping_add
<*const T>::wrapping_sub
and<*mut T>::wrapping_sub
<[T]>::as_mut_ptr
<[T]>::as_ptr_range
<[T]>::as_mut_ptr_range
1.63.0
array::from_ref
slice::from_ref
intrinsics::copy
intrinsics::copy_nonoverlapping
<*const T>::copy_to
<*const T>::copy_to_nonoverlapping
<*mut T>::copy_to
<*mut T>::copy_to_nonoverlapping
<*mut T>::copy_from
<*mut T>::copy_from_nonoverlapping
str::from_utf8
Utf8Error::error_len
Utf8Error::valid_up_to
Condvar::new
Mutex::new
RwLock::new
1.64.0
1.65.0
Const-stable:
以下のAPIが定数文脈でも使用可能になった。
1.59.0
mem::MaybeUninit::as_ptr
mem::MaybeUninit::assume_init
mem::MaybeUninit::assume_init_ref
ffi::CStr::from_bytes_with_nul_unchecked
Compatibility Notes
1.64.0
Errors at const-eval time are now in future incompatibility reports
将来的に定数文脈の評価時のエラーをリントのdenyからコンパイルエラーに変更するのでその前に将来エラーになるということを表示する。
補足: これは1.66.0の更新内容のChange constant evaluation errors from a deny-by-default lint to a hard errorの前段階の更新です。
所感
かなりできることが増えましたね。
Stabilized APIsとして追加されたAPIが最初からconst fn
だったものなどはここに書いていないので実際はこれより多くのことが定数文脈でできるようになっています。すごいですね。
個人的にはStabilize default arguments for const parameters and remove the ordering restriction for type and const parametersでジェネリクスパラメーターの順番の自由度が上がったのが嬉しいです。
Traitの関数をconst fn
にできる(const_trait_impl
)更新は今年は来ませんでしたね。来年こそ来てくれると嬉しいです。
明日は@serinuntiusさんです。