I committed a patch yesterday that I thought was a very good first start. However, this morning I've found some holes in it that make things look very bleak again.
What my patch did was simply ensure one thing -- that whenever an alias was taken, it was verified that it was 'rooted' in a thing that would outlive it, where rooted means the value is either a local variable that isn't assigned to for the lifetime of the alias, or a local temporary value (which can't be assigned to), or it is a field directly dereferenced from another root, with the caveat that dereferencing a mutable field and then a box isn't allowed, because the mutable field could be reassigned, potentially freeing the box. This required only a handful changes to uses of aliases in our current code, and gets by without any kind of alias analysis. That's nice, because alias analysis is impossible to do perfectly, and since this is core behaviour, if we ever want to standardize Rust, we'd have to fix on some heuristic algorithm, describe it in the spec, and require every implementation to do exactly what our rustc does to be compatible. Since decent alias analysis is arbitrarily complex, this sound unattractive. Unfortunately, there's this hole I mentioned before. What this analysis guarantees is that the location pointed to by an alias will always hold a value of type X — if you reassign to it, the alias will still be valid. Except when going through a tag type. If you have an alias inside a tag (as alt creates them) and you reassign its parent, your alias might not point at memory of the right type anymore. You can restrict values used for alt further, requiring that they are not just rooted, but 'rooted immutably' -- if they dereference their root, they may only do so through immutable fields/indices/unboxing. A very typical pattern in code is to take an alias and do an alt on that. Four ways to handle this case come to mind, all unattractive: - Require all aliases to be immutably rooted. This breaks a *lot* of code, and would require much extra copying. If we went to a radically functional paradigm, this might work, but Rust is just not that kind of language. - Don't allow stuff rooted in an alias to be matched with alt. Again, breaks tons of code, requires clunky copying to fix. - Make alt implicitly (or explicitly) copy stuff. Not good for efficiency either. - Have two kinds of aliases, those that must be immutably rooted and those that don't. Even more pointer types. I think I'm somewhat of out of ideas here. The scheme Patrick described with swapping unique pointers in and out would provide something of an solution that doesn't copy, but that moves Rust so far away from convenient simplicity that I really can't get behind it. You'd have a ritualized song and dance, with a bunch of leaky abstraction issues, every time you need to pass something by alias. It's important to keep in mind that if the avoidance of refcounting creates more indirection and overhead than the refcounting itself, we're on the wrong track. So, I'm about ready to try an 'everything is garbage collected' approach. There is a reason almost all recent languages have moved to that... Best, Marijn _______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
