-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reduce unsafe code in get_or #63
Conversation
get_or() currently works as a wrapper around get_or_try(). It wraps the result of the passed function into a Result<T, ()> and then calls unreachable_unchecked, which is an unsafe function. However, as an Err branch is never instantiated for this Result type, we can use the uninhabited Infallible type instead of the unit type. At this point it is 100% safe to unwrap the underlying result and match on the uninhabited error type to eliminate that branch. It turns out this was the only time that the "unreachable" module was used in the library, so I've also taken the liberty of deleting that file. Signed-off-by: John Nunley <dev@notgull.net>
@@ -187,9 +186,9 @@ impl<T: Send> ThreadLocal<T> { | |||
where | |||
F: FnOnce() -> T, | |||
{ | |||
unsafe { | |||
self.get_or_try(|| Ok::<T, ()>(create())) | |||
.unchecked_unwrap_ok() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can even eliminate the Err
line entirely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get "missing match arm" on the current compiler version. I think you need exhaustive_patterns
to land first before that works.
Test failure is not my fault; |
Just bump the MSRV in CI to 1.63 so the tests pass. |
Signed-off-by: John Nunley <dev@notgull.net>
Done. |
Ah, |
Does bumping the CI version to 1.65 not fix this? |
It doesn't. I'm going to drop this PR for now as its usefulness is limited |
get_or() currently works as a wrapper around get_or_try(). It wraps the result of the passed function into a Result<T, ()> and then calls unreachable_unchecked, which is an unsafe function. However, as an Err branch is never instantiated for this Result type, we can use the uninhabited Infallible type instead of the unit type. At this point it is 100% safe to unwrap the underlying result and match on the uninhabited error type to eliminate that branch.
It turns out this was the only time that the "unreachable" module was used in the library, so I've also taken the liberty of deleting that file.