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).
> One is "you asked for more memory than can possibly be allocated by this model of computation", and the other is "the allocator can't make your object (even if you only asked for a single byte)". While in practice the latter is probably just the former (you still have tons of memory, you just asked for something too big), that's not necessarily the case.

That's not true. Rust expects the allocator to bound the maximum allocation size at `int::MAX` and sizes above that will be considered an out-of-memory error.