From the start of this year, I have slowly been going about designing a query system for Krabby. It took five months of sitting still and thinking really hard, but I believe I have a clear grasp of the design now. I’m going to explain why Krabby needs a query system (because I thought it wouldn’t for a while), the special features I wanted, and how everything fits together.
read more…
I’m ecstatic to announce that, from July 22, I will be paid to work on rustc and Krabby for one day a week. This is an internship at RustNL (as part of The Rust Maintainers Team) enabled by my employer NLnet Labs, which will last up to a year. I’m immensely grateful to everyone involved in making this happen! In this post, I’m going to lay out how I will spend this time.
read more…
std::mem::offset_of! is a helpful little macro that lets you compute the offset of a particular field of a struct at compile time. I haven’t had much use for it myself, but a friend has been using it for a cool JIT’ed scripting language for Rust, so it’s come up occasionally.
It has a few quirks, though: you can’t use it for unsized fields (e.g. b in Foo { a: u8, b: [u8] }). This isn’t too common, but if you’re doing weird enough things that you need to compute byte offsets of fields, you are probably familiar with (and happy to (ab)use) dynamically sized types. Like all frustrating things, there’s a reason beneath the surface: in Rust, types that implement Sized have a fixed size and alignment, while others do not. With a type like Bar { a: u8, b: dyn Debug }, b could have an arbitrary type, thus an arbitrary alignment, thus an arbitrary offset.
read more…
I think it’s fairly obvious that I’m a perfectionist. Sometimes that drags me into the land of Linux system APIs — I once wrote a 300 line C program to replace the classic “run date every 60 seconds” loop you might find in your status bar. My goal was to use all the cool system calls I could find, be as efficient as possible, and update the date exactly on time. It was a lot of fun! I ran into a similar rabbit hole while trying to build a file system watcher, and the results were cool enough to deserve their own blog post.
read more…
I have a large backlog of posts to write, but I quickly wanted to share a fun idea I explored on Thursday. I’ve been thinking about how incremental compilation should work in Krabby, and a major sticking point there is spans. But I think I have a plan.
read more…
modeling
on ; by arya dradjicaVenting about the state of the world, in the shape of a poem.
read more…
To recap: it’s November 2025 and I’ve spent the last two-ish months working on identifier interning. My plans to implement name resolution by the end of the year were screwed, but I still wanted to spend substantial time on it.
To be honest, I think my foray into identifier interning was really to avoid implementing parsing. Parsing is just really, really hard. The Rust syntax is deeply complicated, it varies (in subtle ways) across editions, and you need to design an AST to parse into. I had already put a lot of effort into designing my own token stream format, which meant I couldn’t use existing parsers.
read more…
Last week, I happened to glance at the codebase for rust-analyzer. I realized that r-a and Krabby (my very-very-WIP Rust compiler) have a lot in common; r-a re-implements a lot of rustc and has benchmarks and tests to compare it to rustc. While Krabby has different high-level goals, it needs exactly the same infrastructure.
One component that stuck out to me was macro expansion. I’ve previously heard that r-a puts a lot of effort into macro expansion, partly to offer interesting LSP functionality (e.g. “expand this macro”) and partly because macros complicate normal LSP functionality (e.g. “goto definition”, if the definition is generated by a macro). While r-a sometimes re-uses code from rustc, a quick peek around the codebase revealed that most of r-a’s macro handling code is written from scratch. It also appears to be much simpler; I’m not sure whether that’s because it has been written more concisely (with hindsight from rustc), because it is less concerned with diagnostics, or because it differs from rustc in some edge cases.
read more…
Name resolution requires storing lots of identifiers and comparing them to each other very rapidly. While you could store identifiers as Strings and compare them using basic string equality, this is quite inefficient. A nearly universal approach is interning — assigning every identifier a unique numeric ID, and representing and comparing them by ID. Interning uses a hash table to deduplicate identifiers and ensure that distinct IDs refer to distinct identifiers.
read more…
Precisely one year and one week ago, on , I introduced Krabby. It all started because I had too many ideas about compiler architecture and they stopped fitting in my head. Ever since, Krabby has been the primary focus of my spare time. It’s my favorite thing to do; I’m incredibly grateful to have the time for it, and I’m incredibly proud of what I’ve achieved.
read more…
Krabby appeared on Lobste.rs last week, and I’ve since received e-mails from people interested in contributing! I’ve created a Zulip chat for discussions; feel free to join it whether you want to observe what’s happening or participate yourself. If you’re interested but unsure what you can help with, perhaps take a look at the list of open issues.
Some of those e-mails asked whether Krabby is still being actively developed. I will strongly affirm that; yes, Krabby continues, and I’m as motivated as ever (if not more now!). While it’s still incredibly limited in functionality, I have a lot of plans, and I’m really excited. Let me give you a quick status update.
read more…
I wake up on time to a quiet morning before dawn. I move through the steps of my daily routines, picking out my clothes and throwing open the curtains. I stare out to the gradual morning light, listening for birdsong. As I set myself some breakfast, I contemplate what I will do with the two hours before I start work: programming a concurrent memory reclaimer.
While the project has sat in my head for a while, I started writing the API and implementation yesterday. I trace the branches of the dimly-lit trees on my window, and I remember how astonishingly simple the code seems. I think about the underlying ring buffer, its structure as delicate as the little basil plant I am watering. I think about supporting MIRI and loom. I smile as I remember how proud I am of the name I picked – housekeeping. I think about the projects I need it for, and where they will lead. And I return to a familiar feeling, the throughline of all my work: the utter joy of and drive for making nice things.
read more…
I’m incredibly excited to announce that I’ll be giving a talk at RustWeek 2026! On May 20, I’ll talk about phonebook, my attempt to build the fastest identifier interner possible. My goal is to explain my process of optimization, particularly at a low level, and to show how fun it can be. I hope to give you the tools, knowledge, and inspiration to try optimizing your own projects in the same way.
read more…