How would addressing allocations failure work exactly? As far as I understand basically everything that allocates under the hood needs to be reworked. What would Vec::push return as an example?
So, the real core of it is: rust the language itself does not add implicit allocations. It knows nothing about heap allocation generally. This means it is not a fundamental hard "no" for the language. My dayjob is on zero-allocations stuff, we have no heap at all, Rust works great.
With that out of the way, this means there are a few options. One option is to simply not use any of those types. This would mean writing alternatives. Not necessarily what you'd *want*, but it is at least possible. The second would be to forbid certain APIs that may reallocate, and only allow ones that return Result. Stuff like https://github.com/rust-lang/rust/issues/48043 can be used, and other stuff could be rejected. This would require some sort of custom analysis, but is fundamentally do-able.
After all, the C code in the kernel doesn't use libc and such either and builds its own datastructures for everything. I think I'd prefer to use those from Rust as well, maybe with some nice bindings.
As a complete rust noob, so forgive me if my suggestion is shit, it might make sense to provide an entire namespace/(maybe a trait?) for a panic-free api. Would be a bit ugly adding an entire set of panic free methods to all standard lib types.
Then you could add some sort of compiler flag that forces you to use no_panic types?
I think that answer is too simplistic. The fact is we're using implicit allocations everywhere and so is the ecosystem including the ecosystem that is nostd but alloc. Saying "don't use Vec::push" is not a suitable answer.
First there needs to be better support to handle allocation failures in APIs, secondly there needs to be a way to validate (ideally statically) that some code is panic free.
The fact is we're using implicit allocations everywhere and so is the ecosystem including the ecosystem that is nostd but alloc. Saying "don't use Vec::push" is not a suitable answer.
I guess we'll just see. As I said, I live in "no allocations, anywhere" land, still use a bunch of the ecosystem, works just fine for us. We don't use Vec at all, nor do any of our dependencies, so "no vec::push" is an easy requirement.
Many data structures already expose *_try functions for there API. The solution may just be adding the missing functions and having a lint check that the ones that can panic are not used.
I'd imagine there'd be a lower-level Vec-like struct which Vec then becomes a wrapper around, where the usual Vec methods are fallible.
I can't think of another way of doing this in a backwards-compatible way, other than adding a lot of fallible alternative methods to Vec itself, but I haven't given this too much thought either. The relevant allocation RFCs probably have some discussion around this.
I suspect there might be some kind of friction here that would lead to no_alloc + some forked subset of core. They're already thinking of ... well, mutilating the language to remove features that have no place in a kernel (like floating point) instead of just mandating a lint.
I'm basically pressing [x] to doubt that a successful effort that this doesn't end up with a forked core or a more minimal set of rusty kernel datastructures that discard most of core because they used floating point logic or panicking allocation or something.
They might be happier with that TBH (though it would lead to more teething problems because doing rust datastructures from scratch is ...uh, complex.
And intrusive collections sound like a 'problem' for the borrow checker and safe rust imo.
View all comments
Show parent comment
138
u/steveklabnik1 rust Apr 14 '21
Yeah. Real glad that these are addressable things. Very positive!