I have another generics based idea for solving the problem. We change all methods that can fail due to oom to have a generic parameter of an AllocFailure trait, which is defaulted to give the current experience:
#![feature(default_type_parameter_fallback, associated_type_defaults)]
trait OomFailure<ReturnTy> {
type ResultType = ReturnTy;
}
struct AbortOnOom;
impl<T> OomFailure<T> for AbortOnOom {}
struct OomResult;
struct OomError;
impl<T> OomFailure<T> for OomResult {
type ResultType = Result<T, OomError>;
}
struct Vec<T>(T);
impl<T> Vec<T> {
fn push<AF: OomFailure<()> = AbortOnOom>(&mut self, t: T) -> AF::ResultType {
unimplemented!()
}
}
fn foo<T>(v: Vec<T>, u: T, w: T) {
v.push(u); // doesn't work yet due to https://github.com/rust-lang/rust/issues/36887#issuecomment-296787518 being unresolved
v.push::<AbortOnOom>(u); // the above line should work just like this one
v.push::<OomResult>(w); // warning: unused `std::result::Result` which must be used
}