News for hackers. Stuff that matters.
Re:Flattening ASTs (and Other Compiler Data Structures) by jlokier on Sunday July 02, 2023 @06:45AM (#36560210)
> In the process you avoid use-after-free, double-free, and accessing unallocated memory

You don't really avoid those things, though. In the process you end up with index-use-after-index-free, double-index-free, and accessing index-unallocated array entries.

These are the exact same bugs the borrow checker prevents in main memory, just hidden from the borrow checker by adding a layer of abstraction.

These are memory-unsafety bugs. You still get the same wrong answers caused by coding errors. Random junk values and behaviours, when dereferencing use-after-free invalid pointers that point to memory reused for a new object. It's just that pointers are now called indexes, and the borrow checker doesn't check these pointers.

It's like turning the borrow checker off for this set of objects. Those long-lived entities you mentioned act as a mechanism to enable that. That's useful to do, but nobody should be under the impression use-after-free, pointers to the wrong objects and other memory-unsafety bugs don't happen in the array index model.

Re:Flattening ASTs (and Other Compiler Data Structures) by avgcorrection on Sunday July 02, 2023 @06:54AM (#36560239)
> These are memory-unsafety bugs.

It seems that these are memory-unsafety bugs with the caveat that they have nothing to do with the memory allocator. Maybe a sort of sandboxed memory unsafety? I don’t know.

Re:Flattening ASTs (and Other Compiler Data Structures) by kmstout on Sunday July 02, 2023 @10:13AM (#36561666)
> nothing to do with the memory allocator

It's an application-specific memory allocator.

Re:Flattening ASTs (and Other Compiler Data Structures) by avgcorrection on Sunday July 02, 2023 @11:35AM (#36562429)
That’s in effect what I’m saying. You’ve implemented a memory allocator using the “system” one.
Re:Flattening ASTs (and Other Compiler Data Structures) by PartiallyTyped on Sunday July 02, 2023 @08:40AM (#36560930)
That's the specific case of (mis)using an arena, no? Could this be extended to the general model of ownership?
Re:Flattening ASTs (and Other Compiler Data Structures) by skybrian on Sunday July 02, 2023 @11:18AM (#36562239)
Yes, this is true, but sometimes it’s because pointer ownership is a poor fit for the problem. Sometimes dangling references are logically possible and what you want. (There should be a runtime check, though. Generation numbers can help.)

A compiler can only prevent bad things from happening within a system, typically just one process. The world around it doesn’t work that way. A system is often a cache, not an owner, and caches go out of date because the world changed without notice. You want to update on what notices you get that the world changed. You can’t prevent inconsistency, only detect it and react by updating or removing outdated information.

This probably isn’t relevant within a batch compiler, but it would be for a language service in an IDE.

Games often simulate worlds where references shouldn’t own things. It would be a weird form of power to remotely prevent something from getting destroyed because you remember it. Even though both objects are within the same process, they’re modeled as independent systems where pointer ownership doesn’t happen.

Re:Flattening ASTs (and Other Compiler Data Structures) by chlorion on Sunday July 02, 2023 @10:43PM (#36568105)
With something like the slotmap, you store a generation counter, so you can't accidentally use something that has been freed and recreated.

It also checks that the slot you are trying to get is occupied, and if it's not it won't let you access it. It actually is forced to check that the slot is occupied because the slot is an enum with vacant and occupied variants, and the vacant variant doesn't have a value to get in the first place. In rust you can't read a data out of an enum without checking the variant first.

With these two restrictions, you can't use stale keys, you can't UAF, and you can't read junk data at all, it's enforced by the type system and the runtime checks.

You can still have keys that are invalid, but the slotmap's "get" method returns an option type, and invalid keys cause it to return "None".

So in practice, you will end up panicking if your keys become invalid (the index operator panics when the return value is "None"), or you will explicitly handle the "None" case and do whatever you want to do.

All of this only applies to this specific data structure though, and the checks do have some performance cost.