#prog #rust #rustlib #article
Surelock
Работает и на no_std, полагается на lock_api для абстрагирования от реализации взаимной блокировки.
Surelock
Deadlocks are a solved problem in theory — we’ve known how to prevent them since 1971. The challenge is making that prevention ergonomic enough that people actually use it. Surelock is my attempt at that: lean into Rust’s type system to make the correct thing the easy thing, and make the wrong thing a compiler error.
Работает и на no_std, полагается на lock_api для абстрагирования от реализации взаимной блокировки.
👍6
#prog #rust #rustreleasenotes
Вышла версия Rust 1.95.0! Как всегда, тут только выдержки, всё остальное в детальных заметках о релизе.
▪️
▪️Частично примыкающее изменение: компилятор больше не выдаёт предупреждение на безусловные паттерны в
Эта идиома позволяет привязать значение и что-то сделать/проверить с ним и при этом не пустить имя в окружающую область видимости.
▪️Добавили новый макрос cfg_select!, который позволяет сделать подобие
Технически этот макрос не даёт новых возможностей, но без него нужные атрибуты
▪️Навряд ли кого-то коснётся, но:
▪️Поддержку части платформ подняли до Tier 2 — в основном встраиваемые ARM-платформы от Apple (и их симуляторные версии).
▪️Стабилизированы несколько API, в частности:
🔸Конверсии по ссылке из
🔸Аналогичные конверсии по ссылке между массивами в
🔸Модуль core::range, в котором собираются диапазоны, планируемые на замену текущим. Пока что стабилизированы только RangeInclusive и его итератор. В отличие от текущих диапазонов, новый тип не служит одновременно итератором и потому реализует
🔸Функция core::hint::cold_path для пометки пути исполнения, который не предполагается, что будет часто исполняться. Этакая замена
▪️rustdoc теперь предпочитает стабильные определения нестабильным при сортировке результатов поиска.
Вышла версия Rust 1.95.0! Как всегда, тут только выдержки, всё остальное в детальных заметках о релизе.
▪️
if-гуарды на ветках match теперь могут использовать if let:match value {
Some(x) if let Ok(y) = compute(x) => {
// Both `x` and `y` are available here
println!("{}, {}", x, y);
}
_ => {}
}▪️Частично примыкающее изменение: компилятор больше не выдаёт предупреждение на безусловные паттерны в
if let. Автор изменения мотивирует это распространением кода навроде такого:fn main() {
if let x = funx() && x < usize::MAX {
// use x
}
}Эта идиома позволяет привязать значение и что-то сделать/проверить с ним и при этом не пустить имя в окружающую область видимости.
▪️Добавили новый макрос cfg_select!, который позволяет сделать подобие
match, но для cfg-предикатов:cfg_select! {
unix => {
fn foo() { /* unix specific functionality */ }
}
target_pointer_width = "32" => {
fn foo() { /* non-unix, 32-bit functionality */ }
}
_ => {
fn foo() { /* fallback implementation */ }
}
}
let is_windows_str = cfg_select! {
windows => "windows",
_ => "not windows",
};Технически этот макрос не даёт новых возможностей, но без него нужные атрибуты
#[cfg] нужно выписывать самостоятельно, дублируя дословно все предикаты. Ровно по этой причине стал распространён и используется cfg-if — собственно, объявление в блоге напрямую на него и ссылается.▪️Навряд ли кого-то коснётся, но:
match по enum теперь всегда ведёт себя так, как будто он читает дискриминант. Это кажется странным, но объясняется #[non_exhaustive]. Без этого изменения то, есть ли в некотором unsafe-коде UB или нет, зависело от того, определён ли enum в текущем крейте или в другом. Также match теперь читает дискриминант, даже если только одна ветка населена — без этого изменения поведение различалось в обобщённом коде и в ручной мономорфизации.▪️Поддержку части платформ подняли до Tier 2 — в основном встраиваемые ARM-платформы от Apple (и их симуляторные версии).
▪️Стабилизированы несколько API, в частности:
🔸Конверсии по ссылке из
MaybeUninit-массивов в массивы и слайсы из MaybeUninit, а также конверсии по значению между ними🔸Аналогичные конверсии по ссылке между массивами в
Cell и массивами из Cell🔸Модуль core::range, в котором собираются диапазоны, планируемые на замену текущим. Пока что стабилизированы только RangeInclusive и его итератор. В отличие от текущих диапазонов, новый тип не служит одновременно итератором и потому реализует
Copy (при Copy-индексах, разумеется) и занимает меньше места: ему не нужно хранить состояние для отслеживания поведения на последней итерации, только два индекса.🔸Функция core::hint::cold_path для пометки пути исполнения, который не предполагается, что будет часто исполняться. Этакая замена
likely/unlikely.▪️rustdoc теперь предпочитает стабильные определения нестабильным при сортировке результатов поиска.
🎉9❤2🔥1🥰1
#prog #itsec #rust #article
Bugs Rust Won't Catch
Bugs Rust Won't Catch
In April 2026, Canonical disclosed 44 CVEs in uutils, the Rust reimplementation of GNU coreutils that ships by default since 25.10. Most of them came out of an external audit commissioned ahead of the 26.04 LTS.
I read through the list and thought there’s a lot to learn from it.
What’s notable is that all of these bugs landed in a production Rust codebase, written by people who knew what they were doing, and none of them were caught by the borrow checker, clippy lints, or cargo audit.
<...>
If you write systems code in Rust, this is the most concentrated look at where Rust’s safety ends that you’ll likely find anywhere right now.
❤4🥰2🍌1
#prog #rust #cpp #article
How (and why) we rewrote our production C++ frontend infrastructure in Rust
"Фронтенд" в данном случае означает прокси-сервер, если что.
How (and why) we rewrote our production C++ frontend infrastructure in Rust
"Фронтенд" в данном случае означает прокси-сервер, если что.
“Should we convert our _ code to Rust?” is a question that comes up a lot. And a lot of the time the right answer is a pretty firm, “No.” So I thought it might be beneficial (and hopefully interesting) to walk through a case where the code involved was incredibly you-cannot-fuck-this-up business-critical and when we asked that question about it, we came back with a yes. Here’s what it was, how we got to that answer, and what we did about it.
The bottom line is that C++ has caused more than a few situations where we wanted to do something or add a feature and it’s just like… that’s a cool idea, but it’s just not worth the uphill battle against the language. And it was to the point where any change carries the risk of unforeseen consequences.
👍1🥰1😁1
#prog #rust #article
stable specialization in Rust
TL;DR: Iterator::fuse возвращает адаптер, который на вызовах
stable specialization in Rust
TL;DR: Iterator::fuse возвращает адаптер, который на вызовах
.next() после возврата None продолжает возвращать None. Однако для типов, реализующих FusedIterator (то есть тех, кто уже обещает данное поведение), этот адаптер не отслеживает вызовы и просто вызывает .next() у нижележащего типа напрямую. Можно реализовать FusedIterator для своего типа, сделав её условной по предикату, который мы хотим проверить специализацией (например, реализует ли тип Send), и в реализации не соблюсти этот контракт. Тогда можно вызвать на этом типе, обёрнутом в Fuse, метод next() два раза, проверить, сколько раз next() был вызван реально, и тем самым получить ответ на предикат.doc.rust-lang.org
Iterator in std::iter - Rust
A trait for dealing with iterators.
🤔6😭6👍3😁2❤1