#prog #rust #gamedev #amazingopensource (но пока сырое)
Revy is a proof-of-concept time-travel debugger for the Bevy game engine, built using Rerun.
Revy works by snapshotting diffs of the Bevy database every frame that are then logged into the Rerun database.
This allows you to inspect and visualize the state of the engine at any point in time, either in real-time or after the fact.
These recordings can then be shared to be replayed or e.g. attached to bug reports.
👍7🤔3❤1
#prog #rust #rustreleasenotes
Вышла версия Rust 1.93.0! Как обычно, тут только избранное, остальное только в детальных заметках о релизе.
(да, я выкладываю анонс с опозданием больше недели, и что ты мне сделаешь?)
В этот раз большинство изменений связаны со стандартной библиотекой.
▪️Немного печальное изменение: даже с установлением
▪️Компилятор теперь выдаёт предупреждение на #[repr(C)]-перечисления, у которых значения дискриминантов не умещаются в сишный int. Смешно, но до C23 у сишных
▪️Компилятор теперь выдаёт предупреждение на попытку вызвать метод на const-значении, который эксплуатирует внутреннюю изменяемость. Так как константы инлайнятся по месту использования, эти изменения не будут видны. Обычно это является следствием ошибки — использования
▪️Метод
▪️Стабилизированы API:
🔸assume_init_drop, assume_init_ref и assume_init_mut на
🔸
🔸
🔸методы для непроверяемых (и потому потенциально дающих UB) битовых сдвигов в обе стороны на примитивных числах, а на знаковых — ещё и unchecked_neg
🔸методы для перевода ссылок на слайсы в (опциональные, разумеется) ссылки на массивы и сырых указателей на слайсы в сырые указатели на массивы, включая мутабельные варианты
🔸pop_front_if и pop_back_if на
🔸std::fmt::from_fn для ad-hoc форматирования через переданную функцию. Позволяет избежать создания одноразовых типов, нужных только для форматирования
▪️Cargo теперь прокидывает значение конфигурации debug_assertions в билд-скрипты.
▪️Команда
▪️
Вышла версия Rust 1.93.0! Как обычно, тут только избранное, остальное только в детальных заметках о релизе.
(да, я выкладываю анонс с опозданием больше недели, и что ты мне сделаешь?)
В этот раз большинство изменений связаны со стандартной библиотекой.
▪️Немного печальное изменение: даже с установлением
#[global_allocator] std всё ещё может вызывать System аллокатор. По крайней мере, на core это не распространяется.▪️Компилятор теперь выдаёт предупреждение на #[repr(C)]-перечисления, у которых значения дискриминантов не умещаются в сишный int. Смешно, но до C23 у сишных
enum нельзя было указать численный тип и нельзя было использовать значения больше int для дискриминантов.▪️Компилятор теперь выдаёт предупреждение на попытку вызвать метод на const-значении, который эксплуатирует внутреннюю изменяемость. Так как константы инлайнятся по месту использования, эти изменения не будут видны. Обычно это является следствием ошибки — использования
const вместо static (и я, кстати, такую ошибку уже делал).▪️Метод
append на BTreeSet и BTreeMap теперь сохраняет ключ из исходной коллекции, если ключи считаются равными через ==. До этого перезаписывались и ключ, и значение.▪️Стабилизированы API:
🔸assume_init_drop, assume_init_ref и assume_init_mut на
MaybeUninit<T>🔸
write_{copy, clone}_of_slice на [MaybeUninit<T>]🔸
into_raw_parts на String и на Vec. Странно, что только сейчас, потому что обратные from_raw_parts методы были стабилизированы ещё в версии 1.0.🔸методы для непроверяемых (и потому потенциально дающих UB) битовых сдвигов в обе стороны на примитивных числах, а на знаковых — ещё и unchecked_neg
🔸методы для перевода ссылок на слайсы в (опциональные, разумеется) ссылки на массивы и сырых указателей на слайсы в сырые указатели на массивы, включая мутабельные варианты
🔸pop_front_if и pop_back_if на
VecDeque🔸std::fmt::from_fn для ad-hoc форматирования через переданную функцию. Позволяет избежать создания одноразовых типов, нужных только для форматирования
▪️Cargo теперь прокидывает значение конфигурации debug_assertions в билд-скрипты.
▪️Команда
cargo tree теперь позволяет использовать для форматирования записей в дереве длинные имена для элементов шаблонов. Например, следующие два вызова эквивалентны:cargo tree --format='{p} {f}'cargo tree --format='{package} {features}'▪️
cargo clean теперь может удалять артефакты компиляции из всего workspace-а целиком.👍8😁1
Random Rust Dev
Как заставить растовика задуматься над элементарной вещью?
Задайте ему вопрос: Какой тип у `0x12345_f32`?
Задайте ему вопрос: Какой тип у `0x12345_f32`?
#prog #rust
Но вообще ответ не вполне корректен.Тип числового литерала уточняется выводом типов, а конкретно i32 выбирается только в том случае, если ограничений на тип недостаточно, чтобы выбрать конкретный числовой тип (и лично я это считаю недостатком Rust )
Но вообще ответ не вполне корректен.
🤔7👍3
#prog #rust #article
В стандартной библиотеке Rust есть несколько ассоциативных контейнеров:
Возьмём в качестве примера HashMap::get:
Как видно из кода, тип для поиска (
В процессе поиска значения на хранимых ключах вызывается метод
Но у этого API есть недостаток. Именно, оно требует, чтобы предоставляемое значение было ссылкой и чтобы из ссылки на ключ можно было получить ссылку на
В короткой статье Borrowed tuple indexing for HashMap рассказывается, как с некоторым количеством бойлерплейта можно обойти это ограничение.
Для сравнения, hashbrown (поверх которого сделаны мапы в std) от подобных ограничений не страдает, поскольку там в API используется более гибкий трейт Equivalent:
В стандартной библиотеке Rust есть несколько ассоциативных контейнеров:
HashMap, HashSet, BTreeMap и BTreeSet. Часто на практике в качестве ключей в них хранятся строки — String. Требовать от пользователя для поиска значение типа String неудобно и чревато проблемами в производительности. Потому у этих структур данных есть API, позволяющие использовать для поиска ключи других, "похожие" на те, что хранятся в контейнере.Возьмём в качестве примера HashMap::get:
fn get<Q>(&self, k: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: Hash + Eq + ?Sized,
Как видно из кода, тип для поиска (
Q) не обязан совпадать с типом хранимых ключей (K), но на K есть ограничение K: Borrow<Q>. Трейт Borrow выглядит таким образом:trait Borrow<Borrowed>
where
Borrowed: ?Sized,
{
fn borrow(&self) -> &Borrowed;
}
В процессе поиска значения на хранимых ключах вызывается метод
<K as Borrow<Q>>::borrow, и результат возвращаемого значения сравнивается со значением, переданным в get. Именно благодаря этому API (и реализациям в std, разумеется) коллекцию HashMap<String, Thing> можно индексировать значениями типа &str.Но у этого API есть недостаток. Именно, оно требует, чтобы предоставляемое значение было ссылкой и чтобы из ссылки на ключ можно было получить ссылку на
Q. Это ограничивает применимость API. Если, например, в мапе в качестве ключей хранятся (String, String), то логичный невладеющий эквивалент для индексации (&str, &str) не будет работать, потому что это кортеж ссылок, а не ссылка.В короткой статье Borrowed tuple indexing for HashMap рассказывается, как с некоторым количеством бойлерплейта можно обойти это ограничение.
Для сравнения, hashbrown (поверх которого сделаны мапы в std) от подобных ограничений не страдает, поскольку там в API используется более гибкий трейт Equivalent:
trait Equivalent<K>
where
K: ?Sized,
{
fn equivalent(&self, key: &K) -> bool;
}
👍10🤯3🤡1
Блог*
#prog #rust #article Офигенно! Rust's standard library on the GPU GPU code can now use Rust's standard library. We share the implementation approach and what this unlocks for GPU programming. This works because of our custom hostcall framework. A hostcall…
Vectorware
Async/await on the GPU
GPU code can now use Rust's async/await. We share the reasons why and what this unlocks for GPU programming.
🔥8😱3❤1😭1
#prog #rust #article
Making cargo-semver-checks faster - Google Summer of Code 2025
Making cargo-semver-checks faster - Google Summer of Code 2025
Overall, I reduced the typical runtime on very large crates down to ~2s from ~8s - nearly an 80% speedup - without compromising performance on smaller crates. Along the way I reduced test time from ~7min to ~1min.
❤6
#rust
Rust debugging survey 2026
Rust debugging survey 2026
You can fill out the survey here.
Filling the survey should take you approximately 5 minutes, and the survey is fully anonymous. We will accept submissions until Friday, March 13th, 2026.
blog.rust-lang.org
Rust debugging survey 2026 | Rust Blog
Empowering everyone to build reliable and efficient software.
🤔2
#prog #rust #rustreleasenotes
Вышла версия Rust 1.94.0! Как всегда, тут только то, что интересно мне, остальное в детальных заметках о релизе.
▪️Атрибуты для линта
▪️Касты между сырыми указателями на unsized типы с указанием лайфтаймов теперь требуют, чтобы предыдущий тип жил не меньше нового. Или, иными словами, каст из
▪️Стабилизировали array_windows! Украду пример прямо из блогпоста:
Благодаря выводу типов ещё и размер, как правило, не нужно указывать на методе явно.
▪️
▪️Для
▪️cargo теперь использует для парсинга манифестов наконец-то вышедшую версию TOML 1.1. С практической точки зрения это главным образом означает, что inline-таблицы можно писать на нескольких строках и с запятой после — или, иными словами, зависимость в Cargo.toml с большим количеством фичей теперь можно писать среди остальных и не пихать её в одну длинную строку.
▪️Ещё стабилизация: cargo теперь позволяет разбить конфиг на несколько файлов и объединить их при помощи top-level ключа
Вышла версия Rust 1.94.0! Как всегда, тут только то, что интересно мне, остальное в детальных заметках о релизе.
▪️Атрибуты для линта
dead_code (allow/warn/deny/expect) на трейтах и их частях теперь наследуются impl-ами:#[allow(dead_code)]
trait Foo {
const FOO: u32;
}
impl Foo for u32 {
const FOO: u32 = roundtrip(0);
}
// нет предупреждения о мёртвом коде
const fn roundtrip(x: u32) -> u32 {
x
}
▪️Касты между сырыми указателями на unsized типы с указанием лайфтаймов теперь требуют, чтобы предыдущий тип жил не меньше нового. Или, иными словами, каст из
*mut dyn Trait + 'a в *mut dyn Trait + 'b теперь требует 'a: 'b▪️Стабилизировали array_windows! Украду пример прямо из блогпоста:
For example, part of one 2016 Advent of Code puzzle is looking for ABBA patterns: "two different characters followed by the reverse of that pair, such as xyyx or abba." If we assume only ASCII characters, that could be written by sweeping windows of the byte slice like this:
fn has_abba(s: &str) -> bool {
s.as_bytes()
.array_windows()
.any(|[a1, b1, b2, a2]|
(a1 != b1)
&& (a1 == a2)
&& (b1 == b2)
)
}Благодаря выводу типов ещё и размер, как правило, не нужно указывать на методе явно.
▪️
LazyCell и LazyLock обзавелись методами get, get_mut и force_mut.▪️Для
iter::Peekable добавили методы next_if_map и next_if_map_mut. Пример из документации:let mut iter = "125 GOTO 10".chars().peekable();
let mut line_num = 0_u32;
while let Some(digit) = iter.next_if_map(|c| c.to_digit(10).ok_or(c)) {
line_num = line_num * 10 + digit;
}
assert_eq!(line_num, 125);
assert_eq!(iter.collect::<String>(), " GOTO 10");
▪️cargo теперь использует для парсинга манифестов наконец-то вышедшую версию TOML 1.1. С практической точки зрения это главным образом означает, что inline-таблицы можно писать на нескольких строках и с запятой после — или, иными словами, зависимость в Cargo.toml с большим количеством фичей теперь можно писать среди остальных и не пихать её в одну длинную строку.
▪️Ещё стабилизация: cargo теперь позволяет разбить конфиг на несколько файлов и объединить их при помощи top-level ключа
include (документация).👍5