Přeskočit na obsah
Tech-Blog Chatujme.cz Chatujme.cz
Programování

Rust stabilizoval typ never, do stabilního vydání se dostane až v listopadu

Vykřičník je v Rustu typ, který nemá jedinou hodnotu, a na plné použití na stabilním překladači čeká od července 2015. Změnu, která ho tam pouští, sloučili vývojáři jazyka 24. srpna 2026. Platí se za ni nekompatibilní změnou odvozování typů, která se nově týká i starších edicí jazyka.

· 55 zhlédnutí

Makro snímek obrazovky s kódem v Rustu, vidět jsou metody reset a register_tap a výraz match s větvemi Some a None
Detail kódu v Rustu na obrazovce. Kdyby se do některé z větví výrazu match uprostřed napsalo panic!(), dosadí za ni překladač typ never. Foto: Slashme, Wikimedia Commons (CC0)

Vykřičník na místě návratového typu znamená v Rustu, že se funkce normálním návratem nikdy neskončí. Shodí program panikou, zavolá std::process::exit, nebo se zacyklí. Ten vykřičník je přitom sám o sobě typ. Jmenuje se never a je to typ, do kterého se nedá uložit žádná hodnota, protože žádná hodnota toho typu neexistuje.

fn konec() -> ! {
    panic!("dál to nejde");
}

Návrh, který z vykřičníku měl udělat plnohodnotný typ, nese datum 19. července 2015 a v repozitáři překladače k němu od července 2016 visel sledovací záznam. Zavřel se 24. srpna 2026, kdy se do hlavní větve sloučila změna od vývojáře vystupujícího jako WaffleLapkin. Do té doby se ! mimo návratový typ funkce – tedy jako parametr generika nebo položka struktury – dal psát jen na vývojovém kanálu nightly a za přepínačem #![feature(never_type)].

Odvozování, kvůli kterému to trvalo

Sám typ problém nebyl. Potíž dělá odvozování, kterému se v Rustu říká never type fallback. Když překladač narazí na hodnotu typu ! tam, kde se čeká něco jiného, smí ji přetypovat na cokoli – ta hodnota totiž nemůže vzniknout, takže na výsledku nezáleží. Občas ale nemá z čeho poznat, na co ji vlastně převádí, a musí si nějaký typ dosadit sám. Léta dosazoval prázdnou n-tici ().

V edici 2024 už si na tom místě dosazuje !. Srpnová změna to rozšiřuje na všechny starší edice a právě tohle je ta nekompatibilní část. Projeví se hlavně u operátoru ?:

fn x<T: Default>() -> Result<T, ()> { Ok(T::default()) }

x()?;   // dřív se za T dosadilo (), nově !

Typ ! ovšem trait Default neimplementuje, takže se takový řádek přestane překládat. Opravou je typ vypsat: x::<()>()?;, nebo () = x()?;.

Sedm balíčků přímo, zbytek přes staré závislosti

Kolik cizího kódu změna rozbije, se v Rustu měří nástrojem crater, který zkusí přeložit balíčky z registru crates.io. Rozbor toho běhu je z 21. dubna 2026 a autor v něm počítá kolem tří tisíc pádů. Přímo, tedy vlastním kódem, jich ale selhalo sedm: mezi nimi čtyři balíčky, které volají knihovnu redis bez uvedení typu vrácené hodnoty, a jeden test v srt-tokio.

Všechno ostatní jsou balíčky, které do překladu vtáhla stará verze závislosti. Autor u nich píše, že opravená novější verze existuje prakticky u všech, a připomíná, že varování na tenhle vzorec chodí dlouho: ve vlastním kódu od změny 125289, v závislostech od změny 141937, tedy podle jeho slov skoro rok. Sám k tomu dodává, že delším čekáním by se čísla nejspíš nezlepšila.

Dvakrát už to stabilizované bylo

První pokus to není. V dubnu 2018 se stabilizace ! a traitu TryFrom vrátila zpět kvůli chybě, která souvisela právě s dosazováním typů. Podruhé se ! stabilizoval pro vydání 1.41: změna se sloučila 21. listopadu 2019 a 15. prosince téhož roku ji vývojáři zase vzali zpět, protože se objevily regrese.

Ve standardní knihovně ubyl jeden samostatný typ

Se stabilizací se mění i standardní knihovna. Typ Infallible, kterým se označuje chyba, jež nemůže nastat, je nově jen jiné jméno pro !. Lint dependency_on_unit_never_type_fallback mizí, protože po změně odvozování nemá na co upozorňovat. Úklid po stabilizaci se sloučil 28. srpna 2026.

Ke stabilnímu překladači to dorazí 12. listopadu

Změna má v repozitáři milník 1.100.0. Podle plánu vydání se větev pro tuhle verzi oddělí od hlavní 25. září 2026 a stabilní vydání vyjde 12. listopadu 2026. Zatím je stabilní verzí 1.98 z 20. srpna, takže kdo nepoužívá nightly, na vykřičník ještě čeká.

Až se změna dostane ven, přestanou být potřeba prázdné výčty typu enum Never {}, kterými se ! na stabilním překladači obcházel. A zápis Result<T, !> začne říkat přesně to, jak vypadá: tahle funkce chybu vrátit nemůže.

Zdroje

Programování

Rust překladače typové systémy

← zpět na výpis