Open Rahix opened 3 years ago
Breaking the silence on this topic after a couple years, I'll add some takes.
Poking around a little bit, if you set any opt-level
at all, any of these alternatives will just compile away for Infallible / !
errors. So that's at least one aspect we don't need to care about. https://rust.godbolt.org/z/vor63P3j4
But I found the into_ok
docs made a better argument than readability alone:
Unlike
unwrap
, this method is known to never panic on the result types it is implemented for. Therefore, it can be used instead ofunwrap
as a maintainability safeguard that will fail to compile if the error type of theResult
is later changed to an error that can actually occur.
And with that said! I stumbled upon unwrap-infallible
:tada:.
With nearly identical docs and arguments about maintainability.
TL;DR I get to the following table:
Method | Familiar terms | Method readability | Maintenance safeguard | Method in core | Error in core |
---|---|---|---|---|---|
.into_ok() |
Yes | After adoption | Yes | Nightly | Nightly |
.unwrap() |
Yes | No1 | No | 1.34.0 | Yes |
.unwrap_unchecked() |
Yes | No1 | No | 1.58.0 | Yes |
.void_unwrap() |
No2 | With IDE | Yes | No | No |
.unwrap_infallible() |
Yes | Yes | Yes | No | Yes |
No1 = It's not obvious from .unwrap()
and friends that this is infallible.
No2 = Personal opinion. I think void
is an overloaded term and doesn't make it obviously infallible to me.
So my opinion is that:
Result<_, Infallible>
is better than Result<_, Void>
and confirmed in v1: https://github.com/rust-embedded/embedded-hal/pull/150.embedded-hal
is primarily for other maintainers. And it may be a motivation to use a "stopgap" crate before .into_ok()
lands in stable.unwrap_infallible
and is_ok
are better method names than void_unwrap
.However I cannot propose what the tradeoff should be here. If we're going to push hard on .into_ok()
adoption, this will impact the MSRV at that time. unwrap-infallible
seems well positioned to add deprecation warnings when .into_ok()
is available.
Possibly even with feature flags and adding UnwrapInfallible::is_ok
as a PR there, it could be a drop-in replacement simply by making the use unwrap_infallible::UnwrapInfallible;
and crate dependency conditional.
Currently I don't see any v1
code that actually unwraps an infallible result though! If that remains the case, it might actually be up to other maintainers whether they want to use unwrap-infallible
or not?
(From #328)
Back in the days, before
core::convert::Infallible
was added, we hadvoid::Void
to markResult
s which cannot ever produce the error variant. With it came thevoid::ResultExt
extension trait that adds a.void_unwrap()
method toResult<T, Void>
, to unwrap such an infallible result. There were nice advantages to that over just using normalunwrap()
on such results:Result
is getting unwrapped.void_unwrap()
would immediately stop to compile, forcing one to revisit the code. When just usingunwrap()
, this would silently become a panic site on dependency upgrade.Now, the
void
crate is largely unmaintained and ascore::convert::Infallible
is becoming the core-language equivalent, I'd like to see a similar feature available. There is an unstableResult<T, !>::into_ok()
method but that doesn't help much for stable users. To note, it is trivial to reimplement but I feel like this needs to be done somewhere "official" and embraced throughout the ecosystem.What I care about most here is how we can teach proper coding habits: By experience, people copy from crate and documentation examples so if these use
unwrap()
, downstream code will as well. In turn, this will make it hard for upstream crates to eventually introduce concrete error types because of the risk of silently breaking downstream code. If there is a commonly accepted version of "infallible_unwrap()
" (please bikeshed a better name) which is used throughout examples, downstream users will naturally move to using it as well.I see a few possible solutions to here:
embedded-hal
. While not technically a fitting place,embedded-hal
(and itsprelude
!) is pulled in by lots of projects already, so having it available there would reach the most people.into_ok()
method such that we can just promote use of that.