rust: sync: add #[must_use] to Lock::try_lock
Subsystems (3)
PATCH 1/1 rust: sync: add #[must_use] to Lock::try_lock
The Lock::try_lock function returns an Option<Guard<...>>, but it currently does not issue a warning if the return value is unused. This could result in the lock being unlocked immediately, which is unsafe and unintended. This patch adds a #[must_use] annotation to Lock::try_lock to prevent this.
--- rust/kernel/sync/lock.rs | 1 + 1 file changed, 1 insertion(+)
rust/kernel/sync/lock.rs +1 -0
@@ -147,6 +147,7 @@ pub fn lock(&self) -> Guard<'_, T, B> {/// Tries to acquire the lock. /// /// Returns a guard that can be used to access the data protected by the lock if successful. +#[must_use = "if unused, the lock will be immediately unlocked" ] pub fn try_lock (&self) ->Option <Guard <'_,T ,B >> {// SAFETY: The constructor of the type calls `init`, so the existence of the object proves // that `init` was called.
Signature · 1 line
2.44.2
Hi Jason,
Thanks for the patch.
Quoted 3 lines · Jason Devers
The
Lock::try_lockfunction returns anOption<Guard<...>>, but it currently does not issue a warning if the return value is unused. This could result in the lock being unlocked immediately, which is unsafe
I don't think not having #[must_use] will result in the locking being unlocked immediately, do you have an example?
Quoted 1 line
and unintended. This patch adds a
#[must_use]annotation to
Are you sure this is unsafe? Again do you have an example showing this?
Regards,
Boqun
Quoted 24 lines
Lock::try_lockto prevent this.Suggested-by Alice Ryhl <[email protected]>Signed-off-by Jason Devers <[email protected]>--- rust/kernel/sync/lock.rs | 1 + 1 file changed, 1 insertion(+)rust/kernel/sync/lock.rs +1
-0@@ -147,6 +147,7 @@ pub fn lock(&self) -> Guard<'_, T, B> {/// Tries to acquire the lock. /// /// Returns a guard that can be used to access the data protected by the lock if successful. +#[must_use = "if unused, the lock will be immediately unlocked" ] pub fn try_lock (&self) ->Option <Guard <'_,T ,B >> {// SAFETY: The constructor of the type calls `init`, so the existence of the object proves // that `init` was called. Signature · 1 line
2.44.2
A message that is not in the archive (sent off-list or not yet received): CAOJvc-bi6ym6ZMAbDSh4H_L6LQXoTs8oNY07SZ1crzXxY9BodQ@mail.gmail.com
Hi Boqun,
Thank you for the feedback, I am new to kernel development and appreciate the response.
To answer your question(s):
Quoted 2 lines
I don't think not having
#[must_use]will result in the locking being unlocked immediately, do you have an example?
You're correct that the absence of #[must_use] itself does not directly result in the lock being unlocked immediately, my mistake.
How I understand the issue arises when the result of Lock::try_lock is called and its return value can be ignored, the lock is never acquired, and no guard is created. Making the caller assume the lock was successfully acquired and proceeding with operations as if the data is safely protected, e.g. calling lock.try_lock() and proceeding with critical section code.
The use of the #[must_use] macro annotation will ensure the caller cannot silently ignore its return value.
I believe the annotation can be revised to:#[must_use = "if unused, return value may be unhandled, leading to potential race conditions"] ?
But would love to hear your thoughts and suggestions!
Best,
Jason
Quoted 67 lines · jos
Hi Boqun,
Thank you for the feedback, I am new to kernel development and appreciate the response.
To answer your question(s):
Quoted 2 lines
I don't think not having
#[must_use]will result in the locking being unlocked immediately, do you have an example?You're correct that the absence of
#[must_use]itself does not directly result in the lock being unlocked immediately, my mistake.How I understand the issue arises when the result of
Lock::try_lockis called and its return value can be ignored, the lock is never acquired, and no guard is created. Making the caller assume the lock was successfully acquired and proceeding with operations as if the data is safely protected, e.g. callinglock.try_lock()and proceeding with critical section code.The use of the
#[must_use]macro annotation will ensure the caller cannot silently ignore its return value. I believe the annotation can be revised to:#[must_use = "if unused, return value may be unhandled, leading to potential race conditions"]?But would love to hear your thoughts?
Best,
JasonQuoted 44 lines · Boqun Feng
Hi Jason,
Thanks for the patch.
Quoted 3 lines · Jason Devers
The
Lock::try_lockfunction returns anOption<Guard<...>>, but it currently does not issue a warning if the return value is unused. This could result in the lock being unlocked immediately, which is unsafeI don't think not having
#[must_use]will result in the locking being unlocked immediately, do you have an example?Quoted 1 line
and unintended. This patch adds a
#[must_use]annotation toAre you sure this is unsafe? Again do you have an example showing this?
Regards,
BoqunQuoted 24 lines
Lock::try_lockto prevent this.Suggested-by Alice Ryhl <[email protected]>Signed-off-by Jason Devers <[email protected]>--- rust/kernel/sync/lock.rs | 1 + 1 file changed, 1 insertion(+)rust/kernel/sync/lock.rs +1
-1@@ -147,6 +147,7 @@ pub fn lock(&self) -> Guard<'_, T, B> {/// Tries to acquire the lock. /// /// Returns a guard that can be used to access the data protected by the lock if successful. +#[must_use = "if unused, the lock will be immediately unlocked" ] pub fn try_lock (&self) ->Option <Guard <'_,T ,B >> {// SAFETY: The constructor of the type calls `init`, so the existence of the object proves // that `init` was called. --2.44.2
Quoted 10 lines · jos
Hi Boqun,
Thank you for the feedback, I am new to kernel development and appreciate the response.
To answer your question(s):
Quoted 2 lines
I don't think not having
#[must_use]will result in the locking being unlocked immediately, do you have an example?
Quoted 9 lines
You're correct that the absence of
#[must_use]itself does not directly result in the lock being unlocked immediately, my mistake.How I understand the issue arises when the result of
Lock::try_lockis called and its return value can be ignored, the lock is never acquired, and no guard is created. Making the caller assume the lock was successfully acquired and proceeding with operations as if the data is safely protected, e.g. callinglock.try_lock()and proceeding with critical section code.
Well, in most cases, locking is data-oriented, i.e. you have to have the Guard to access locked data, so the "issue" you mention could not happen. Besides, it's relatively easy to "get around" #[must_use] by doing:
let _ = l.try_lock()?;
Overall, #[must_use] here should be the tool to avoid some code that obviously doesn't make sense (like acquring and releasing lock without any code in between), rather than silver bullets for a serious safety issue. So I think you should reword the commit log to reflect this.
Quoted 6 lines
The use of the
#[must_use]macro annotation will ensure the caller cannot silently ignore its return value. I believe the annotation can be revised to:#[must_use = "if unused, return value may be unhandled, leading to potential race conditions"]?
I would just say "if unused, leading to an empty critical section", i.e. it's bad but not a correct-or-wrong issue. Does this make sense?
Regards,
Boqun
Quoted 53 lines
But would love to hear your thoughts?
Best,
JasonQuoted 46 lines · Boqun Feng
Hi Jason,
Thanks for the patch.
Quoted 3 lines · Jason Devers
The
Lock::try_lockfunction returns anOption<Guard<...>>, but it currently does not issue a warning if the return value is unused. This could result in the lock being unlocked immediately, which is unsafeI don't think not having
#[must_use]will result in the locking being unlocked immediately, do you have an example?Quoted 1 line
and unintended. This patch adds a
#[must_use]annotation toAre you sure this is unsafe? Again do you have an example showing this?
Regards,
BoqunQuoted 14 lines
Lock::try_lockto prevent this.Suggested-by Alice Ryhl <[email protected]>Signed-off-by Jason Devers <[email protected]>--- rust/kernel/sync/lock.rs | 1 + 1 file changed, 1 insertion(+)rust/kernel/sync/lock.rs +0
-0rust/kernel/sync/lock.rs pub fn lock(&self) -> Guard<'_, T, B> { · line 149
Quoted 3 lines
rust/kernel/sync/lock.rs +0
-0@@ -147,6 +147,7 @@ pub fn lock(&self) -> Guard<'_, T, B> {/// Tries to acquire the lock. /// /// Returns a guard that can be used to access the data protected by the lock if successful.
rust/kernel/sync/lock.rs pub fn lock(&self) -> Guard<'_, T, B> {
Quoted 3 lines
rust/kernel/sync/lock.rs +1
-0+#[must_use = "if unused, the lock will be immediately unlocked" ] pub fn try_lock (&self) ->Option <Guard <'_,T ,B >> {// SAFETY: The constructor of the type calls `init`, so the existence of the object proves
Quoted 4 lines
rust/kernel/sync/lock.rs +0
-1// that `init` was called. --2.44.2
PATCH 1/1 rust: sync: add #[must_use] to Lock::try_lock
The Lock::try_lock function returns an Option<Guard<...>>, but it currently does not issue a warning if the return value is unused.
To avoid potential bugs, the #[must_use] annotation is added to ensure proper usage.
--- rust/kernel/sync/lock.rs | 1 + 1 file changed, 1 insertion(+)
rust/kernel/sync/lock.rs +1 -0
@@ -147,6 +147,7 @@ pub fn lock(&self) -> Guard<'_, T, B> {/// Tries to acquire the lock. /// /// Returns a guard that can be used to access the data protected by the lock if successful. +#[must_use = "if unused, leading to an empty critical section" ] pub fn try_lock (&self) ->Option <Guard <'_,T ,B >> {// SAFETY: The constructor of the type calls `init`, so the existence of the object proves // that `init` was called.
Signature · 1 line
2.44.2
Quoted 4 lines · Jason Devers
The
Lock::try_lockfunction returns anOption<Guard<...>>, but it currently does not issue a warning if the return value is unused.
To avoid potential bugs, the#[must_use]annotation is added to ensure proper usage.
It'd be great to mention in this message (and perhaps in the code) that the reason this annotation is necessary is that Option<T> is not #[must_use] regardless of T being #[must_use]. It might also be handy to leave a breadcrumb pointing to
https://github.com/rust-lang/rust/issues/71368.
Quoted 2 lines
I may be misunderstanding what you are trying to say, but the guard is created, and the lock is acquired.
Apologizes, I had a misunderstanding of the macro that was being used. Thank you Boqun and Miguel for providing clarity, much appreciated!
Quoted 5 lines
It'd be great to mention in this message (and perhaps in the code) that the reason this annotation is necessary is that
Option<T>is not#[must_use]regardless ofTbeing#[must_use]. It might also be handy to leave a breadcrumb pointing to
https://github.com/rust-lang/rust/issues/71368.
Sure I can do that, thank you for the suggestion!
Thanks,
Jason
Quoted 12 lines · Tamir Duberstein
Quoted 4 lines · Jason Devers
The
Lock::try_lockfunction returns anOption<Guard<...>>, but it currently does not issue a warning if the return value is unused.
To avoid potential bugs, the#[must_use]annotation is added to ensure proper usage.It'd be great to mention in this message (and perhaps in the code) that the reason this annotation is necessary is that
Option<T>is not#[must_use]regardless ofTbeing#[must_use]. It might also be handy to leave a breadcrumb pointing to
https://github.com/rust-lang/rust/issues/71368.
PATCH 1/1 rust: sync: add #[must_use] to Lock::try_lock
The Lock::try_lock function returns an Option<Guard<...>>, but it currently does not issue a warning if the return value is unused.
To avoid potential bugs, the #[must_use] annotation is added to ensure proper usage.
Note that T is #[must_use] but Option<T> is not.
For more context, see: https://github.com/rust-lang/rust/issues/71368.
--- rust/kernel/sync/lock.rs | 1 + 1 file changed, 1 insertion(+)
rust/kernel/sync/lock.rs +1 -0
@@ -147,6 +147,7 @@ pub fn lock(&self) -> Guard<'_, T, B> {/// Tries to acquire the lock. /// /// Returns a guard that can be used to access the data protected by the lock if successful. +#[must_use = "if unused, leading to an empty critical section" ] pub fn try_lock (&self) ->Option <Guard <'_,T ,B >> {// SAFETY: The constructor of the type calls `init`, so the existence of the object proves // that `init` was called.
Signature · 1 line
2.44.2
Quoted 11 lines · Jason Devers
The
Lock::try_lockfunction returns anOption<Guard<...>>, but it currently does not issue a warning if the return value is unused.
To avoid potential bugs, the#[must_use]annotation is added to ensure proper usage.Note that
Tis#[must_use]butOption<T>is not.
For more context, see: https://github.com/rust-lang/rust/issues/71368.Suggested-by Alice Ryhl <[email protected]>Signed-off-by Jason Devers <[email protected]>
Please use the version option of format-patch, e.g. -v4, when you send new versions, so that they are tagged as such. Otherwise, all the patches look like they are the first version, which is confusing for tooling (and people :)
Also, in general, it is best to wait a day or two to give people a chance to review your patches, so that you do not need to accumulate too many versions.
Quoted 1 line
+ #[must_use = "if unused, leading to an empty critical section"]
I am not a native speaker, but this sounds a bit strange. Is it written like this due to how it gets "rendered" by the compiler later on?
Thanks!
Cheers,
Miguel
Quoted 1 line
I use [email protected] for kernel contributions.
Sorry about this, I will update with the correct email!
Quoted 8 lines
Please use the version option of
format-patch, e.g.-v4, when you send new versions, so that they are tagged as such. Otherwise, all the patches look like they are the first version, which is confusing for tooling (and people :)Also, in general, it is best to wait a day or two to give people a chance to review your patches, so that you do not need to accumulate too many versions.
Will do! I really appreciate the patience and feedback, please continue doing so :)
Quoted 5 lines
+ #[must_use = "if unused, leading to an empty critical section"]
I am not a native speaker, but this sounds a bit strange. Is it written like this due to how it gets "rendered" by the compiler later on?
I agree this sounds a bit strange, perhaps it would sound more proper to say:
#[must_use = "if unused, leads to an empty critical section"]
Will give it some time to receive more thoughts before sending an updated version.
Thanks,
Jason
Quoted 33 lines · Miguel Ojeda
Quoted 11 lines · Jason Devers
The
Lock::try_lockfunction returns anOption<Guard<...>>, but it currently does not issue a warning if the return value is unused.
To avoid potential bugs, the#[must_use]annotation is added to ensure proper usage.Note that
Tis#[must_use]butOption<T>is not.
For more context, see: https://github.com/rust-lang/rust/issues/71368.Suggested-by Alice Ryhl <[email protected]>Signed-off-by Jason Devers <[email protected]>Please use the version option of
format-patch, e.g.-v4, when you send new versions, so that they are tagged as such. Otherwise, all the patches look like they are the first version, which is confusing for tooling (and people :)Also, in general, it is best to wait a day or two to give people a chance to review your patches, so that you do not need to accumulate too many versions.
Quoted 1 line
+ #[must_use = "if unused, leading to an empty critical section"]
I am not a native speaker, but this sounds a bit strange. Is it written like this due to how it gets "rendered" by the compiler later on?
Thanks!
Cheers,
Miguel
PATCH v4 1/1 rust: sync: add #[must_use] to Lock::try_lock
In reply to josThe Lock::try_lock function returns an Option<Guard<...>>, but it currently does not issue a warning if the return value is unused.
To avoid potential bugs, the #[must_use] annotation is added to ensure proper usage.
Note that T is #[must_use] but Option<T> is not.
For more context, see: https://github.com/rust-lang/rust/issues/71368.
--- rust/kernel/sync/lock.rs | 2 ++ 1 file changed, 2 insertions(+)
rust/kernel/sync/lock.rs +2 -0
@@ -147,6 +147,8 @@ pub fn lock(&self) -> Guard<'_, T, B> {/// Tries to acquire the lock. /// /// Returns a guard that can be used to access the data protected by the lock if successful. +/// Note that `T` is `#[must_use]` but `Option<T>` is not. +#[must_use = "if unused, leads to an empty critical section" ] pub fn try_lock (&self) ->Option <Guard <'_,T ,B >> {// SAFETY: The constructor of the type calls `init`, so the existence of the object proves // that `init` was called.
Signature · 1 line
2.44.2
Alice Ryhl
maintainerQuoted 20 lines · Jason Devers
The
Lock::try_lockfunction returns anOption<Guard<...>>, but it currently does not issue a warning if the return value is unused.
To avoid potential bugs, the#[must_use]annotation is added to ensure proper usage.Note that
Tis#[must_use]butOption<T>is not.
For more context, see: https://github.com/rust-lang/rust/issues/71368.Suggested-by Alice Ryhl <[email protected]>Signed-off-by Jason Devers <[email protected]>--- rust/kernel/sync/lock.rs | 2 ++ 1 file changed, 2 insertions(+)rust/kernel/sync/lock.rs +0
-0
rust/kernel/sync/lock.rs pub fn lock(&self) -> Guard<'_, T, B> { · line 151
Quoted 5 lines
rust/kernel/sync/lock.rs +2
-0@@ -147,6 +147,8 @@ pub fn lock(&self) -> Guard<'_, T, B> {/// Tries to acquire the lock. /// /// Returns a guard that can be used to access the data protected by the lock if successful. +/// Note that `T` is `#[must_use]` but `Option<T>` is not. +#[must_use = "if unused, leads to an empty critical section" ]
Can't we use the same warning message as Guard?
#[must_use = "the lock unlocks immediately when the guard is unused"]
Alice
Quoted 2 lines · Jason Devers
+ /// Note that
Tis#[must_use]butOption<T>is not.
Should this be a comment, i.e. //, rather than part of the documentation?
I would also reword to explain the "what", not just "why", e.g. something like:
// `Option<T>` is not `#[must_use]` even if `T` is, thus the
attribute is needed here.
Cheers,
Miguel
Quoted 3 lines
Can't we use the same warning message as Guard?
#[must_use = "the lock unlocks immediately when the guard is unused"]
That is what I originally had in my first patch and how I understood the annotation should be phrased, but @Boqun Feng maybe you can chime in with your input?
Quoted 3 lines
Quoted 1 line
+ /// Note that
Tis#[must_use]butOption<T>is not.Should this be a comment, i.e.
//, rather than part of the documentation?
Agreed, after reading more documentation conventions
(https://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md),
this should not be part of the rustdocs.
Quoted 4 lines
I would also reword to explain the "what", not just "why", e.g. something like:
// `Option<T>` is not `#[must_use]` even if `T` is, thus theattribute is needed here.
Thank you for the insight, I can see how there is missing clarity in the current comment, will update in the next patch.
Thanks,
Jason
Quoted 14 lines · Miguel Ojeda
Quoted 2 lines · Jason Devers
+ /// Note that
Tis#[must_use]butOption<T>is not.Should this be a comment, i.e.
//, rather than part of the documentation?I would also reword to explain the "what", not just "why", e.g. something like:
// `Option<T>` is not `#[must_use]` even if `T` is, thus theattribute is needed here.
Cheers,
Miguel
Quoted 8 lines · jos
Quoted 3 lines
Can't we use the same warning message as Guard?
#[must_use = "the lock unlocks immediately when the guard is unused"]
That is what I originally had in my first patch and how I understood the annotation should be phrased, but @Boqun Feng maybe you can chime in with your input?
Hmm... I think it was a mis-communication. In the v1, you said "..but it currently does not issue a warning if the return value is unused. This could result in the lock being unlocked immediately.." I thought "This" means "not having #[must_use]", but you probably meant "not using the value"? My comment is more to that commit log instead of the warning message in the #[must_use = ...] block.
Anyway, I think the warning message in your v1 works for me. Again, to be clear, my concern was on the commit log then. Hope it clarifies things.
Regards,
Boqun
Quoted 36 lines
Quoted 3 lines
Quoted 1 line
+ /// Note that
Tis#[must_use]butOption<T>is not.Should this be a comment, i.e.
//, rather than part of the documentation?Agreed, after reading more documentation conventions
(https://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md),
this should not be part of the rustdocs.Quoted 4 lines
I would also reword to explain the "what", not just "why", e.g. something like:
// `Option<T>` is not `#[must_use]` even if `T` is, thus theattribute is needed here.
Thank you for the insight, I can see how there is missing clarity in the current comment, will update in the next patch.
Thanks,
JasonQuoted 14 lines · Miguel Ojeda
Quoted 2 lines · Jason Devers
+ /// Note that
Tis#[must_use]butOption<T>is not.Should this be a comment, i.e.
//, rather than part of the documentation?I would also reword to explain the "what", not just "why", e.g. something like:
// `Option<T>` is not `#[must_use]` even if `T` is, thus theattribute is needed here.
Cheers,
Miguel
PATCH v5 1/1 rust: sync: add #[must_use] to Lock::try_lock
In reply to josThe Lock::try_lock function returns an Option<Guard<...>>, but it currently does not issue a warning if the return value is unused.
To avoid potential bugs, the #[must_use] annotation is added to ensure proper usage.
Note that T is #[must_use] but Option<T> is not.
For more context, see: https://github.com/rust-lang/rust/issues/71368.
--- rust/kernel/sync/lock.rs | 2 ++ 1 file changed, 2 insertions(+)
rust/kernel/sync/lock.rs +2 -0
@@ -147,6 +147,8 @@ pub fn lock(&self) -> Guard<'_, T, B> {/// Tries to acquire the lock. /// /// Returns a guard that can be used to access the data protected by the lock if successful. +// Note that `T` is `#[must_use]` but `Option<T>` is not. +#[must_use = "if unused, the lock will be immediately unlocked" ] pub fn try_lock (&self) ->Option <Guard <'_,T ,B >> {// SAFETY: The constructor of the type calls `init`, so the existence of the object proves // that `init` was called.
Signature · 1 line
2.44.2
Quoted 2 lines · Jason Devers
+ // Note that
Tis#[must_use]butOption<T>is not.
I think the wording of the comment was not updated? If there is a reason for not doing it, then you should normally put it in the changelog (i.e. after the first --- line) or you would reply to the original feedback with the reason.
Thanks!
Cheers,
Miguel
PATCH v6 1/1 rust: sync: add #[must_use] to Lock::try_lock
In reply to josThe Lock::try_lock function returns an Option<Guard<...>>, but it currently does not issue a warning if the return value is unused.
To avoid potential bugs, the #[must_use] annotation is added to ensure proper usage.
Note that T is #[must_use] but Option<T> is not.
For more context, see: https://github.com/rust-lang/rust/issues/71368.
--- rust/kernel/sync/lock.rs | 2 ++ 1 file changed, 2 insertions(+)
rust/kernel/sync/lock.rs +2 -0
@@ -147,6 +147,8 @@ pub fn lock(&self) -> Guard<'_, T, B> {/// Tries to acquire the lock. /// /// Returns a guard that can be used to access the data protected by the lock if successful. +// `Option<T>` is not `#[must_use]` even if `T` is, thus the attribute is needed here. +#[must_use = "if unused, the lock will be immediately unlocked" ] pub fn try_lock (&self) ->Option <Guard <'_,T ,B >> {// SAFETY: The constructor of the type calls `init`, so the existence of the object proves // that `init` was called.
Signature · 1 line
2.44.2
Hi Jason,
Quoted 9 lines · Jason Devers
The
Lock::try_lockfunction returns anOption<Guard<...>>, but it currently does not issue a warning if the return value is unused.
To avoid potential bugs, the#[must_use]annotation is added to ensure proper usage.Note that
Tis#[must_use]butOption<T>is not.
For more context, see: https://github.com/rust-lang/rust/issues/71368.
I think you could add Alice's Reviewed-by from the previous version:
or you have any reason that you need another "Reviewed-by" tag?
(No need to send a new version, I'm just making sure you and Alice both agree the "Reviewed-by" tag still applies to this patch.)
Regards,
Boqun
Quoted 21 lines
Signed-off-by Jason Devers <[email protected]>--- rust/kernel/sync/lock.rs | 2 ++ 1 file changed, 2 insertions(+)rust/kernel/sync/lock.rs +2
-0@@ -147,6 +147,8 @@ pub fn lock(&self) -> Guard<'_, T, B> {/// Tries to acquire the lock. /// /// Returns a guard that can be used to access the data protected by the lock if successful. +// `Option<T>` is not `#[must_use]` even if `T` is, thus the attribute is needed here. +#[must_use = "if unused, the lock will be immediately unlocked" ] pub fn try_lock (&self) ->Option <Guard <'_,T ,B >> {// SAFETY: The constructor of the type calls `init`, so the existence of the object proves // that `init` was called. Signature · 1 line
2.44.2
Quoted 11 lines · Jason Devers
The
Lock::try_lockfunction returns anOption<Guard<...>>, but it currently does not issue a warning if the return value is unused.
To avoid potential bugs, the#[must_use]annotation is added to ensure proper usage.Note that
Tis#[must_use]butOption<T>is not.
For more context, see: https://github.com/rust-lang/rust/issues/71368.Suggested-by Alice Ryhl <[email protected]>Signed-off-by Jason Devers <[email protected]>
Quoted 6 lines · Alice Ryhl
Quoted 5 lines · Jason Devers
The
Lock::try_lockfunction returns anOption<Guard<...>>, but it currently does not issue a warning if the return value is unused.
To avoid potential bugs, the#[must_use]annotation is added to ensure proper usage.
Quoted 8 lines
Quoted 6 lines
Note that
Tis#[must_use]butOption<T>is not.
For more context, see: https://github.com/rust-lang/rust/issues/71368.Suggested-by Alice Ryhl <[email protected]>Signed-off-by Jason Devers <[email protected]>Reviewed-by Alice Ryhl <[email protected]>
Queued. I reworded a bit on the commit log because of the tip maintainer guideline. Thank you both!
Regards,
Boqun
[tip: locking/core] rust: sync: Add #[must_use] to Lock::try_lock()
In reply to Jason DeversThe following commit has been merged into the locking/core branch of tip:
The following commit has been merged into the locking/core branch of tip:
Commit-ID: 99214efedea521f1b79fa2a28ff142e933fc3eba Gitweb: https://git.kernel.org/tip/99214efedea521f1b79fa2a28ff142e933fc3eba Author: Jason Devers <[email protected]> AuthorDate: Thu, 12 Dec 2024 10:47:53 -05:00 Committer: Boqun Feng <[email protected]> CommitterDate: Fri, 11 Jul 2025 15:11:54 -07:00
rust: sync: Add #[must_use] to Lock::try_lock()
The Lock::try_lock() function returns an Option<Guard<...>>, but it currently does not issue a warning if the return value is unused. To avoid potential bugs, the #[must_use] annotation is added to ensure proper usage.
Note that T is #[must_use] but Option<T> is not.
For more context, see: https://github.com/rust-lang/rust/issues/71368.
--- rust/kernel/sync/lock.rs | 2 ++ 1 file changed, 2 insertions(+)
rust/kernel/sync/lock.rs +2 -0
@@ -175,6 +175,8 @@ impl<T: ?Sized, B: Backend> Lock<T, B> {/// Tries to acquire the lock. /// /// Returns a guard that can be used to access the data protected by the lock if successful. +// `Option<T>` is not `#[must_use]` even if `T` is, thus the attribute is needed here. +#[must_use = "if unused, the lock will be immediately unlocked" ] pub fn try_lock (&self) ->Option <Guard <'_,T ,B >> {// SAFETY: The constructor of the type calls `init`, so the existence of the object proves // that `init` was called.
Quoted 2 lines · jos
How I understand the issue arises when the result of
Lock::try_lockis called and its return value can be ignored, the lock is never acquired, and no guard is created.
I may be misunderstanding what you are trying to say, but the guard is created, and the lock is acquired.
So the issue is that someone does not keep the guard around, so the guard is dropped right away and so the critical section is empty.
Cheers,
Miguel
Quoted 6 lines · Jason Devers
The
Lock::try_lockfunction returns anOption<Guard<...>>, but it currently does not issue a warning if the return value is unused. This could result in the lock being unlocked immediately, which is unsafe and unintended. This patch adds a#[must_use]annotation toLock::try_lockto prevent this.
I agree that "unsafe" is the wrong word here. We can just say "which is probably not what the user intended".
Quoted 1 line
Suggested-by Alice Ryhl <[email protected]>
I use [email protected] for kernel contributions.
Quoted 2 lines
Overall looks good to me! You may add: