This can be labeled as a "Question" I think.
While I am sure, that there are advantages to using Rust for the emacs base in terms of safe code and in the future maybe even speed and development time, I am wondering in what areas exactly the advantages are, when rewriting the emacs base.
For example I just saw the following https://github.com/Wilfred/remacs/pull/255 .
It's great that people contribute, but should not anything unsafe be avoided at all cost if possible? Isn't that the purpose of rewriting the whole thing? And thus to avoid any bugs on that layer?
Maybe the Rust rewrite gets rid of very old cruft, which has accumulated. I don't know. I have no clue about the emacs core things and how the rewriting policies are or how the rewriting has been going so far. That is why I am writing this question.
Please tell in detail how Rust helps with the emacs core/base/whatever, which aspects will be improved once the rewrite is done ; )
There's a few possible answers here, so let me present my personal view.
I would guess that most of us who work on Remacs do it because we love Rust and Emacs. So that's one motivation to choose this relatively large project (300kLOC of C) for a rewrite. It's also a very nice case study of how to transfer a code base piece by piece, hooking into the core layer (LispObjects) while keeping compatibility with existing C. Finally, it's an opportunity to use the strengths of the library ecosystem, and to discover and put into place missing pieces.
As long as there is substantial core infrastructure maintained on the C side, we have to make concessions. As soon as we completely control a core piece, we can make it more idiomatic (for example, if we can port the core of Emacs' hash tables, we can make it use the standard HashMap, see #251).
In any case, Rust is not only about avoiding unsafe code. It is also about collecting a small kernel of unsafe, making sure safety guarantees are upheld at the boundary, and abstracting it away for the consumers, as much as possible in a zero-cost way.
Regarding #255 in particular, there's nothing I can see that's especially unsafe there.
But yes, the goal is to avoid as many bugs as possible using the static guarantees of Rust. One very trivial but hopefully clear example of how we already do this is the API to cast the anytype LispObject to specific variants, let's say a float. Emacs C writes this as CHECK_FLOAT(x) followed by a float = EXTRACT_FLOAT(x), which will simply do something undefined when the CHECK was forgotten and you pass something different. In Rust, we have as_float() which returns None or Some(float), both of which cases must be handled.
To add to what @birkenfeld said, which was well said, I would like to quote a post I made on Hacker News about this subject:
I believe there are hidden benefits to an incremental rewrite to Rust executed this way.
In the long term, not only will we have safer code, but we will have less of it to maintain. This is not just because of using crates, but from being able to eliminate a lot of legacy code paths that aren't relevant anymore for our supported platforms.
Beyond general safety, I believe that Rust will give us a unique advantage in solving certain long term problems in the emacs community that have been difficult to address (in my opinion) partially because of the C language, such as threading key parts of emacs that are currently single threaded, or the unexec problem (https://github.com/Wilfred/remacs/issues/105).
In addition to the great answers above, let me clarify a little regarding unsafe.
Remacs will always have some unsafe code in it.
Elisp uses tagged pointers, which can only be dereferenced after you've checked the tag. It's easy to provide a safe interface on top, but this will always be unsafe.
Using the Emacs FFI is interacting with arbitrary C code, so that's unsafe.
The bytecode interpreter (written in C) deliberately contains some array access without range checks (for performance), assuming that Emacs always generates valid bytecode. Remacs will probably want to do the same thing.
I suspect the garbage collector (when ported to Rust) will contain some unavoidable unsafe bits.
Overall, we should be able to move to a codebase with very few unsafe blocks. At the moment however, the Rust code calls into the C code in many places, which requires unsafe blocks too.
I don't think this needs to be kept open.
Most helpful comment
In addition to the great answers above, let me clarify a little regarding
unsafe.Remacs will always have some unsafe code in it.
Elisp uses tagged pointers, which can only be dereferenced after you've checked the tag. It's easy to provide a safe interface on top, but this will always be unsafe.
Using the Emacs FFI is interacting with arbitrary C code, so that's unsafe.
The bytecode interpreter (written in C) deliberately contains some array access without range checks (for performance), assuming that Emacs always generates valid bytecode. Remacs will probably want to do the same thing.
I suspect the garbage collector (when ported to Rust) will contain some unavoidable unsafe bits.
Overall, we should be able to move to a codebase with very few unsafe blocks. At the moment however, the Rust code calls into the C code in many places, which requires unsafe blocks too.