Suggestion (Pre-RFC?): Implement Default for Result

I'd like to propose for the Result<T, E> struct, one of the most used container types in Rust to implement the Default trait in either this form:

impl<E> Default for Result<(), E> {
  fn default() -> Self { Ok(()) }

I'm sure that for most, if not all, use cases of Result<(), Something>, the unit value does represent the default, non-erroneous case and is in line with the semantics of the type.


The trait could also be implemented generic over T:

impl<T: Default, E> Default for Result<T, E> {
  fn default() -> Self { Ok(<T as Default>::default()) }

However, the semantics of this are in my opinion much more debatable than the first case.


Because both the Default and Result are defined in the std crate, users can't implement this themselves, therefore I don't think this change could break any compilation.

Do you think this is a good idea? If yes, how should I proceed with this? Is it enough for making a formal RFC or is a pull request enough?

1 Like

A potential problem/confusion point is that Optionʼs default is None, so people might expect an “error” value as the Default for Result as well.

Also Iʼd be curious about in what settings having the default implementation for Result<(), E> in particular is actually useful and in which way. AFAIK, default implementations are particularly useful for saving lots of typing long expressions if the type implementing Default is a larger struct with lots of fields; for helping with deriving default if the type is often used as a field or generic parameter in the type of a field of a struct; for allowing mem::take; and for marking some conceptually clear default variant of e. g. a configuration enum or struct or similar things, for structs also for using the builder pattern.

I don't use Rust in practice myself though, so I'm probably missing use cases. Anyway, of the cases above that I could think of, not much applies to Result. Unless Result<(), E> often appears in the type of your struct fields, I'm really not sure of the use case, but you'll probably have one, otherwise you wouldn't suggest the implementation in the first case, right?