The point is with FnOnce() -> T : Into<T> you could have unwrap_or(impl Into<T>), such that you could both write unwrap_or(42) as well as unwrap_or(|| default()). There would need be no distinction between unwrap_or and unwrap_or_else; both would use the same codepath.
However, due to the confusion potential of Fn() -> Self, I do think the split is useful. I can't write the impl for a custom struct Else(impl Fn() -> T), so I don't see how std gets to actually sidestep the underlying issue (rather than just work around it).
(Now, a type-lookup .unwrap_or!($expr), on the other hand... (off-topic do not discuss))
Nothing. I was responding to a question regarding what benefit this change would provide: it cleans up some API surface area. Whether or not it cleans it up enough to be worth the implementation (especially if it's not straightforward) is also worth discussing; it sounds like it's not just "adding an impl". I'm not sure if it's helpful to dismiss the change out of hand.
Clippy even has some helpful lints to point you to the correct unwrap_or_X, and lints against the first example. But assuming most of the difficulties could be ironed out, under the proposed change you could write
op.unwrap_or(42)
op.unwrap_or(default) // ← same number of chars as op.unwrap_or_default()
op.unwrap_or(|| something_more_complicated(x, y, 42))
which might be nice? Not particularly earth shattering, but nice.
I suspect such a change would be difficult for type inference -- e.g. unwrap_or(42) would probably have to fall back to i32, if it's not an outright {integer} inference failure, but of course that won't work for Option<usize>.
Returning a Result, which is the idiomatic way to do error handling if something fails. Abviously the only interface difference between Into and TryInto is that the conversion method of the latter returns a Result. TryFrom docs says that:
The From trait is intended for perfect conversions, so the TryFrom trait informs the programmer when a type conversion could go bad and lets them decide how to handle it.
The only way TryInto or TryFrom could inform the programmer that something did go bad would be returning Err, so I don't see how "failing" includes panicking in this context.
Then why do this even compile? If Into implementations must not panic, maybe we should mark the Into as an unsafe trait.
panic'ing in an Into::into implementation would merely be a sign of bug, just like how panicking in a checked vector indexing would be. @xfix pointed out that:
And I wanted to point out that IMHO this doesn't really changes anything because Into::into can already panic. You can't assume that Into::into will not panic in an unsafe context, can you?
Since From/Into does not return a Result, there's no other realistic way in which it could "fail", except for panicking.
Yes, Rust doesn't have an effect system, and the type checker allows you to panic as much as you would like. Still, just because From::from() can technically panic, doing so remains to be regarded as unidiomatic, and people won't expect it.
No, because panicking is not inherently unsafe. If it were, we would need to mark literally every function as unsafe.
Note that there's impl<T: Ord> From<Vec<T, Global>> for BinaryHeap<T> in std, so you probably need to add the same requirement to never panic to Ord and/or PartialOrd (which probably means "no math allowed here because it could overflow"). And also Clone and ToOwned for a number of cloning implementations. And the program, obviously, can still have an allocation failure, which will probably become a potential panic under RFC 2116.