#prog #rust #rustreleasenotes
Вышла версия Rust 1.90.0!.. Больше недели назад. В свою защиту могу сказать, что в этой версии заметных для большинства пользователей изменений в языке и нету.
Как всегда, тут только избранные части, всё остальное в детальных заметках о релизе.
▪️Как и было обещано, для таргета
▪️В качестве расширения к методам, добавленным в Rust 1.66.0, добавили методы
▪️
▪️Старый PR докатился до стейбла: в const-контексте наконец можно вызывать
▪️Реализацию
▪️Реализации
▪️Компилятор теперь не даёт скомпилировать код, который упоминает ABI, неподдерживаемый на целевой платформе.
Вышла версия Rust 1.90.0!.. Больше недели назад. В свою защиту могу сказать, что в этой версии заметных для большинства пользователей изменений в языке и нету.
Как всегда, тут только избранные части, всё остальное в детальных заметках о релизе.
▪️Как и было обещано, для таргета
x86_64-unknown-linux-gnu теперь по умолчанию используется более быстрый линкер lld.▪️В качестве расширения к методам, добавленным в Rust 1.66.0, добавили методы
uX::*_sub_signed (wrapping, checked, overflowing и saturating варианты) для корректного вычитания чисел с разной знаковостью.▪️
CString, CStr и Cow<CStr> теперь можно сравнивать на равенство между собой. Нет, PartialOrd между ними не реализован. Нет, я не знаю, почему.▪️Старый PR докатился до стейбла: в const-контексте наконец можно вызывать
reverse на слайсах. Также теперь там можно вызывать на числах с плавающей точкой различные методы для округления и fract для извлечения дробной части.▪️Реализацию
Default для iter::Fuse привели в соответствие с документацией: теперь default создаёт Fuse, оборачивающий значение по умолчанию внутреннего итератора, вместо создания всегда пустого итератора.▪️Реализации
io::Write для TcpStream и UnixStream теперь на Linux пишут данные с флагом MSG_NOSIGNAL. Это означает, что запись в померший нижележащий сокет теперь возвращает EPIPE — или, в терминах Rust, io::Error, у которого kind() возвращает ErrorKind::BrokenPipe. Данное изменение делает поведение консистентным с тем, как сокеты ведут себя в других местах в std.▪️Компилятор теперь не даёт скомпилировать код, который упоминает ABI, неподдерживаемый на целевой платформе.
👍6❤1
#prog #rust #article
From Rust to Reality: The Hidden Journey of fetch_max
From Rust to Reality: The Hidden Journey of fetch_max
Why would Rust providefetch_maxas a built-in intrinsic? Intrinsics usually exist to leverage specific hardware instructions. But x86-64 doesn't have anatomic maxinstruction. So there had to be a CAS loop somewhere in the pipeline.
<...>
So I started digging. What I found was a fascinating journey through five distinct layers of compiler transformations, each one peeling back another level of abstraction, until I found exactly where that loop materialized. Let me share what I discovered.
❤3
#prog #rust #rustlib #ml #abnormalprogramming
unwrap_or_ai
unwrap_or_ai
Tired of manually handling unwrap() results? Let AI do the heavy lifting!
🤩19🤡2
#prog #cpp #rust #article
Why we didn't rewrite our feed handler in Rust
Отдельно отмечается, что Rust в технологическом стеке в этой компании уже есть и успешно используется. Проблемы возникли с переписыванием конкретного компонента, который уже есть и написан на C++. Конкретно в тексте приведены три паттерна, которые валидны в C++ и не выразимы или выразимы неудобно на Rust.
Первое касается ограничений borrow checker-а. Вот какой пример приводят:
Простой и понятный код — но, к сожалению, выделяющий память в цикле. Логично было бы вынести аллокацию за цикл и очищать буфер в конце — но тогда компилятор не даёт скомпилировать код:
Второй паттерн — самоссылающиеся структуры, известная больная тема в Rust.
Третий паттерн — множество определений разных версий и унифицированный код для работы с ними (из-за необходимости поддержки разных версий схем обмена данных, насколько я понял). Пример из статьи на C++:
Унифицированный код для работы с обоими этими типами можно написать при помощи шаблонов:
Нетрудно видеть, как это обобщается на случай большего количества полей и различных версий. В Rust можно попробовать сделать нечто подобное, но это вырождается в бойлерплейт, облегчать который приходится макросами — иными словами, попытка повторить шаблоны из C++.
Why we didn't rewrite our feed handler in Rust
Отдельно отмечается, что Rust в технологическом стеке в этой компании уже есть и успешно используется. Проблемы возникли с переписыванием конкретного компонента, который уже есть и написан на C++. Конкретно в тексте приведены три паттерна, которые валидны в C++ и не выразимы или выразимы неудобно на Rust.
Первое касается ограничений borrow checker-а. Вот какой пример приводят:
fn process_source(sources: Vec<Source>) {
for source in sources {
let mut buffer: Vec<&[u8]> = Vec::new();
let data: Vec<u8> = source.fetch_data();
buffer.extend(data.split(splitter));
process_data(&buffer);
}
}Простой и понятный код — но, к сожалению, выделяющий память в цикле. Логично было бы вынести аллокацию за цикл и очищать буфер в конце — но тогда компилятор не даёт скомпилировать код:
error[E0597]: `data` does not live long enough
--> src/lib.rs:32:23
|
31 | let data: Vec<u8> = source.fetch_data();
| ---- binding `data` declared here
32 | buffer.extend(data.split(splitter));
| ------ ^^^^ borrowed value does not live long enough
| |
| borrow later used here
33 | process_data(&buffer);
34 | }
| - `data` dropped here while still borrowed
Второй паттерн — самоссылающиеся структуры, известная больная тема в Rust.
Третий паттерн — множество определений разных версий и унифицированный код для работы с ними (из-за необходимости поддержки разных версий схем обмена данных, насколько я понял). Пример из статьи на C++:
struct RecV1 {
uint32_t x;
uint32_t y;
}
struct RecV2 {
uint32_t x;
uint32_t y;
uint32_t z;
}Унифицированный код для работы с обоими этими типами можно написать при помощи шаблонов:
template <typename T>
T InitRec() {
T res;
res.x = 1;
res.y = 2;
if constexpr(std::is_same_v<T, RecV2>()) {
res.z = 3;
}
return res;
}
Нетрудно видеть, как это обобщается на случай большего количества полей и различных версий. В Rust можно попробовать сделать нечто подобное, но это вырождается в бойлерплейт, облегчать который приходится макросами — иными словами, попытка повторить шаблоны из C++.
👍10🤡5🔥1
#prog #rust #abnormalprogramming
fibonacci-numbers crate with self-recursive dependencies
fibonacci-numbers crate with self-recursive dependencies
I have created a crate called fibonacci-numbers. There are 187 different major versions of the crate, each exporting the Fibonacci number corresponding to that version.
<...>
Version 186 depends on version 184 and 185 and exports the largest Fibonacci number that fits in a u128:
pub const VALUE: u128 = fib184::VALUE + fib185::VALUE;
😁28🔥7🤡3🤯1
#prog #rust
rustc_codegen_gcc: Progress Report #38
В rustc_codegen_gcc теперь работает LTO, в том числе и cross-language! 🎉
rustc_codegen_gcc: Progress Report #38
В rustc_codegen_gcc теперь работает LTO, в том числе и cross-language! 🎉
blog.antoyo.xyz
rustc_codegen_gcc: Progress Report #38
Antoyo's Personal Blog
😢16👍9🌚3
#prog #rust #article
A Little Rust Trait Limitation
I stumbled across a … bug(?) … a limitation(?) … an issue(!) with the Rust compiler. Fortunately, I was able to find out what was going on in the Rust programming language forum. I thought this issue was interesting enough and subtle enough to try to explain to my blog audience.
<...>
This isn’t an explanation of why this limitation is necessary or fundamental, because it isn’t – it’s a limitation that could, and maybe at some point will be, fixed.
A Little Rust Trait Limitation
I stumbled across a … bug(?) … a limitation(?) … an issue(!) with the Rust compiler. Fortunately, I was able to find out what was going on in the Rust programming language forum. I thought this issue was interesting enough and subtle enough to try to explain to my blog audience.
<...>
This isn’t an explanation of why this limitation is necessary or fundamental, because it isn’t – it’s a limitation that could, and maybe at some point will be, fixed.
😢14