WIP: Add Faux allocator API

This adds a alloc::faux module that implements an interpretation of @pnkfelix's proposed high-level allocator API (rust-lang/rfcs#244), optimized for the libstd usecases. This moves all of the tedious oom/zst/capacity-overflow logic into a central place, so that collections and other things don't need to think about it.

As part of this PR I have migrated RingBuf to this API as a proof of concept. Migrating Vec will likely be more tricky, because it does a lot more special tricks based on ZSTs, making the logic more tangled. It is possible that migrating to this API would cause a perf regression for duplicated checks/extra branching. However most of the checks are largely based on compile-time-constants, so I am optimistic about LLVM's ability to optimize these to death.

I guessed out the best semantics I could for some iffy things, like how the `alloc_array` API should handle `len = 0`.

I also am considering adding triple_alloc_array/triple_dealloc_array methods to handle the HashMap usecase (which BTree can also benefit from longterm).
I am considering deprecating realloc_array_inplace in favour of shrink/grow. That way they can be optimized accordingly. try_grow_inplace does a simpler size check for "success" and shrink_in_place omits a checked_mul, assuming they indeed passed in a smaller value than old_len. (I'm shaky on what *exactly* should be checked in both, though).