Forwarded from dev optozorax
ААААААААА, ЭТО ОФИГЕННО!!!! 🤩 Клеточный автомат «Игра Жизнь» симулируется на самом себе бесконечно в обе стороны!!! Просто откройте!
https://oimo.io/works/life/
https://oimo.io/works/life/
oimo.io
Life Universe
🔥15
То есть за всё время существования cargo функционал по отдаче результатов тестов в машинно-читаемом формате всё ещё нестабильный?!
#rust #бомбёжкипост
#rust #бомбёжкипост
GitHub
Tracking issue for libtest JSON output · Issue #49359 · rust-lang/rust
Added in #46450 Available in nightly behind a -Z flag.
🤡2
Блог*
То есть за всё время существования cargo функционал по отдаче результатов тестов в машинно-читаемом формате всё ещё нестабильный?! #rust #бомбёжкипост
И cargo-nextest эту проблему тоже не решает
GitHub
Machine-readable output for cargo nextest run · Issue #20 · nextest-rs/nextest
The output should be similar to what cargo itself provides, complete with --message-format json and --message-format json-render-status options.
#prog #rust #rustreleasenotes
Вышла версия Rust 1.66.0! Как всегда, вычленю только интересное мне, а остальное в детальных заметках о релизе.
▪️Очень важная фича для интеропа: теперь даже для
▪️Наконец-то можно бенчмаркать код без того, чтобы оптимизатор вырезал всё подчистую для тривиальных случаев: стабилизирована функция core::hint::black_box, которая функционально эквивалентна
В документации, однако, сказано:
> Note however, that
▪️Теперь можно вызывать
▪️Изменение, о котором я говорил, докатилось до стейбла: в паттернах теперь можно использовать диапазоны с открытой нижней границей:
▪️
▪️Вопреки принятому RFC,
▪️Option::unzip 👏
▪️BTreeMap и BTreeSet обзавелись методами для доступа к первым (= минимальным) и последним (= максимальным) элементам:
Да, это правда, что технически приличную долю этих методов можно заменить на вызовы методов итераторов. Но итераторы у
▪️Примитивные числовые типы обзавелись методами для прибавления соответствующих типов противоположной знаковости (
▪️Компилятор стал побыстрее за счёт LTO для самого rustc и BOLT для LLVM (BOLT?). К сожалению, только на Linux.
Вышла версия Rust 1.66.0! Как всегда, вычленю только интересное мне, а остальное в детальных заметках о релизе.
▪️Очень важная фича для интеропа: теперь даже для
enum с данными на вариантах можно использовать явные дискриминанты. Пример:#[repr(u8)]В сочетании с
enum Foo {
A(u8) = 0,
B(i8) = 1,
C(bool) = 42,
}
#[repr(primitive_int)] и #[repr(C, primitive_int] это даёт предсказуемое представление в памяти: c #[repr(primitive_int)] enum будет union с вариантами перечисления, а с #[repr(C, primitive_int] enum будет парой из явного дискриминанта и union с вариантами без поля под дискриминант. И в том, и в другом случае дискриминант будет первым полем в представлении enum, и reference говорит, что дискриминант можно всегда можно достать путём кастования указателя на enum в указатель на типа дискриминанта. Например, в случае Foo, указанного выше:impl Foo {
fn discriminant(&self) -> u8 {
unsafe { *(self as *const Self as *const u8) }
}
}
▪️Ошибка при вычислении константного выражения наконец-то останавливает компиляцию, а не просто выдаёт предупреждение.▪️Наконец-то можно бенчмаркать код без того, чтобы оптимизатор вырезал всё подчистую для тривиальных случаев: стабилизирована функция core::hint::black_box, которая функционально эквивалентна
core::convert::identity, но при этом с точки зрения оптимизатора может сделать что угодно. В блогопосте есть пример использования.В документации, однако, сказано:
> Note however, that
black_box is only (and can only be) provided on a “best-effort” basis. The extent to which it can block optimisations may vary depending upon the platform and code-gen backend used. Programs cannot rely on black_box for correctness in any way.▪️Теперь можно вызывать
transmute между обобщёнными типами, которые отличаются лишь подставленными лайфтайм-параметрами.▪️Изменение, о котором я говорил, докатилось до стейбла: в паттернах теперь можно использовать диапазоны с открытой нижней границей:
..X и ..=X.▪️
impl Trait-типы теперь наследуют #[must_use]-аннотации от супертрейтов. В частности, теперь компилятор предупреждает о неиспользуемом impl ExactSizeIterator.▪️Вопреки принятому RFC,
#[derive(Default)] на enum добавлял баунд : Default на тИповых параметрах. Сейчас это поправили.▪️Option::unzip 👏
▪️BTreeMap и BTreeSet обзавелись методами для доступа к первым (= минимальным) и последним (= максимальным) элементам:
BTreeSet::{first,last
,pop_first
,pop_last
}first_key_value
BTreeMap::{
,last_key_value
,first_entry
,last_entry
,pop_first
,pop_last
}При этом методы
first_entry и last_entry возвращают (опционально, разумеется) OccupiedEntry, то есть ещё и дают возможность манипулировать значением in-place.Да, это правда, что технически приличную долю этих методов можно заменить на вызовы методов итераторов. Но итераторы у
BTreeMap и BTreeSet двухсторонние и потому вынуждены спускаться в по дереву в обе стороны, что является лишней работой в случае, если требуется элемент лишь с одной стороны.▪️Примитивные числовые типы обзавелись методами для прибавления соответствующих типов противоположной знаковости (
iX::*_add_unsigned и uX::*_add_signed), а знаковые типы — и методами для вычитания беззнаковых чисел. Почему-то есть checked_*, overflowing_*, saturating_* и wrapping_* варианты, но нету просто прибавления без уточнения поведения.▪️Компилятор стал побыстрее за счёт LTO для самого rustc и BOLT для LLVM (BOLT?). К сожалению, только на Linux.
blog.rust-lang.org
Announcing Rust 1.66.0 | Rust Blog
Empowering everyone to build reliable and efficient software.
🔥4👍1
Блог*
#prog #rust #rustreleasenotes Вышла версия Rust 1.66.0! Как всегда, вычленю только интересное мне, а остальное в детальных заметках о релизе. ▪️Очень важная фича для интеропа: теперь даже для enum с данными на вариантах можно использовать явные дискриминанты.…
Для тех, кто занимается процедурными макросами: у Span добавили метод source_text, который возвращает кусок исходника, на который указывает Span. Возвращает None для сгенерированного кода. В документации при этом прямо сказано, что "The observable result of a macro should only rely on the tokens and not on this source text. The result of this function is a best effort to be used for diagnostics only".
doc.rust-lang.org
Span in proc_macro - Rust
A region of source code, along with macro expansion information.
#prog #rust #article
My Year With Rust: The Good, The Bad, The Ugly
<...>
I always feel that reducing Rust to its safety aspect is doing the language a disservice. While safety might be important for big corporations, a small-time game developer like me doesn't really care about it. For me, Rust is so much more than just safety.
<...>
Rust Does Not Crash
Okay, this is an exaggeration, but it is somewhat true, especially for safe Rust. The truth is probably closer that Rust gives me a huge amount of confidence. When it compiles, it generally works. It won't protect you from all kinds of logic errors, but it prevents a whole class of errors from happening and turns many into compile time rather than runtime ones.
I admit, when I first started with Rust, correctness was not really a big concern. The program should run of course, but crashing or bugs are not the end of the world most of the time, especially when it comes to games. They just happen.
However, correctness is something that I really started to appreciate after using Rust for a while. It really grew on me to a point where I don't want to miss it anymore.
<...>
The language itself also has some holes. Rust offers many useful features with its lifetimes, traits, and it's typesystem, but I am constantly hitting unstable features or outright forbidden operations when trying to use them together in certain contexts.
<...>
As mentioned before, Rust focuses on correctness. There are many tracking issues that seem to be stuck for years, because there is no agreement on a solution, or because it wouldn't work on some exotic platforms or due to a niche reason. It's quickly adding new features that people can agree on, but the difficult questions seem to be stuck at times, with only an occasional bump being a lost soul, asking for the current status.
<...>
Switching To Other Languages Feels Off
I know. This sounds like /r/rustjerk content, feel free to skip over this part, but my point is not that Rust is superior, but more that it can causes changes in general, at least it did to me. Rust just does so many things differently.
Being conditioned to please the borrow checker will just change how you approach problems and write code in general. It takes a lot of time to switch from the "ownership and lifetime" model to the "Oprah handing out mutable references"-style. The cost of the context switch is huge.
My Year With Rust: The Good, The Bad, The Ugly
<...>
I always feel that reducing Rust to its safety aspect is doing the language a disservice. While safety might be important for big corporations, a small-time game developer like me doesn't really care about it. For me, Rust is so much more than just safety.
<...>
Rust Does Not Crash
Okay, this is an exaggeration, but it is somewhat true, especially for safe Rust. The truth is probably closer that Rust gives me a huge amount of confidence. When it compiles, it generally works. It won't protect you from all kinds of logic errors, but it prevents a whole class of errors from happening and turns many into compile time rather than runtime ones.
I admit, when I first started with Rust, correctness was not really a big concern. The program should run of course, but crashing or bugs are not the end of the world most of the time, especially when it comes to games. They just happen.
However, correctness is something that I really started to appreciate after using Rust for a while. It really grew on me to a point where I don't want to miss it anymore.
<...>
The language itself also has some holes. Rust offers many useful features with its lifetimes, traits, and it's typesystem, but I am constantly hitting unstable features or outright forbidden operations when trying to use them together in certain contexts.
<...>
As mentioned before, Rust focuses on correctness. There are many tracking issues that seem to be stuck for years, because there is no agreement on a solution, or because it wouldn't work on some exotic platforms or due to a niche reason. It's quickly adding new features that people can agree on, but the difficult questions seem to be stuck at times, with only an occasional bump being a lost soul, asking for the current status.
<...>
Switching To Other Languages Feels Off
I know. This sounds like /r/rustjerk content, feel free to skip over this part, but my point is not that Rust is superior, but more that it can causes changes in general, at least it did to me. Rust just does so many things differently.
Being conditioned to please the borrow checker will just change how you approach problems and write code in general. It takes a lot of time to switch from the "ownership and lifetime" model to the "Oprah handing out mutable references"-style. The cost of the context switch is huge.
👍1🤨1
Блог*
#prog #rust #article My Year With Rust: The Good, The Bad, The Ugly <...> I always feel that reducing Rust to its safety aspect is doing the language a disservice. While safety might be important for big corporations, a small-time game developer like me…
Полюбуйтесь на эту красоту из web-sys
🤯9🔥3😱3❤1👍1🤮1
#prog #rust #article
Native Reflection in Rust
Пост про библиотеку deflect, которая добавляет в Rust рефлексию, но, в отличие от, скажем, bevy_reflect, работает для всех типов, а не только для тех, на которых навешан дерайв.
TL;DR:
1. invokes
3. searches your application’s debuginfo for the entry describing the function at that offset
4. parses that debugging information entry (DIE) to determine the type of
The DIE of the Self type has information about the kind of the type (struct, enum, pointer, primitive, etc.), its size, alignment, and the locations and types of its fields. With all this, deflect is able to dynamically reflect the structure of your value’s bytes.
Разумеется, из-за механизма работы не работает на бинарниках без DWARF-символов.
Native Reflection in Rust
Пост про библиотеку deflect, которая добавляет в Rust рефлексию, но, в отличие от, скажем, bevy_reflect, работает для всех типов, а не только для тех, на которых навешан дерайв.
TL;DR:
pub trait Reflect {
#[inline(never)]
fn local_type_id(&self) -> usize {
<Self as Reflect>::local_type_id as usize
}
}
impl<T: ?Sized> Reflect for T {}
When you call .reflect on a dyn Reflect value, deflect figures out its concrete type in four steps:1. invokes
local_type_id to get the memory address of your value’s static implementation of local_type_id
2. maps that memory address to an offset in your application’s binary3. searches your application’s debuginfo for the entry describing the function at that offset
4. parses that debugging information entry (DIE) to determine the type of
local_type_id’s &self parameter.The DIE of the Self type has information about the kind of the type (struct, enum, pointer, primitive, etc.), its size, alignment, and the locations and types of its fields. With all this, deflect is able to dynamically reflect the structure of your value’s bytes.
Разумеется, из-за механизма работы не работает на бинарниках без DWARF-символов.
Jack Sometimes Writes
Native Reflection in Rust
😱8❤4🤔2👍1