Skip Navigation

Search

Why Rust mutexes look like they do - Cliffle

16

#rust analyzer question for #emacs folks

\#rust analyzer question for #emacs folks In client more I see run and debug But gui emacs I don't .. why pfa

@rust

2

Is there a way to detect all structs in the current crate that implement a certain trait?

Hi all.

I want to develop a plugin system within my program, and I have a trait that functions defined by plugins should implement.

Currently, my code gets all the functions in a HashMap and then calls them by their name. Problem is, I have to create that hashmap myself by inserting every function myself.

I would really appreciate it if there was a way to say, suppose, all pub members of mod functions:: that implement this trait PluginFunction call register(hashmap) function. So as I add more functions as mod in functions it'll be automatically added on compile.

Pseudocode:

Files: src/ ├── attrs.rs ├── functions │   ├── attrs.rs │   ├── export.rs │   └── render.rs ├── functions.rs ├── lib.rs

Basically, in mod functions I want: impl AllFunctions{ pub fn new() -> Self { let mut functions_map = HashMap::new();[[ register_all!(crate::functions::* implementing PluginFunction, &mut functions_map); Self { function_map } } } Right now I'm doing: impl AllFunctions{ pub fn new() -> Self { let mut functions_map = HashMap::new();[[ crate::functions::attrs::PrintAttr{}.register(&mut functions_map); crate::functions::export::ExportCSV{}.register(&mut functions_map); crate::functions::render::RenderText{}.register(&mut functions_map); // More as I add more functions Self { function_map } } }

10
0

World Wonders Explorer - small Leptos site demoing a free API I built

Hey all, just sharing a small, single-page site I built using Leptos + TailwindCSS, mainly intended as a demo for an API I built using Axum. Hope someone also finds it interesting!

I'm sharing this site and not the API itself cause I figure it's easier to look at and understand, but if you want to roast some code I would appreciate any feedback you have on the API itself (repo here). Trying to leave the front end developer scene so this is the first API I've tried building, fairly basic but it was fun (I am a big Civ V fan - I hear it's inspired by some niche thing called human history?).

Edit: whoops, looks like the link didn't get set cause I put an image - the site is available here, and the repo for it is here. The live API is available here

2

Asterinas linux abi compatible OS core in Rust

After reading Drew's pitch to the rust community to write our own kernel, I've searched for "linux abi compatible rust kernel" and found "Asterinas". Surprised that it is not mentioned here

4

I sped up serde_json strings by 20%

1

Treedome 0.5.0: Local Encrypted Notes with Modern Features

codeberg.org treedome

A local-first, encrypted, note taking application organized in tree-like structures

treedome

cross-posted from: https://programming.dev/post/18265389 >Hello again everyone, Dihar here. It's been a while since the last release of treedome, but here you go! This release is all about UI update, emojis, and bug fixes. Please consult this git diff for a more detailed changelog https://codeberg.org/solver-orgz/treedome/compare/0.4.5...0.5.0. These are the highlight of the release. > > ! > > * Add emoji picker for title, will show up in tree! > * Text Editor toolbar is back, now with option to toggle both toolbar and floating menu independently! > * Checkbox is here! Thanks Mantine UI! > * You can check the size of each notes by navigating to Escape Menu -> Configure -> Show Note Sizes! > * Add created/last modified date in notes. Note created before this will not have this field and will set as today's date! > * Create child note can now be done through dropdown instead of only from shortcuts! > * Fix bugs of saving empty tree > * General UI update and more stability for auto scrolling in tree view > * Documentation update

0

Debug-time enforcement of borrowing rules, and safety in general.

Another crazy idea I share with this website.

I was developing a game and an engine in Rust, so I was reading many articles, most of which criticize the 'borrow checker'.

I know that Rust is a big agenda language, and the extreme 'borrow checker' shows that, but if it weren't for the checker, Rust would be a straight-up better C++ for Game development, so I thought: "Why not just use unsafe?", but the truth is: unsafe is not ergonomic, and so is Refcell<T> so after thinking for a bit, I came up with this pattern:

let mut enemies = if cfg!(debug_assertions) { // We use `expect()` in debug mode as a layer of safety in order // to detect any possibility of undefined bahavior. enemies.expect("*message*"); } else { // SAFETY: The `if` statement (if self.body.overlaps...) must // run only once, and it is the only thing that can make // `self.enemies == None`. unsafe { enemies.unwrap_unchecked() } };

You can also use the same pattern to create a RefCell<T> clone that only does its checks in 'debug' mode, but I didn't test that; it's too much of an investment until I get feedback for the idea.

This has several benefits:

1 - No performance drawbacks, the compiler optimizes away the if statement if opt-level is 1 or more. (source: Compiler Explorer)

2 - It's as safe as expect() for all practical use cases, since you'll run the game in debug mode 1000s of times, and you'll know it doesn't produce Undefined Behavior If it doesn't crash.

You can also wrap it in a "safe" API for convenience:

``` // The 'U' stands for 'unsafe'. pub trait UnwrapUExt { type Target;

fn unwrap_u(self) -> Self::Target; }

impl<T> UnwrapUExt for Option<T> { type Target = T;

fn unwrap_u(self) -> Self::Target { if cfg!(debug_assertions) { self.unwrap() } else { unsafe { self.unwrap_unchecked() } } } } ```

I imagine you can do many cool things with these probably-safe APIs, an example of which is macroquad's possibly unsound usage of get_context() to acquire a static mut variable.

Game development is a risky business, and while borrow-checking by default is nice, just like immutability-by-default, we shouldn't feel bad about disabling it, as forcing it upon ourselves is like forcing immutability, just like Haskell does, and while it has 100% side-effect safety, you don't use much software that's written in Haskell, do you?

Conclusion: we shouldn't fear unsafe even when it's probably unsafe, and we must remember that we're programming a computer, a machine built upon chaotic mutable state, and that our languages are but an abstraction around assembly.

20

graydon/rust-prehistory: historical archive of rust pre-publication development

github.com GitHub - graydon/rust-prehistory: historical archive of rust pre-publication development

historical archive of rust pre-publication development - graydon/rust-prehistory

GitHub - graydon/rust-prehistory: historical archive of rust pre-publication development

Excerpt:

> This is a reconstruction -- extracted and very lightly edited -- of the "prehistory" of Rust development, when it was a personal project between 2006-2009 and, after late 2009, a Mozilla project conducted in private. > > The purposes of publishing this now are: > > - It might encourage someone with a hobby project to persevere > - It might be of interest to language or CS researchers someday > - It might settle some arguments / disputed historical claims

Rust started being developed 18 years ago. This is how it looked until 14 years ago, where I believe the rest of development is on rust-lang/rust. The first Rust program looks completely different than the Rust we know today.

1

A table of publicly available Arena crates and their features

donsz.nl Arenas

Sometimes you just really need an arena. Sometimes for performance reasons, other times for lifetime-related reasons. In their most basic forms, they're just a vec with some extra guarantees. However, it's those extra guarantees that matter. I've found myself looking for the right kind of arena too ...

Table of Arena Crates

For a technical discussion of using arenas for memory allocation with an example implementation, see gingerBill's Memory Allocation Strategies - Part 2: Linear/Arena Allocators

0

COSMIC ALPHA 1 Released (Desktop Environment Written In Rust From System76)

system76.com System76 - Linux Laptops, Desktops, and Servers

System76 computers empower the world's curious and capable makers of tomorrow

10

How do I parse the escape characters of the content of a string literal input with nom?

So, I'm basically trying to parse a string literal with nom. This is the code I've come up with:

```rust use nom::{ bytes::complete::{tag, take_until}, sequence::delimited, IResult, };

/// Parses string literals. fn parse_literal<'a>(input: &'a str) -> IResult<&'a str, &'a str> { // escape tag identifier is the same as delimiter, obviously let escape_tag_identifier = input .chars() .nth(0) .ok_or(nom::Err::Error(nom::error::Error::new( input, nom::error::ErrorKind::Verify, )))?;

let (remaining, value) = delimited( tag(escape_tag_identifier.to_string().as_str()), take_until(match escape_tag_identifier { '\'' => "'", '"' => "\"", _ => unreachable!("parse_literal>>take_until branched into unreachable."), }), tag(escape_tag_identifier.to_string().as_str()), )(input)?;

Ok((remaining, value)) }

#[cfg(test)] mod literal_tests { use super::*;

#[rstest] #[case(r#""foo""#, "foo")] #[case(r#""foo bar""#, "foo bar")] #[case(r#""foo \" bar""#, r#"foo " bar"#)] fn test_dquotes(#[case] input: &str, #[case] expected_output: &str) { let result = parse_literal(input); assert_eq!(result, Ok(("", expected_output))); }

#[rstest] #[case("'foo'", "foo")] #[case("'foo bar'", "foo bar")] #[case(r#"'foo \' bar'"#, "foo ' bar")] fn test_squotes(#[case] input: &str, #[case] expected_output: &str) { let result = parse_literal(input); assert_eq!(result, Ok(("", expected_output))); }

#[rstest] #[case(r#""foo'"#, "foo'")] #[case(r#"'foo""#, r#"foo""#)] fn test_errs(#[case] input: &str, #[case] expected_err_input: &str) { let result = parse_literal(input); assert_eq!( result, Err(nom::Err::Error(nom::error::Error::new( expected_err_input, nom::error::ErrorKind::TakeUntil ))), ); } } ```

> Note: The example uses rstest for tests.

Although it looks a little bit complex, actually, it is not. Basically, the parse function is parse_literal. The tests are separated for double quotes and single quotes and errors.,

When you run the tests, you will realize first and second cases for single and double quotes run successfully. The problem is with the third case of each: #[case(r#""foo \" bar""#, r#"foo " bar"#)] for test_dquotes and #[case(r#"'foo \' bar'"#, "foo ' bar")] for test_squotes.

Ideally, if a string literal is defined with single quotes and has single quotes in its content, the single quotes can be escaped with single quotes again. Same goes for double quotes as well. To demonstrate in a pseudocode:

plain "foo ' bar" // is ok "foo \" bar" // is ok "foo " bar" // is err 'foo " bar' // is ok 'foo \' bar' // is ok 'foo ' bar' // is err

Currently, in the code, I take characters until the delimiter with take_until, which reaches to the end of the input, which, let's say, in this case, is guaranteed to contain only and only the string literal as input. So it's kind of okay for first and second cases in the tests.

But, of course, this fails in the third cases of each test since the input has the delimiter character early on, finishes early and returns the remaining.

This is only for research purposes, so you do not need to give a fully-featured answer. A pathway is, as well, appreciated.

Thanks in advance.

3

System76 with Jeremy Soller | Rust in Production Podcast S02 E07 by corrode Rust Consulting | 2024-07-25

corrode.dev System76 with Jeremy Soller - Rust in Production Podcast | corrode Rust Consulting

Many devs dream of one day writing their own operating system. Ideally in their favorite language: Rust. For many of us, this dream remains just that: a dream. Jeremy Soller from System76, however, didn't just contribute kernel code for Pop!_OS, but also started his own operating system, RedoxOS, wh...

System76 with Jeremy Soller - Rust in Production Podcast | corrode Rust Consulting

> Many devs dream of one day writing their own operating system. Ideally in their favorite language: Rust. For many of us, this dream remains just that: a dream. > > Jeremy Soller from System76, however, didn't just contribute kernel code for Pop!_OS, but also started his own operating system, RedoxOS, which is completely written in Rust. One might get the impression that he likes to tinker with low-level code! > > In this episode of Rust in Production, Jeremy talks about his journey. From getting hired as a kernel developer at Denver-based company System76 after looking at the job ad for 1 month and finally applying, to being the maintainer of not one but two operating systems, additional system tools, and the Rust-based Cosmic desktop. We'll talk about why it's hard to write correct C code even for exceptional developers like Jeremy and why Rust is so great for refactoring and sharing code across different levels of abstraction.

Listen to Rust in Production Podcast S02 E07

1

Jiff is a new date-time library for Rust that encourages you to jump into the pit of success

github.com GitHub - BurntSushi/jiff: A date-time library for Rust that encourages you to jump into the pit of success.

A date-time library for Rust that encourages you to jump into the pit of success. - BurntSushi/jiff

GitHub - BurntSushi/jiff: A date-time library for Rust that encourages you to jump into the pit of success.
26

Anyone looking for a fun small rust project? Create a crate for cleaning urls, based on the ClearUrls project

cross-posted from: https://lemmy.ml/post/18162485

> This would entail: > > - Pulling in the ClearUrls rules as a git submodule. > - Reading / transforming the json there into Rust structs. > - Creating a Rust crate that runs a .clean(input_url) -> String > > Lemmy issue: https://github.com/LemmyNet/lemmy/issues/4905

0

diesel_async 0.5 released, with SQlite support

github.com Release Diesel-Async 0.5.0 · weiznich/diesel_async

Added type diesel_async::pooled_connection::mobc::PooledConnection MySQL/MariaDB now use CLIENT_FOUND_ROWS capability to allow consistent behaviour with PostgreSQL regarding return value of UPDATe ...

Release Diesel-Async 0.5.0 · weiznich/diesel_async

> - Added type diesel_async::pooled_connection::mobc::PooledConnection > - MySQL/MariaDB now use CLIENT_FOUND_ROWS capability to allow consistent behaviour with PostgreSQL regarding return value of UPDATe commands. > - The minimal supported rust version is now 1.78.0 > - Add a SyncConnectionWrapper type that turns a sync connection into an async one. This enables SQLite support for diesel-async > - Add support for diesel::connection::Instrumentation to support logging and other instrumentation for any of the provided connection impls. > - Bump minimal supported mysql_async version to 0.34 > > A special thanks goes to @momobel and Wattsense for contributing the SyncConnectionWrapper implementation. > > To support future development efforts, please consider sponsoring me on GitHub. > > Full Changelog: v0.4.0...v0.5.0

0

Ferris is now on the Fediverse Canvas!

I hope this slightly off-topic post is ok here. Today the Fediverse Canvas 2024 event begun and I thought it would be nice to add Ferris to the canvas. I started with a couple of pixels, but after a while I got distracted with other things. When I came back, I found that some of you have already finished it 🦀

Btw. Ferris sits on top of the Godot logo (bottom and slightly right).

5

Should RustSec (Advisory Database and Cargo tools) be embraced at the foundational level and made a "mandatory best practice"?

rustsec.org About RustSec › RustSec Advisory Database

Security advisory database for Rust crates published through https://crates.io

Hi all,

ref: https://programming.dev/post/16349359

I agree with all the criticism about the author, the intentions, and the points in the article, expressed in the ref. thread. I also think the author highlights a serious issue (if we leave "selling the book", cheap criticism, and sensationalism aside). While nothing new for most developers, the article has spawned a personal rabbit hole of discovery, starting from supply chain attacks.

I am still very early in my process of learning Rust (still reading The Book) and self-taught software engineering in general, and the journey the article has spawned was very educational to me. I've learned about securing software and being mindful across the whole SDLC[1], AppSec, DevSec, OWASP, SLSA[2] Socket[3], GitHub Advanced Security, and many more tools and guidelines. Last of which is RustSec[4]. Which quenched my thirst and closed that personal rabbit hole. It has opened a different can of worms though.

While endemic to any non-monolithic ecosystem and only part of the "big security picture", supply chain is possibly the major player across the spectrum. Comparable to "the legacy issue" of stagnating systems and infrastructures, open to exploits as old as the Sun.

Now, while I am aware that security is a process, not a product and that this is easier said than done: I wonder if tools like RustSec should be embraced at the foundational level and made a "mandatory best practice". RustSec tools integrate with an up to date security advisory database and Cargo. They can also be deployed as GitHub Actions.

Because I am sure this is not all roses: I agree that (for example) dependabot is seen as a major annoyance more than a useful tools for a number of reasons, and that RustSec could spark the same kind of thoughts. However, it could be a great stepping stone of the security process.

I am aware I may be being too idealistic here, but the process has to start from somewhere and stagnating on "dogmas" ain't helping either.

Please be kind in your replies.

Cheers

[1] https://www.youtube.com/watch?v=hDvz8KivY_U [2] https://slsa.dev [3] https://socket.dev [4] https://rustsec.org

6

Rust has a HUGE supply chain security problem | Sylvain Kerkour | July 2, 2024

July 2, 2024

Sylvain Kerkour writes:

> Rust adoption is stagnating not because it's missing some feature pushed by programming language theory enthusiasts, but because of a lack of focus on solving the practical problems that developers are facing every day. > > ... no company outside of AWS is making SDKs for Rust ... it has no official HTTP library. > > As a result of Rust's lack of official packages, even its core infrastructure components need to import hundreds of third-party crates. > > - cargo imports over 400 crates. > > - crates.io has over 500 transitive dependencies. > > ...the offical libsignal (from the Signal messaging app) uses 500 third-party packages. > > ... what is really inside these packages. It has been found last month that among the 999 most popular packages on crates.io, the content of around 20% of these doesn't even match the content of their Git repository. > > ...how I would do it (there may be better ways): > > A stdx (for std eXtended) under the rust-lang organization containing the most-needed packages. ... to make it secure: all packages in stdx can only import packages from std or stdx. No third-party imports. No supply-chain risks.

[stdx packages to include, among others]:

> gzip, hex, http, json, net, rand

Read Rust has a HUGE supply chain security problem

---

Submitter's note:

I find the author's writing style immature, sensationalist, and tiresome, but they raise a number of what appear to be solid points, some of which are highlighted above.

25
#rust analyzer question for #emacs folks
  • @thevoidzero not doom/space just regular emacs with vterm ( 29±)
    rust is nightly on nixos 24.11 last I checked
    in a devshell
    rust setup
    https://git.sr.ht/~carnotweat/morning-rust

  • [Help] Is there a way to detect all structs in the current crate that implement a certain trait?
  • No, macros can see only the tokens you give them. They have no notion of the fact that crate::functions is a module, that PluginFunction is a trait and that functions_map is a variable. Not even the compiler may know those informations when the macro is expanded.

    If you really really want to do this, you can use something like inventory. Note that inventory uses a special linker section to do this, which some consider a hack. This is also not supported on WASM if you want to target it.

  • Changes to `impl Trait` in Rust 2024
  • I have observed people taking Rust seriously. You need to reexamine your assumptions.

    We have an evolved capability to short-circuit decisions with a rapid emotional evaluation. It means as a species we didn't die out early ["that's a lion; I'm a oerson; lions eat people ergo... Agh!" is not a sustainable strategy] - what's amazing is that we can also apply it to elarned abstract things like an aestetic sense about programming languages. Such instincts aren't always perfect, but they're still worth paying attention to. I don't see a reason not to express that in a blog post, but you can replace it with "this is unergonomic and in some cases imprecise" if you prefer.

  • Announcing Rust 1.81.0
  • It's a subtle difference between that and path::exists().

    • path::exists() == false might just mean you can't use it (if path::exists() cannot access a file due to e.g. permissions, it'll return false)
    • fs::exists() == Ok(false) means it's definitely not there (permissions error will cause an Err to be returned)
  • Asterinas linux abi compatible OS core in Rust
  • Oh wow.. This might be what the rust in Linux people need to switch to. Fuck all the LKML bullshit, fuck mailinglists, fuck C, fuck the shitty tooling and hodgepodge of languages. This looks amazing. Seriously, cargo run and the kernel starts up in a VM? How friggin cool is that?

    Wow...

    Anti Commercial-AI license

  • Derailed talk regarding Rust's integration into the Linux filesystem
  • Again, the Linux kernel needs more funding. For crying out loud, these kinds of people holding back progress should be made obsolete (by bringing in and paying talent that is willing to work towards a brighter future with less memory errors, a sane tech stack with better tooling, and better processes). Holding back progress because of their incessant pearl clutching "but my dearest C!!!" Just hurts everybody and impedes progress.

    Of course blindly adding the latest and greatest is asking for trouble. Assessing risk, weighing options, making a plan and continuously assessing impact is definitely important, but straight up blocking the road on principle is extremely unproductive.

    Anti Commercial-AI license

  • Async Rust can be a pleasure to work with (without `Send + Sync + 'static`)
  • but futures only execute when polled.

    The most interesting part here is the polling only has to take place on the scope itself. That was actually what I wanted to check, but got distracted because all spawns are awaited in the scope in moro's README example.

    async fn slp() {
        tokio::time::sleep(std::time::Duration::from_millis(1)).await
    }
    
    async fn _main() {
        let result_fut = moro::async_scope!(|scope| {
            dbg!("d1");
            scope.spawn(async { 
                dbg!("f1a");
                slp().await;
                slp().await;
                slp().await;
                dbg!("f1b");
            });
            dbg!("d2"); // 11
            scope.spawn(async {
                dbg!("f2a");
                slp().await;
                slp().await;
                dbg!("f2b");
            });
            dbg!("d3"); // 14
            scope.spawn(async {
                dbg!("f3a");
                slp().await;
                dbg!("f3b");
            });
            dbg!("d4");
            async { dbg!("b1"); } // never executes
        });
        slp().await;
        dbg!("o1");
        let _ = result_fut.await;
    }
    
    fn main() {
        let rt = tokio::runtime::Builder::new_multi_thread()
            .enable_all()
            .build()
            .unwrap();
        rt.block_on(_main())
    }
    
    [src/main.rs:32:5] "o1" = "o1"
    [src/main.rs:7:9] "d1" = "d1"
    [src/main.rs:15:9] "d2" = "d2"
    [src/main.rs:22:9] "d3" = "d3"
    [src/main.rs:28:9] "d4" = "d4"
    [src/main.rs:9:13] "f1a" = "f1a"
    [src/main.rs:17:13] "f2a" = "f2a"
    [src/main.rs:24:13] "f3a" = "f3a"
    [src/main.rs:26:13] "f3b" = "f3b"
    [src/main.rs:20:13] "f2b" = "f2b"
    [src/main.rs:13:13] "f1b" = "f1b"
    

    The non-awaited jobs are run concurrently as the moro docs say. But what if we immediately await f2?

    [src/main.rs:32:5] "o1" = "o1"
    [src/main.rs:7:9] "d1" = "d1"
    [src/main.rs:15:9] "d2" = "d2"
    [src/main.rs:9:13] "f1a" = "f1a"
    [src/main.rs:17:13] "f2a" = "f2a"
    [src/main.rs:20:13] "f2b" = "f2b"
    [src/main.rs:22:9] "d3" = "d3"
    [src/main.rs:28:9] "d4" = "d4"
    [src/main.rs:24:13] "f3a" = "f3a"
    [src/main.rs:13:13] "f1b" = "f1b"
    [src/main.rs:26:13] "f3b" = "f3b"
    

    f1 and f2 are run concurrently, f3 is run after f2 finishes, but doesn't have to wait for f1 to finish, which is maybe obvious, but... (see below).

    So two things here:

    1. Re-using the spawn terminology here irks me for some reason. I don't know what would be better though. Would defer_to_scope() be confusing if the job is awaited in the scope?
    2. Even if assumed obvious, a note about execution order when there is a mix of awaited and non-awaited jobs is worth adding to the documentation IMHO.
  • Async Rust can be a pleasure to work with (without `Send + Sync + 'static`)
  • I skimmed the latter parts of this post since I felt like I read it all before, but I think moro is new to me. I was intrigued to find out how scoped span exactly behaves.

    async fn slp() {
        tokio::time::sleep(std::time::Duration::from_millis(1)).await
    }
    
    async fn _main() {
        let value = 22;
        let result_fut = moro::async_scope!(|scope| {
            dbg!(); // line 8
            let future1 = scope.spawn(async {
                slp().await;
                dbg!(); // line 11
                let future2 = scope.spawn(async {
                    slp().await;
                    dbg!(); // line 14
                    value // access stack values that outlive scope
                });
                slp().await;
                dbg!(); // line 18
    
                let v = future2.await * 2;
                v
            });
    
            slp().await;
            dbg!(); // line 25
            let v = future1.await * 2;
            slp().await;
            dbg!(); // line 28
            v
        });
        slp().await;
        dbg!(); // line 32
        let result = result_fut.await;
        eprintln!("{result}"); // prints 88
    }
    
    fn main() {
        // same output with `new_current_thread()` of course
        let rt = tokio::runtime::Builder::new_multi_thread()
            .enable_all()
            .build()
            .unwrap();
        rt.block_on(_main())
    }
    

    This prints:

    [src/main.rs:32:5]
    [src/main.rs:8:9]
    [src/main.rs:25:9]
    [src/main.rs:11:13]
    [src/main.rs:18:13]
    [src/main.rs:14:17]
    [src/main.rs:28:9]
    88
    

    So scoped spawn doesn't really spawn tasks as one might mistakenly think!

  • One Of The Rust Linux Kernel Maintainers Steps Down - Cites "Nontechnical Nonsense"
  • How much more? When it comes to whether I'd write GPU drivers for money, I can tell you that LF doesn't pay enough, Collabora doesn't pay enough, Red Hat doesn't pay enough, and Google illegally depressed my salary. Due to their shitty reputation, Apple, Meta, or nVidia cannot pay enough. And AMD only hires one open-source developer every few years. Special shoutout to Intel, who is too incompetent to consider as an employer.

  • One Of The Rust Linux Kernel Maintainers Steps Down - Cites "Nontechnical Nonsense"
  • It's such a shame that Rust developers feel like they feel unwelcome, especially due to a complete misunderstanding in implementation details.

    Even worrying, this is kernel developers saying they prioritise their own convenience over end user safety.

    Google has been on a Rust adoption scheme, and it seems to have done wonders on Android: https://security.googleblog.com/2022/12/memory-safe-languages-in-android-13.html?m=1

    But also, there is a bit of a problem to adopt Rust. I think the memory model may prove challenging to some, but I do worry in this case that even if it was super simple, the existing C kernel devs would still reject the code due to it not being C and not willing to adopt a new language.

  • Why am I writing a Rust compiler in C?
  • It seems it would be a lot easier to work on the GCC compiler, and work with others to bootstrap GCC (if it hasn't already been done). Getting the GCC Rust compiler able to compile some version of rustc probably wouldn't be that hard, and then you can just use that version to compile up the chain to modern Rust.

  • Why am I writing a Rust compiler in C?
  • A lot of this bootstrapping stuff comes back to the 'trusting trust' attack. You could write a compiler that adds some malicious code to programs it compiles. But the thing is, it could also insert it's own malicious code when compiling a compiler. So you look at your code, and the code of your compiler, and everything looks fine, but the exploit is still there. Someone wrote an example in rust.

    Theoretically there could also be bugs that propagate this way. So to fully trust your code is doing what you think it is, you'd need a chain of compilers back to hand coded assembly.

  • Why am I writing a Rust compiler in C?
  • Then there is the question of where the CPU is supposed to come from. Any modern one was designed using lots of mysterious CAD tools. Maybe scrounge a vintage Z80 out of an old Timex-Sinclair or something?

    Ben Eater has entered the chat

  • Why am I writing a Rust compiler in C?
  • The main thing is that TinyCC has already been bootstrapped.

    Check out this page on bootstrappable.org. Basically they start with a 200 something byte binary (hex0) that can act as an assembler, then using a bunch of layers of tools and compilers you can bootstrap a whole system. I think they use stage0 to build M2-Planet, use that to build GNU Mes, and use that to build TinyCC.

    So a project like this fits neatly into that bootstrapping path. It could be done other ways, but starting from a fairly complete C compiler makes it a lot easier than building an entire path from scratch.

  • What are you working on this week? (Aug. 25, 2024)
  • i'm tricking the nintendo switch into thinking my computer is a bluetooth pro controller. I'm using a crate called bluer which exposes bindings to the BlueZ stack and it's been great to use.

    I got to the point where it pairs the controller and hits B to exit. However it doesnt seem to accept any more button presses after that... :) So I have some ways to go.

    I've also needed a project where I can challenge myself with the basics of async without it being overwhelming, and I think this hits the sweet spot. It's my first time using tokio spawn, join, and select in a real project!

  • What are you working on this week? (Aug. 25, 2024)
  • Rewriting huge parts of the IDL compiler for Nucom, my implementation of Microsoft’s COM binary interface standard and (in the future) network protocol. The original version was hacked together with a lot of assumptions made in the parser and isn’t very extensible, and I do need to extend it now.

    (Nucom is another way to have a stable ABI for Rust, e.g. for a plugin interface, and for Rust/C++ (and more OOP-style C) interop, based on objects with vtable pointers. And hopefully sometime in the future, transparent IPC and networking so you don’t have to load plugins into your process’s memory space if they don’t need to be there, with it working the same as if it were direct calls. All of this I assume you can already do on Windows with the windows-rs crate but it's obviously Windows-only.)

    I do have to say though, I need a better way of transforming my syntax tree. Right now I’m just copying the struct definitions over and over for each compile stage and manually writing code to copy everything instead of just the parts I’m actually transforming, and it just seems like there has to be a better way. I might want another proc macro for this.