programmatūra · 6 min · 09.09.2026

Rust never tips kļūst stabils pēc desmit gadiem: crater atrada 3277 regresijas

Rust kompilatora repozitorijā 24. augustā tika iekļauts pieprasījums #155499, kas stabilizē never tipu !. Kods nonāks laidienā 1.100.0. Astoņpadsmit komiti maina 428 failus, pievieno 1798 rindas un dzēš 3635.

Priekšlikumu RFC 1216 Rust komanda pieņēma 2015. gadā, izsekošanas problēmu #35121 atvēra 2016. gada jūlijā. Kopš tā laika bija pieci stabilizācijas mēģinājumi un visi pieci apstājās. Sesto aizvadīja izstrādātājs ar segvārdu WaffleLapkin, kurš pie tā strādāja vairāk nekā divus gadus.

Mēģinājumu pēdas paliek atvērtas līdz šai dienai. 2018. gada 21. janvārī canndrew iesniedza pieprasījumu #47630 ar nosaukumu “Stabilise feature(never_type)”, kas tipa atzarošanas daļu atdalīja karodziņā exhaustive_patterns. 2019. gada februārī parādījās atsevišķa problēma #58184 “Stabilize (only) the never type”. Valodas komandai bija sava lieta #60 tajā pašā jautājumā. Katrā no tām saruna beidzās vienā punktā: kamēr atkāpšanās tips nav sakārtots, tipu stabilizēt nedrīkst.

Kas ir never tips

! ir tips bez vērtībām. Nav nevienas izteiksmes, kuras rezultātu varētu ielikt mainīgajā ar šādu tipu, jo tādas vērtības neeksistē. Tipu iegūst kods, kas nekad neatgriežas: panic!(), return, break, continue un std::process::exit().

Praktiskais ieguvums ir tas, ka ! pārvēršas jebkurā citā tipā. Tāpēc kompilē rinda let x: i32 = if ok { 5 } else { return };. Otrs zars i32 nedod, bet tas arī neko neatgriež, tāpēc kompilators drīkst to uzskatīt par i32 bez pārbaudes. Līdz šim stabilajā Rust ! drīkstēja rakstīt tikai funkcijas atgriežamā tipa vietā. Mainīgā anotācijā vai ģenērikā to ielikt prasīja karodziņu #![feature(never_type)] un nakts kompilatoru.

Tāpēc bibliotēkās izauga apvedceļi. Kas gribēja pateikt, ka funkcija kļūdu nekad nedod, rakstīja Result<T, Infallible> vai definēja savu tukšo enum. Katrai pakotnei sanāca sava tukšā tipa versija un savā starpā šie tipi nesarunājās.

Aizķērās pie atkāpšanās tipa

Kad kompilators pārveidošanas vietā ierauga !, tas ievieto pāreju uz jaunu inferences mainīgo. Ja neviens cits kods šo mainīgo neierobežo, kompilatoram tomēr jāizvēlas kāds tips. Vēsturiski izvēle bija (), tukšais kortežs. Šī izvēle nekad nebija aprakstīta kā valodas daļa un tieši tā turēja stabilizāciju: ! pēkšņi kļuva par () arī tur, kur kompilators pats no sevis () nekad nesecinātu.

Rust 1.85 atkāpšanās tipu nomainīja uz !, bet tikai 2024. gada izdevumā. Stabilizācija prasīja to pašu visos izdevumos. Izdevumu rokasgrāmata parāda, kāds kods no tā salūzt. Ģenēriskā funkcijā ar ? operatoru tipa parametrs agrāk atkāpās uz (), tagad tas atkāpjas uz !. Ja parametram uzlikta prasība Default vai kāda cita ieviešana, ko ! nepilda, būvējums apstājas.

Otrs biežais gadījums ir aizvērums, kas tikai panikē. Izsaukums run(|| panic!()) vairs neiet cauri, ja funkcija prasa atgriežamo tipu ar kādu iezīmi. Risinājums abos gadījumos ir viens: uzrakstīt tipu ar roku. Der f::<()>()?, der arī () = f()? vai aizvērumam || -> () { panic!() }. Automātiska pārrakstīšana nav pieejama.

crater uzrādīja 3277 regresijas

Pirms iekļaušanas komanda palaida crater, rīku, kas ar veco un jauno kompilatoru pārbūvē visas crates.io pakotnes un publiskos GitHub projektus. Atskaite uzrādīja 3277 regresijas. Aptuveni 1149 no tām bija viltus trāpījumi, kas krīt arī bez ielāpa. Paliek nedaudz vairāk par diviem tūkstošiem pakotņu, kurām jāpieliek tipa anotācija.

Divi tūkstoši pakotņu izklausās daudz, bet labojums lielākoties ir vienas rindas garš. Rust komanda regresijas šķiro pēc tā, vai koda autors var to salabot pats un vai labojums strādā arī ar vecāku kompilatoru. Abas atbildes šeit ir apstiprinošas: tipa anotācija () = f()?; kompilējas arī uz 1.85 un vecāku, tāpēc pakotnes autoram nav jāceļ minimālā atbalstītā versija.

Brīdinājums par šo lūzumu kodā stāvēja kopš 1.85 ar nosaukumu dependency_on_unit_never_type_fallback. Tagad tas ir izmests, jo brīdināt vairs nav par ko. Vietā paliek never_type_fallback_flowing_into_unsafe, kas pēc noklusējuma ir deny līmenī. Tas ķer gadījumus, kad atkāpšanās tips ieplūst unsafe blokā un ietekmē, cik baitu kods nolasa.

Pats WaffleLapkin bloga ierakstā tajā pašā dienā rakstīja, ka gandarījumu nejūt.

Es jūtos tukšs. Tieši tāpat kā never tips.

Infallible pārtop par aliasu

Stabilizācija maina arī standarta bibliotēku. std::convert::Infallible gadiem bija enum bez variantiem. Tagad tas ir tipa alias uz !. Rīks cargo-semver-checks šo pārmaiņu atzīmēja kā API lūzumu, jo publisks enum kļūst par publisku type. Recenzents pieprasījumā atbildēja, ka komanda uz šo brīdi gājusi gadiem un izlaidīs cauri.

Kods, kas raksta type Error = Infallible;, turpina strādāt. Mainās tas, ka Infallible un ! tagad ir viens tips, tāpēc atzarošana pār tukšu kļūdu vairs neprasa neiespējamu zaru. Kopā ar stabilizāciju no bibliotēkas izņemta rezervētā From<!> for T ieviešana, kas gaidīja tieši šo laidienu.

Kad tas nonāks līdz kodam

Nakts kompilators ! pieņem kopš 24. augusta. Tajā pašā laidienā 1.100.0 saraksta ir vēl deviņi punkti, starp tiem bool::toggle, veselo skaitļu minimuma un maksimuma iekšējās funkcijas un labojums tam, kā if let aizvērumā tver mainīgos.

Zars 1.100.0 no galvenā atdalīsies 25. septembrī. Stabilais laidiens iznāks 12. novembrī, deviņas nedēļas pēc šodienas.

Avoti

komentārisaruna

Komentāri

Šim rakstam vēl nav komentāru. Esi pirmais, kurš dalās ar savu viedokli.

Pievieno komentāru

Tavs e-pasts netiks publicēts. Obligātie lauki atzīmēti.

vēl no programmatūrasaistītie