I don’t wanna have to do this.

andrew kelley is wrong about rust but he already knew that

Let’s start with the issue title:

introduce an actually memory safe (unlike borrow checking) compilation mode inspired by Fil-C

Judging by the rest of the post, Kelley’s actual memory-safety objections with Rust are that it can link with nonmemorysafe C and it can violate memory safety in unsafe blocks. Not to point out the obvious, but neither of these features are borrowchecking.

If you had a language which couldn’t link with C, didn’t have an unsafe “escape hatch”, and ensures memory accesses are safe at compile time by encoding lifetime information into the type system aka a “borrow checker”, everything you could write in it would be memory safe, because the issue title is wrong and borrow checking is actually memory safe.

When Kelley writes an issue with this needlessly standoffish title and then gets all herp derp rustaceans mad in the replies it’s just kinda embarassing? Yes of course people think you’re a fool for calling borrowchecking “not actually memory safe”, because it’s wrong and you’re obviously trying to start shit.

“okay but in practice”

and, in the case of Rust, additional use of unsafe beyond FFI.

Rust programmers can-and-do write safe wrappers around unsafe code, yes. Like there’s RefCell. If you have an immutable reference to the RefCell then you can get mutable references to its contents, normally very illegal under Rust’s implementation of borrowchecking, but it’s still memory-safe because it panics at runtime if you try to get two mutable references to the same value.

Implementing RefCell requires unsafe code. Fortunately, you don’t have to implement it because it’s part of the standard library, and any memory-safety-related bugs with it would be reported to Rust (they’d be on the same level as a miscompile).

My (rhetorical) question is, is this not just the Fil-C thing. We have a memory-safety invariant which can’t be checked at compile-time (pointer aliasing, in this case) so we check it at runtime instead. The difference is that Rust checks a lot more at compile-time so it doesn’t need as many runtime checks, and its runtime invariants are simpler and pay-as-you-go (“is this value borrowed or not”, rather than a capabilities system which stows data before every single allocation just in case).

It’s true that a bug in the bedrock layer of unsafe code can endanger the memory-safety guarantees of the rest of the project. The same is true for a bug in Fil-C; it’d be treated as a miscompile.

a restrictive toolchain?

Once [The Fil-inspired ABI] is implemented then, in a twist of fate, Zig will become one of the only toolchains capable of producing actually memory safe executables

I just think it’s silly to define a toolchain by what it can’t do. If “fully memory safe, no escape hatch” deserves bolded letters in the post, then does it check I’m not writing to /proc/self/mem, does it check that my shared library which adheres to the Fil-C ABI doesn’t do unchecked pointer accesses in its assembly code, does it check that it doesn’t upload your browser cookies to my server (because if the point of “defining a toolchain by what it can’t do” is that you can always trust the output without needing to trust your dependencies, why only trust it along the memory-safety axis). There’s no technical magic-wand workaround for vetting your dependencies, is my point, and Rust has established tools for vetting dependencies. If Rust isn’t actually memory safe because you can type unsafe, then don’t type it.

also, cmon

Is introducing a constant-factor slowdown in the name of safety the best possible future for software? I don’t doubt that Fil-C is an incredible technical achievement: it turns C into a memory safe language (at a runtime cost because C isn’t very good at being a memory-safe language). My opinion is that it’s a great stopgap for emergency safetyifying old C code, but the best programming-language research is in finding languages which are memory-safe without needing a thousand just-in-case checks every time you’re in the vicinity of a pointer, and the best way to use our hardware is to write new programs in those languages. Famously it’s not hard to design a new memory-safe language if you throw in boundschecks and a garbage collector (Java is memory safe!)

There’s more points on the pareto frontier than “fast but yolo-ed runtime checks” and “completely runtime-checked but slow”

Honestly I think two different questions are being asked (memory-safety vs “hardening”)

memory safety is woke and gay

Last month some idiots forked Git, deleted the code of conduct, renamed the default branch to master, removed all the Rust code, and then forgot about it. The Fil-C developer decided this is a great project to send a pull request to. A couple weeks later Andrew Kelley just loves memory safety but only when it’s done in the Fil-C way and let me also weirdly bash Rust while I’m at it.

Everyone likes memory safety in concept, but systems-language memory safety is associated with Rust and is therefore woke and gay; except now we have an antiwoke option so memory safety is back on the table, and the gay memory safety is not “actually memory safe” all of a sudden. Ah well! Funny how that works

objections

“oh yeah where’s your zig code”

(because I guess this matters).

Well I don’t write Rust anymore either. So there.