#prog #rust #article
Shortcomings of Procedural Macros
Или как в процедурный макрос, определённый на impl-блоке, прокинуть информацию о методах с реализацией по умолчанию из определения трейта.
Спойлер: всё в рамках языка, без IO между макросами, но выглядит всё равно как хак.
Shortcomings of Procedural Macros
Или как в процедурный макрос, определённый на impl-блоке, прокинуть информацию о методах с реализацией по умолчанию из определения трейта.
Спойлер: всё в рамках языка, без IO между макросами, но выглядит всё равно как хак.
cryptical.xyz
Shortcomings of Procedural Macros – Cryptical
and how to overcome them
🤔6❤1
#prog #rust
Faster linking times with 1.90.0 stable on Linux using the LLD linker
Faster linking times with 1.90.0 stable on Linux using the LLD linker
TL;DR: rustc will start using the LLD linker by default on the x86_64-unknown-linux-gnu target starting with the next stable release (1.90.0, scheduled for 2025-09-18), which should significantly reduce linking times.From our prior testing, we don't really expect issues to happen in practice. It is a drop-in replacement for the vast majority of cases, but lld is not bug-for-bug compatible with GNU ld.
In any case, using rust-lld can be disabled if any problem occurs: use the -C linker-features=-lld flag to revert to using the system's default linker.
❤🔥6🎉3🤩1
#prog #rust #serde #article
Be Careful Zero-Copying Strings with serde
TL;DR: из-за того, что строки во многих форматах передачи данных (JSON, например) требуют экранирования специальных символов, строки с подобными символами не могут быть десериализованы в
Be Careful Zero-Copying Strings with serde
TL;DR: из-за того, что строки во многих форматах передачи данных (JSON, например) требуют экранирования специальных символов, строки с подобными символами не могут быть десериализованы в
&str (которые указывают на данные из входа). Для того, чтобы поддержать подобные строки, но по мере возможности все же не копировать данные, используйте Cow<str> с атрибутом #[serde(borrow)] на поле.💯8❤3👌2
#prog #rust
Rust compiler performance survey 2025 results
Помимо того, что вынесено в заголовок — немного о конкретных усилиях для уменьшения времени компиляции.
Rust compiler performance survey 2025 results
Помимо того, что вынесено в заголовок — немного о конкретных усилиях для уменьшения времени компиляции.
blog.rust-lang.org
Rust compiler performance survey 2025 results | Rust Blog
Empowering everyone to build reliable and efficient software.
👍1🤔1
#rust
crates.io phishing campaign
crates.io phishing campaign
We received multiple reports of a phishing campaign targeting crates.io users (from the rustfoundation.dev domain name), mentioning a compromise of our infrastructure and asking users to authenticate to limit damage to their crates.
These emails are malicious and come from a domain name not controlled by the Rust Foundation (nor the Rust Project), seemingly with the purpose of stealing your GitHub credentials.
<...>
Do not follow any links in these emails if you receive them, and mark them as phishing with your email provider.
🤯3🤔1
#prog #rust #itsec
crates.io: Malicious crates faster_log and async_println
crates.io: Malicious crates faster_log and async_println
The users in question were immediately disabled, and the crates in question were deleted from crates.io shortly after. We have retained copies of all logs associated with the users and the malicious crate files for further analysis.
The deletion was performed at 15:34 UTC on September 24, 2025.
#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
👍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.
#prog #c #rust #article
"Just Use Rust": A Best-Case Historical Study of Open Source Vulnerabilities in C (PDF)
"Just Use Rust": A Best-Case Historical Study of Open Source Vulnerabilities in C (PDF)
We identified 68 prominent open source projects with C code, collected their vulnerability history data, and used their CWE designations to explore a best-case speculation on how many vulnerabilities might have been prevented with Rust. We estimate that 58.2% of historical vulnerabilities in our selection of open source C projects would have been virtually impossible in Rust.
😁13🤡7👍5🔥1🤔1
#prog #rust #rustreleasenotes
Вышла версия Rust 1.91.0! Как всегда, тут только избранные части, всё остальное — в детальных заметках о релизе.
Если бы этот релиз можно было описать одним словом, то это было бы слово "полировка": релиз скорее про улучшение уже существующих фич и стабилизацию старых, давно бывших в nightly, чем про добавление чего-то действительно нового.
▪️Компилятор теперь не даёт компилировать код с суффиксами на индексах для кортежей и кортежных структур. Это было разрешено ранее по недосмотру.
▪️Добавили предупреждение на создание повисших указателей на локальные переменные. Сама по себе эта операция не является небезопасной, но на таком указателе определено очень мало осмысленных операций. Пример (из PR):
⬇️
Анализ достаточно умный, чтобы понимать поток управления и цепочки кастов (примеры в тестах в PR).
▪️Компилятор теперь не выдаёт предупреждение о мёртвом коде на
▪️Уровень поддержки для Windows с нативным ABI на ARM (aarch64-pc-windows-msvc) подняли до Tier 1.
▪️Парочка дополнений насчёт потоков: попытка установки минимального размера стека теперь возвращает ошибку при невозможности это сделать вместо паники. Сообщение о панике теперь включает в себя ID потока, в котором её начали.
▪️Задокументировали разумное предположение о Clone и PartialEq/Eq, на которое опирается стандартная библиотека (главным образом коллекции): копия значения, полученная путём вызова .clone(), должна быть равна исходному значению (при условии, что исходное значение равно самому себе).
▪️Ещё одно дополнение к документации (и соответствующий фикс): функции
▪️Стабилизировали громадное количество функций:
🔸 Path::file_prefix для извлечения порции имени файла до расширения. В отличие от существующей Path::file_stem, отрезает все расширения, а не только последнее:
🔸Несколько методов для модификации
🔸
🔸uN::checked_signed_diff для вычисления знаковой разницы беззнаковых чисел.
🔸array::repeat (в отличие от встроенного синтаксиса, работает не только с
🔸Duration::from_mins и Duration::from_hours.
🔸BTreeMap::extract_if и BTreeSet::extract_if для ленивого вытаскивания из коллекций значений, удовлетворяющих предикату.
🔸str::ceil_char_boundary и str::floor_char_boundary.
▪️
▪️У cargo теперь есть настройка для указывания того, куда складывать промежуточные артефакты компиляции.
▪️Для ключа
Вышла версия Rust 1.91.0! Как всегда, тут только избранные части, всё остальное — в детальных заметках о релизе.
Если бы этот релиз можно было описать одним словом, то это было бы слово "полировка": релиз скорее про улучшение уже существующих фич и стабилизацию старых, давно бывших в nightly, чем про добавление чего-то действительно нового.
▪️Компилятор теперь не даёт компилировать код с суффиксами на индексах для кортежей и кортежных структур. Это было разрешено ранее по недосмотру.
▪️Добавили предупреждение на создание повисших указателей на локальные переменные. Сама по себе эта операция не является небезопасной, но на таком указателе определено очень мало осмысленных операций. Пример (из PR):
fn f() -> *const u8 {
let x = 0;
&x // returns a dangling ptr to `x`
}⬇️
warning: a dangling pointer will be produced because the local variable x will be dropped
--> src/lib.rs:3:5
|
1 | fn f() -> *const u8 {
| --------- return type of the function is *const u8
2 | let x = 0;
| - x is part the function and will be dropped at the end of the function
3 | &x // returns a dangling ptr to x
| ^^
|
= note: pointers do not have a lifetime; after returning, the u8 will be deallocated at the end of the function because nothing is referencing it as far as the type system is concerned
= note: #[warn(dangling_pointers_from_locals)] on by default
Анализ достаточно умный, чтобы понимать поток управления и цепочки кастов (примеры в тестах в PR).
▪️Компилятор теперь не выдаёт предупреждение о мёртвом коде на
as-касты из выражений типа never. Да, это действительно мёртвый код, но в некоторых ситуациях подобные касты были нужны (главным образом для todo!() в функциях, возвращающих impl Trait).▪️Уровень поддержки для Windows с нативным ABI на ARM (aarch64-pc-windows-msvc) подняли до Tier 1.
▪️Парочка дополнений насчёт потоков: попытка установки минимального размера стека теперь возвращает ошибку при невозможности это сделать вместо паники. Сообщение о панике теперь включает в себя ID потока, в котором её начали.
▪️Задокументировали разумное предположение о Clone и PartialEq/Eq, на которое опирается стандартная библиотека (главным образом коллекции): копия значения, полученная путём вызова .clone(), должна быть равна исходному значению (при условии, что исходное значение равно самому себе).
▪️Ещё одно дополнение к документации (и соответствующий фикс): функции
{min, max, minmax}_by из std::cmp передают сравниваемые значения в функцию-компаратор в том же порядке, в котором они передаются в саму функцию.▪️Стабилизировали громадное количество функций:
🔸 Path::file_prefix для извлечения порции имени файла до расширения. В отличие от существующей Path::file_stem, отрезает все расширения, а не только последнее:
assert_eq!("foo", Path::new("foo.tar.gz").file_prefix().unwrap());
assert_eq!("foo.tar", Path::new("foo.tar.gz").file_stem().unwrap());🔸Несколько методов для модификации
AtomicPtr.🔸
strict_*-методы на примитивных числах, которые паникуют при переполнении вне зависимости от профиля компиляции, включая методы для операций с различной знаковостью.🔸uN::checked_signed_diff для вычисления знаковой разницы беззнаковых чисел.
🔸array::repeat (в отличие от встроенного синтаксиса, работает не только с
Copy-типами).🔸Duration::from_mins и Duration::from_hours.
🔸BTreeMap::extract_if и BTreeSet::extract_if для ленивого вытаскивания из коллекций значений, удовлетворяющих предикату.
🔸str::ceil_char_boundary и str::floor_char_boundary.
▪️
const TypeId::of 🎉🎉🎉▪️У cargo теперь есть настройка для указывания того, куда складывать промежуточные артефакты компиляции.
▪️Для ключа
--target в cargo теперь можно указывать значение host-tuple, которое будет заменено на target tuple для платформы, на которой проходит компиляция.blog.rust-lang.org
Announcing Rust 1.91.0 | Rust Blog
Empowering everyone to build reliable and efficient software.
👍5❤4🎉3