"Rust: implementation of `hg`

This commit provides a mostly-working implementation of the
`hg` script in Rust along with scaffolding to support Rust in
the repository.

If you are familiar with Rust, the contents of the added rust/
directory should be pretty straightforward. We create an "hgcli"
package that implements a binary application to run Mercurial.
The output of this package is an "hg" binary.

Our Rust `hg` (henceforth "rhg") essentially is a port of the existing
`hg` Python script. The main difference is the creation of the embedded
CPython interpreter is handled by the binary itself instead of relying
on the shebang. In that sense, rhg is more similar to the "exe wrapper"
we currently use on Windows. However, unlike the exe wrapper, rhg does
not call the `hg` Python script. Instead, it uses the CPython APIs to
import mercurial modules and call appropriate functions. The amount of
code here is surprisingly small.

It is my intent to replace the existing C-based exe wrapper with rhg.
Preferably in the next Mercurial release. This should be achievable —
at least for some Mercurial distributions. The future/timeline for
rhg on other platforms is less clear. We already ship a hg.exe on
Windows. So if we get the quirks with Rust worked out, shipping a
Rust-based hg.exe should hopefully not be too contentious."

Имеем исходник:
fn main() {
const SIZE: usize = 10000000;
let array: [u8; SIZE] = [0; SIZE];
$ cargo run
Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/foo`
zsh: segmentation fault (core dumped) cargo run

Всё, что вам нужно знать о безопасности памяти раста.
"Using Rust in Mercurial
This page describes the plan and status for leveraging the Rust programming language in Mercurial.
Why use Rust?
Today, Mercurial is a Python application. It uses Python C extensions in various places to achieve better performance.
There are many advantages to being a Python application. But, there are significant disadvantages.
Performance is a significant pain point with Python. There are multiple facets to the performance problem:
Startup overhead
General performance overhead compared to native code
GIL interfering with parallel execution
It takes several dozen milliseconds to start a Python interpreter and load the Mercurial Python modules. If you have many extensions loaded, it could take well over 100ms just to effectively get to a Mercurial command's main function. Reports of over 250ms are known. While the command itself may complete in mere milliseconds, Python overhead has already made hg seem non-instantaneous to end-users.
A few years ago, we measured that CPython interpreter startup overhead amounted to 10-18% of the run time of Mercurial's test harness. 100ms may not sound like a lot. But it is enough to give the perception that Mercurial is slower than tools like Git (which can run commands in under 10ms).
There are also situations like querying hg for shell prompts that require near-instantaneous execution.
Mercurial is also heavily scripted by tools like IDEs. We want these tools to provide results near instantaneously. If people are waiting over 100ms for results from hg, it makes these other tools feel sluggish.
There are workarounds for startup overhead problems: the CommandServer (start a persistent process and issue multiple commands to it) and CHg (a C binary that speaks with a Mercurial command server and enables chg commands to execute without Python startup overhead). chg's very existence is because we need hg to be a native binary in order to avoid Python startup overhead. If hg weren't a Python script, we wouldn't need chg to be a separate program.
Python is also substantially slower than native code. PyPy can deliver substantially better performance than CPython. And some workloads with PyPy might even be faster than native code due to JIT. But overall, Python is slower than native code.
But even with PyPy's magical performance, we still have the GIL. Python doesn't allow you to execute CPU-bound Python code on multiple threads. If you are CPU bound, you need to offload that work to an extension (which releases the GIL when it executes hot code) or you spawn multiple processes. Since Mercurial needs to run on Windows (where new process overhead is ~10x worse than POSIX and is a platform optimized for spawning threads — not processes), many of the potential speedups we can realize via concurrency are offset on Windows by new process overhead and Python startup overhead. We need thread-level concurrency on Windows to help with shorter-lived CPU-bound workloads. This includes things like revlog reading (which happens on nearly every Mercurial operation).
In addition to performance concerns, Python is also hindering us because it is a dynamic programming language. Mercurial is a large project by Python standards. Large projects are harder to maintain. Using a statically typed programming language that finds bugs at compile time will enable us to make wide-sweeping changes more fearlessly. This will improve Mercurial's development velocity.
Today, when performance is an issue, Mercurial developers currently turn to C. But we treat C as a measure of last resort because it is just too brittle. It is too easy to introduce security vulnerabilities, memory leaks, etc. On top of vanilla C, the Python C API is somewhat complicated. It takes significantly longer to develop C components because the barrier to writing bug-free C is much higher..."
"What’s in 1.22.0 and 1.22.1 stable

The headline feature for this release is one many have been anticipating for a long time: you can now use ? with Option<T>! About a year ago, in Rust 1.13, we introduced the ? operator for working with Result<T, E>. Ever since then, there’s been discussion about how far ? should go: should it stay only for results? Should it be user-extensible? Should it be usable with Option<T>?

In Rust 1.22, basic usage of ? with Option<T> is now stable. This code will now compile:

fn try_option_some() -> Option<u8> {
let val = Some(1)?;
assert_eq!(try_option_some(), Some(1));

fn try_option_none() -> Option<u8> {
let val = None?;
assert_eq!(try_option_none(), None);

However, this functionality is still a bit limited; you cannot yet write code that mixes results and options with ? in the same function, for example. This will be possible in the future, and already is in nightly Rust; expect to hear more about this in a future release.

Types that implement Drop are now allowed in const and static items. Like this:

struct Foo {
a: u32

impl Drop for Foo {
fn drop(&mut self) {}

const F : Foo = Foo { a : 0 };
static S : Foo = Foo { a : 0 };

This change doesn’t bring much on its own, but as we improve our ability to compute things at compile-time, more and more will be possible in const and static.

Additionally, some small quality-of-life improvements:

Two recent compiler changes should speed up compiles in debug mode. We don’t have any specific numbers to commit to with these changes, but as always, compile times are very important to us, and we’re continuing to work on improving them.

T op= &T now works for primitive types, which is a fancy way of saying:

let mut x = 2;
let y = &8;

// this didn't work, but now does
x += y;

Previously, you’d have needed to write x += *y in order to de-reference, so this solves a small papercut."

Есть такая библиотека (или crate) для Rust, `Cursive`, построенная поверх ncurses, для создания программ с TUI.
Автору крэйта `Cursive` ещё в сентябре на мозги накапали: запили возможность расцвечивать произвольный участок текста в текстовом виджете, а не как сейчас для всего текста only. Обещал заняться этим в октобере, но, кажется, воз и ныне там.
Уже жалею, что не взял сразу прямой и незамысловатый биндинг к ncurses.

error: aborting due to worker thread panic

Сказал раст на виртуалке с 1 гигом и 500Mb свопом при сборке средних размеров проекта.

Думал очень долго, а потом просто умер, куда катится мир..

Пришлось еще гиг накинуть, что бы собралось.
"Rust 1.20 adds the ability to define “associated constants” as well:
struct Struct;
impl Struct {
const ID: u32 = 0;
fn main() {
println!("the ID of Struct is: {}", Struct::ID);
That is, the constant ID is associated with Struct. Like functions, associated constants work with traits and enums as well.
Traits have an extra ability with associated constants that gives them some extra power. With a trait, you can use an associated constant in the same way you’d use an associated type: by declaring it, but not giving it a value. The implementor of the trait then declares its value upon implementation"

"А чего там про Rust
Вот как раз стример у нас ржавый. Целая пачка unsafe кода, автогенеренного из сишного кода SDK с помощью bindgen, подпатченый биндинг к libc (постараемся залить патч в апстрим) и дальше реализация RTSP на tokio. Даже уже есть возможность посмотреть видео с камеры в обычном браузере — это недостижимая роскошь для китайских камер, которые поголовно требуют установку ActiveX.
Структура очень непривычна после эрланга: ведь тут нет процессов и сообщений, есть каналы, а с ними всё становится немножко по-другому. Как я уже выше писал, современно написанный код с правильной организацией дает возможность раздавать видео не 2-3 клиентам, а более 50 без какой-либо просадки производительности.
Важный момент: за время разработки пока не случилось ни единого сегфолта. Пока есть стойкое ощущение, что Rust заставляет писать так, как в принципе пишут хорошие поседевшие сишники, повидавшие всякого нехорошего. Так что пока всё нравится.
В течение августа есть планы закончить работу по базовому сценарию, так что есть вопрос к аудитории, который идет в опросе. Ну и задавайте вопросы, которые возникли."

У меня одного метод зависает в реакторе?
query в асинхронной версии и execute в синхронной спокойно работают, а этот висит со статусом idle и не завершает свой Future.

Хозяйке на заметку:
let future_returns_db_connection = ...;
let prog = future_returns_db_connection.and_then(|db_connection| {
your_stream_wants_to_work_with_db.fold(db_connection, |also_db_connection, value| {

Хозяйке на заметку:
fn main() {
let mut core = Core::new().expect("Can't create Tokio Core");
let handle = core.handle();

// Use only one Ctrl+C signal.
let ctrl_c = tokio_signal::ctrl_c(&handle).flatten_stream().take(1).map(|_| false);

let interval = Interval::new(Duration::from_secs(1), &handle).expect("Cann't create timer").map(|_| true);

// Process each ctrl-c as it comes in
let prog = ctrl_c
.take_while(|c| Ok(*c)) // stop when Ctrl+C
.for_each(|c| {
println!("{:?}", c);

match {
Ok(o) => println!("Finish: {:?}", o),
Err(e) => println!("Error: {}", e),

Реддит как обычно доставляет:

Having conversed with the Rust community my conclusion is that it is a language for highly religious disgruntled C++ programmers who still insist that real men don't use garbage collection but end up resorting to reference counting everywhere because ownership is hard
"What’s in 1.18.0 stable
As usual, Rust 1.18.0 is a collection of improvements, cleanups, and new features.
One of the largest changes is a long time coming: core team members Carol Nichols and Steve Klabnik have been writing a new edition of “The Rust Programming Language”, the official book about Rust. It’s being written openly on GitHub, and has over a hundred contributors in total. This release includes the first draft of the second edition in our online documentation. 19 out of 20 chapters have a draft; the draft of chapter 20 will land in Rust 1.19. When the book is done, a print version will be made available through No Starch Press, if you’d like a paper copy. We’re still working with the editors at No Starch to improve the text, but we wanted to start getting a wider audience now.
The new edition is a complete re-write from the ground up, using the last two years of knowledge we’ve gained from teaching people Rust. You’ll find brand-new explanations for a lot of Rust’s core concepts, new projects to build, and all kinds of other good stuff. Please check it out and let us know what you think!
As for the language itself, an old feature has learned some new tricks: the pub keyword has been expanded a bit. Experienced Rustaceans will know that items are private by default in Rust, and you can use the pub keyword to make them public. In Rust 1.18.0, pub has gained a new form:
pub(crate) bar;
The bit inside of () is a ‘restriction’, which refines the notion of how this is made public. Using the crate keyword like the example above means that bar would be public to the entire crate, but not outside of it. This makes it easier to declare APIs that are “public to your crate”, but not exposed to your users. This was possible with the existing module system, but often very awkward.
You can also specify a path, like this:
pub(in a::b::c) foo;
This means “usable within the hierarchy of a::b::c, but not elsewhere.” This feature was defined in RFC 1422 and is documented in the reference.
For our Windows users, Rust 1.18.0 has a new attribute, #![windows_subsystem]. It works like this:
These control the /SUBSYSTEM flag in the linker. For now, only console and windows are supported.
When is this useful? In the simplest terms, if you’re developing a graphical application, and do not specify windows, a console window would flash up upon your application’s start. With this flag, it won’t.
Finally, Rust’s tuples, enum variant fields, and structs (without #[repr]) have always had an undefined layout. We’ve turned on automatic re-ordering, which can result in smaller sizes through reducing padding..."

В пакетном менеджере Cargo реализована команда "cargo check", при указании которой компилятором выполняются все совершаемые при сборке проверки кода, но пропускаются достаточно ресурсоёмкие стадии, связанные с генерацией исполняемых файлов. Для некоторых проектов "cargo check" может выполняться в несколько раз быстрее обычной сборки, что позволяет значительно сэкономить время разработчика при выполнении тестовых пересборок, обычно используемые в процессе разработки чтобы убедиться, что добавленный код компилируется; Хм… А ghc умеет в то чтобы натравить на исходник тайп-чекер и не генерить ничего?

Это просто праздник какой-то:
"Состоялся первый публичный релиз системы управления версиями Pijul 0.3, написанной на языке программирования Rust. Pijul объединяет в себе производительность git и простоту использования darcs. Основанная на модели теории патчей, система Pijul направлена на то, чтобы сделать операции слияния и забора определенных коммитов (cherry-pick) более интуитивным.
Pijul можно установить при помощи Cargo (пакетного менеджера для Rust): команда cargo install pijul соберёт самую последнюю версию. Минимальная для сборки версия Rust — 1.15.1."

Вот и появился скриптовый язык моей мечты:
Gluon is a small, statically-typed, functional programming language designed for application embedding.
Statically typed — Static typing makes it easier to write safe and efficient interfaces between gluon and the host application.
Type inference — Type inference ensures that types rarely have to be written explicitly giving all the benefits of static types with none of the typing.
Simple embedding — Marshalling values to and from gluon requires next to no boilerplate, allowing functions defined in Rust to be directly passed to gluon.
UTF-8 by default — Gluon supports unicode out of the box with utf-8 encoded strings and unicode codepoints as characters.
Separate heaps — Gluon is a garbage-collected language but uses a separate heap for each executing gluon thread. This keeps each heap small, reducing the overhead of the garbage collector.
Thread safe — Gluon is written in Rust, which guarantees thread safety. Gluon keeps the same guarantees, allowing multiple gluon programs to run in parallel (example)*
* Parallel execution of gluon programs is a recent addition and may still have issues such as deadlocks."
"The largest addition to Rust 1.16 is cargo check. This new subcommand should speed up the development workflow in many cases."
"When slicing a &str, you’ll see better errors. For example, this code:
Is incorrect. It generates this error:
thread 'str::test_slice_fail_boundary_1' panicked at 'byte index 4 is not
a char boundary; it is inside 'α' (bytes 3..5) of `abcαβγ`'
The part after the ; is new."

Градостроительный симулятор, который мы заслужили:
"The city sim you deserve.
Cities are complex and that's why you love them.
Experience a true city: millions of interactions between people, companies and neighborhoods. Follow detailed daily lifes, see businesses struggle in the local economy and be mesmerized by the traffic simulation. Each citizen is simulated individually, their behaviour is realistic and adorably human.
Think and plan as the urban developer that you are.
Prepare changes to your city by creating the perfect plan. Use the most powerful and yet intuitive drawing tools in any city sim ever. Create the craziest roads and intersections, lay out custom parks or even airports. Juggle projects, set priorities and recover from bad situations.
Create a city that looks like a city.
Let your city grow across a beautiful landscape, without boundaries. Enjoy detailed control over zones that curve along roads. Be surprised by procedural architecture that uniquely adapts to the available space and the local circumstances. What style and flavor will your city have?
Humble beginnings, ambitious goal.
Anselm Eickhoff builds Citybound. It gained attention as a small prototype, then became his fulltime dream project. Now he is chipping away at the impossibility of the task.
Cutting edge tech and latest research.
The solid foundation: a custom geometry toolset, high-performance microsimulation framework and economy model — based on and inspired by countless papers and theses.
We are getting there — be a part of the process.
Citybound is developed completely open source. In addition, I regularly update my community about my progress, we discuss all kinds of aspects and even invent stuff together!
My funding model is honest and sustainable: I make every new prototype available to everyone and fans pledge a monthly contribution of their choosing."