Lifting binary operations, e.g. T+T → Option<T> + Option<T>

That doesn't "capture" the errors, though, so only works if you want to use it in a method that returns an option where you want to return None if either is None.

Consider, for example, Chain::size_hint. The method doesn't return Option, so it can't use ? without a catch block, but still wants to combine the two Option<usize> upper-bound hints. The actual working on stable solution is (||{ Some(x? + y?) })(), but I loathe that syntax. (Assuming inference cooperates, since it doesn't always with ?-in-closures. And Chain needs checked_add to deal with overflow, but that's not important to the lifting discussion.)

Assuming a Lift like above, the problem is that, for example, Lift(u32::max) does something different from Option<u32>::max. (Both maxs in this case being instances of Ord::max.)

a b Option::max(a, b) Lift(Ord::max)(a, b)
None None None None
Some None Some None
None Some Some None
Some Some Some Some

And min doesn't have this difference, so the solutions to nearly-identical problems turn out to be very different depending whether you're looking for min or max, which can be quite confusing.

If Option were only PartialOrd instead, None could be neither before nor after the Somes, which is less arcane than the current totally-arbitrary choice. (And Option wouldn't get a min from Ord, so we could choose how to define it, or even just to not define it at all. All arguments here are also true with cmp::min/max; that's just less clean to write in the tables.)

I don't want to have to write ¿{} and Some(). One or the other is fine. I've elaborated on that in `catch` blocks are not `Ok`-wrapping their value · Issue #41414 · rust-lang/rust · GitHub