-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
Add std::mem::defer for conveniently build DropGuard<(), FnOnce(())>
#150027
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
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: tison <[email protected]>
library/core/src/mem/drop_guard.rs
Outdated
| /// { | ||
| /// // Create a new guard that will do something | ||
| /// // when dropped. | ||
| /// let _guard = DropGuard::new(|()| println!("Goodbye, world!")); |
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.
| /// let _guard = DropGuard::new(|()| println!("Goodbye, world!")); | |
| /// let _guard = DropGuard::new(|| println!("Goodbye, world!")); |
It's more proper to write || without (). But it seems quite hard to fine-tune the type parameter F: FnOnce(T) even if we are sure that T = (). impl FnOnce(()) is different from impl FnOnce().
|
I think the proposed API would be nice to have if it got rid of the unit argument, but as it is it feels like a half-measure. I don't know if it would be popular, but maybe we could provide a macro_rules! defer {
($($t:tt)*) => {
let _guard = DropGuard::new((), |()| { $($t)* });
};
}This works too: const fn defer<F: FnOnce()>(f: F) -> DropGuard<(), impl FnOnce(())> {
DropGuard {
inner: ManuallyDrop::new(()),
f: ManuallyDrop::new(move |()| f()),
}
} |
This looks like a good solution. Let me try it out. So far we export |
Signed-off-by: tison <[email protected]>
|
Updated with: Maybe we should keep |
|
I think we should keep The macro is not perfect, e.g. I don't think you can have both |
Signed-off-by: tison <[email protected]>
Signed-off-by: tison <[email protected]>
|
@nxsaken Great suggestion! Updated. |
| /// ``` | ||
| #[unstable(feature = "drop_guard", issue = "144426")] | ||
| pub macro defer($($t:tt)*) { | ||
| $crate::mem::DropGuard::new((), |()| { $($t)* }) |
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.
Not sure if |()| { ... } can proper move value when needed.
Added defer_moved_value test case and it seems to work properly.
std::mem::defer for conveniently build DropGuard<(), FnOnce(())>
|
r? libs-api |
Signed-off-by: tison <[email protected]>
|
I'd lean toward keeping If we go with a macro, one advantage of a macro is that it can wrap the entire |
|
I think the macro makes a lot of sense, if it includes the Any usage pattern where the lifetime of the guards ends early in some branch via |
|
5 out of 10 in my use cases need to store the |
This refers to #144426.
cc @andylokandy @jplatte
Updated with:
Unfortunately, it's hard to convert
impl FnOnce()to the input type paramF: FnOnce(T) where T = ().I tried:
But it failed because the new closure has a different type of
F.