A Rust csapata pontosan a szokott hat hetes ütemben szállított: 2023. augusztus 24-én jelent meg a Rust 1.72, és ahogy az lenni szokott, a rustup már most is simán felhozza a gépedet erre a verzióra. Ez nem egy hatalmas, feature-dús release volt, mint amikor a GATs vagy a let-else landolt, hanem inkább egy „minőségi életet javító” kiadás – de két apróság van benne, amit érdemes közelebbről megnézni, mert a napi munkádban is előbukkanhat.
A const-eval lépésszám limit eltávolítása
Ha már írtál const fn-t, ami valamit ciklusban számol, valószínűleg belefutottál már abba a kellemetlen hibaüzenetbe, hogy „reached the configured maximum number of steps” – vagyis a fordító feladta a const kiértékelést, mert túl sok lépésen ment keresztül. Ez egy védőháló volt, hogy a fordítás ne fusson vég nélkül egy hibás vagy szándékosan gonosz const kifejezés miatt.
A Rust 1.72-ben ez a mesterséges lépésszám-limit eltűnt. A const evaluator mostantól addig fut, amíg tényleg szükséges, nincs beégetett plafon. Ez azt jelenti, hogy bátrabban írhatsz komplexebb, ciklusokkal, rekurzióval dolgozó const fn-eket, anélkül hogy a fordító időnként közbeszólna.
const fn fibonacci(n: u64) -> u64 {
let mut a = 0u64;
let mut b = 1u64;
let mut i = 0;
while i < n {
let tmp = a + b;
a = b;
b = tmp;
i += 1;
}
a
}
// Korábban nagy N esetén könnyen belefutottál a lépésszám-limitbe.
// A Rust 1.72-től ez már nem korlátoz.
const FIB_90: u64 = fibonacci(90);
fn main() {
println!("A 90. Fibonacci-szám: {}", FIB_90);
}
A limit eltávolítása nem jelenti azt, hogy a fordítási idő ingyen van. Ha egy const kifejezés tényleg brutálisan sok lépést igényel, a fordítás lassabb lesz – de legalább nem hasal el egy önkényes plafon miatt, hanem tényleg lefut.
Ez különösen jól jön, ha no_std környezetben, embedded projektekben vagy compile-time táblázatgenerálásnál dolgozol, ahol a const kiértékelés valódi munkaeszköz, nem csak apró trükk.
Jobb diagnosztika a cfg-attribútumoknál
A másik nagy nyereség a #[cfg(...)] körüli hibaüzenetek finomítása. Eddig, ha elgépelted egy feature nevét, vagy egy target-specifikus cfg-t írtál rosszul, a fordító egyszerűen csendben kihagyta az adott kódágat – nem fordítási hiba lett belőle, hanem futásidejű meglepetés, amikor rájöttél, hogy egy egész funkció hiányzik a bináriból.
A Rust 1.72 ezen javít: a cfg-kkel kapcsolatos figyelmeztetések most sokkal informatívabbak, és jobban jelzik, ha egy cfg-predikátum soha nem teljesül, vagy ha gyanús, nem ismert kulcsot használsz.
#[cfg(feature = "experimetal")] // elgépelés: hiányzik egy 'n'
fn kiserleti_funkcio() {
println!("Ez sosem fog lefutni, ha a Cargo.toml-ban 'experimental' van");
}
fn main() {
#[cfg(not(feature = "experimetal"))]
println!("A cfg-diagnosztika most segít elkapni az ilyen elgépeléseket");
}
Ha Cargo.toml-ban definiált feature-öket használsz cfg(feature = "...") formában, a Cargo és a Rust fordító mostantól közösen jobban rá tud szólni, ha egy nem létező feature-re hivatkozol. Érdemes időnként lefuttatni egy cargo check --all-features-t, hogy biztosan minden cfg-ág életképes legyen.
Ez nem egy látványos nyelvi feature, de aki már dolgozott multi-platform crate-en (mondjuk #[cfg(target_os = "linux")] és #[cfg(target_os = "windows")] ágakkal), tudja, mennyire idegtépő tud lenni egy néma cfg-hiba felkutatása. Most legalább a fordító nagyobb eséllyel szól, mielőtt te magad bukkansz rá production-ben.
Mit jelent ez a gyakorlatban?
Ha nem írsz extrém const kifejezéseket vagy bonyolult cfg-mátrixokat, a Rust 1.72 nem fog radikálisan megváltoztatni semmit a napi munkádban – és ez oké. A Rust release-ciklusa pont attól stabil és megbízható, hogy nem minden hat hét hoz földrengést. Amit viszont mindenképp érdemes szem előtt tartani:
- Ha korábban kompromisszumokat kötöttél a const-eval limit miatt (pl. kisebb lookup táblát generáltál compile-time-ban, mint amit szerettél volna), most újra megnézheted, hogy a teljes megoldás belefér-e.
- Ha a crate-ed sok feature flag-et és
cfg-t használ, most jobb eséllyel kapod el az elgépeléseket és a soha nem teljesülő ágakat márcargo checkszinten. - A
GATs, alet-elseszintaxis és azOnceCell/OnceLocktovábbra is stabil, jól bevált eszközök – ha még nem próbáltad ki azOnceLock-ot lazy statikus inicializáláshoz, most jó alkalom lehet rá.
use std::sync::OnceLock;
static KONFIG: OnceLock<String> = OnceLock::new();
fn get_konfig() -> &'static str {
KONFIG.get_or_init(|| {
println!("Konfiguráció betöltése egyszer...");
String::from("production")
})
}
fn main() {
println!("{}", get_konfig());
println!("{}", get_konfig()); // már nem inicializál újra
}
Hogyan frissíts
A frissítés, mint mindig, egyetlen paranccsal elintézhető:
rustup update stable
Ez behúzza a 1.72-es toolchaint, és ha a stable a defaultod, automatikusan azt fogja használni a cargo build is. Érdemes ellenőrizni a verziót:
rustc --version
# rustc 1.72.0 (5680fa18f 2023-08-23)
Ha CI/CD pipeline-ban rögzített toolchain verziót használsz (rust-toolchain.toml fájlban), ne feledd frissíteni azt is, különben a lokális gépeden más viselkedést kaphatsz, mint a build szerveren.
Összefoglalás
A Rust 1.72 nem egy hangos, feature-parádés release, hanem egy csendes, de fontos karbantartás: eltűnt egy mesterséges korlát a const-eval-ból, és okosabb lett a cfg-diagnosztika. Mindkettő abba az irányba mutat, amit a Rust csapata már évek óta csinál – kevesebb meglepetés, több segítség a fordítótól, mielőtt a hiba futásidőben csapna le rád. Ha még nem tetted meg, futtasd le a rustup update stable-t, és élvezd a simább const-eval élményt.