1.93K subscribers
3.5K photos
136 videos
15 files
3.72K links
Блог со звёздочкой.

Много репостов, немножко программирования.

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
#prog #rust #article

From Rust to Reality: The Hidden Journey of fetch_max

Why would Rust provide fetch_max as a built-in intrinsic? Intrinsics usually exist to leverage specific hardware instructions. But x86-64 doesn't have an atomic max instruction. 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
😁16🤣2👎1🤔1
#prog #rust #rustlib #article

I Wrote A String Type

Статья, рассказывающая о принципиальном устройстве byteyarn — оптимизированного типа для строк, который умещается в 16 байт, имеет small string optimisation и имеет нишу, позволяющую не увеличивать размер при оборачивании в Option
👍6🤔1
😁17👏8🔥1
#prog #rust #rustlib #ml #abnormalprogramming

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-а. Вот какой пример приводят:

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

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! 🎉
😢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.
😢14
#prog #c #rust #article

"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.
😢17😁13🤡7👍5🔥1🤔1
#prog #rust #rustreleasenotes

Вышла версия 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 для платформы, на которой проходит компиляция.
😢16👍54🎉3
#prog #article#rust, но многое в статье от Rust не зависит)

SocketAddrV6 is not roundtrip serializable
😱5💩1
#prog #rust #article

Rust in Android: move fast and fix things

The 2025 data continues to validate the approach, with memory safety vulnerabilities falling below 20% of total vulnerabilities for the first time.

We adopted Rust for its security and are seeing a 1000x reduction in memory safety vulnerability density compared to Android’s C and C++ code. But the biggest surprise was Rust's impact on software delivery. With Rust changes having a 4x lower rollback rate and spending 25% less time in code review, the safer path is now also the faster one.


We'll analyze a near-miss memory safety bug in unsafe Rust: how it happened, how it was mitigated, and steps we're taking to prevent recurrence. It’s also a good chance to answer the question “if Rust can have memory safety issues, why bother at all?”
👍5
#prog #rust #rustlib

TIL что в bindgen есть возможность прицепить коллбеки, которые будут вызываться для определений, обрабатываемых во время генерации биндингов, и что есть уже готовый CargoCallbacks, который печатает

cargo:rerun-if-changed...

для каждого обрабатываемого файла и каждой явно заданной переменной окружения.
🤔2
#prog #rust #python

Pre-PEP: Rust for CPython

In summary, Rust provides many extremely useful benefits that would improve CPython development. Increasing memory safety would be a significant improvement in of itself, but it is far from the only benefit Rust provides.
Историческое событие.

Отдельно отмечается, что компилятор Rust в настоящее время поддерживает все платформы, официально поддерживаемые CPython.
🔥14🤡2