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).
> Panic is supposed to be for logic errors and using it for a runtime error like out-of-memory would be misuse.

It's not clear to me whether asking for 2^100 bytes of memory is a logic or runtime error.

> I don't see why the API should be complicated by splitting out this error condition from out-of-memory but not all others.

It's the current semantics all of our collections have though. If you ask for more capacity than a uint can handle, they panic with "capacity overflow". ::oom'ing would change from the current behaviour.

> The right solution is bubbling up the out-of-memory errors. Panics are not an acceptable solution to runtime errors. I think it's unacceptable to force people to use unwinding to have a not-even-half-working way of handling OOM.

Can you elaborate on the design you imagine? I believe we discussed this on IRC before, and I don't recall any concrete ideas. Bubbling the errors via Results on every-operation-that-can-allocate would almost *certainly* have a performance impact, so I'm assuming you have a more robust solution in mind?

> It's going to be a step backwards for performance and is not going to be as clean as simply using Vec<T> inside of the ring buffer implementation. I don't see the need for this extra complexity / code bloat to factor out a couple calls to the lower level API. It's not an improvement over reusing Vec<T>.

I'm not convinced of this at all. Using Vec would be fairly awkward from what I picture the implementation being, would add extra useless fields to the RingBuf (Vec::len wouldn't be used), and would likely involve duplicate logic. As for performance compared to the current impl, the only extra work I do now that the current RingBuf doesn't is check for len == 0, which I'm strongly considering removing in favour of just declaring it UB.

Regardless, I'll prototype out a couple different impls/benches to compare perf/design.