-
Notifications
You must be signed in to change notification settings - Fork 13.3k
False postive for if-let-rescope
on hashbrown::HashMap::get
?
#137411
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
Another case with #![warn(if_let_rescope)]
#![allow(unused_variables)]
use std::sync::Arc;
pub struct Droppy;
impl Drop for Droppy {
fn drop(&mut self) {}
}
pub struct Foo {
field: Arc<Droppy>,
}
impl Foo {
// Triggers lint
pub fn foo(&mut self) {
if let Some(value) = Arc::get_mut(&mut self.field) {
// do something
} else {
// do something else
}
}
}
// Triggers lint
pub fn foo1(mut arc: Arc<Droppy>) {
if let Some(value) = Arc::get_mut(&mut arc) {
// do something
} else {
// do something else
}
}
/// Does NOT trigger lint
pub fn foo2(arc: &mut Arc<Droppy>) {
if let Some(value) = Arc::get_mut(arc) {
// do something
} else {
// do something else
}
} |
It seems like this doesn't even need Arc/HashMap, although this might be a separate issue: #![warn(if_let_rescope)]
#![allow(unused_variables, clippy::needless_else)]
pub struct SigDrop;
impl Drop for SigDrop {
fn drop(&mut self) {}
}
pub fn with_option() {
let sigdrop = Some(SigDrop);
if let Some(sigdrop_ref) = &sigdrop { // Triggers here
} else {
}
}
#[allow(irrefutable_let_patterns)]
pub fn irrefutable_pattern() {
let sigdrop = SigDrop;
if let sigdrop_ref = &sigdrop { // Triggers here
} else {
}
} This ends up triggering all over the https://github.com/serenity-rs/serenity codebase, making it hard to find a true positive. |
Is this a duplicate of that? My |
I don't think this is a duplicate. In this case, the value being rescoped doesn't even implement Drop. The other issue is about the lint not being able to reason that dropping None is a no-op. |
Another reproducer, which probably more clearly shows the cause of the issue: #![warn(if_let_rescope)]
pub struct SigDrop;
impl Drop for SigDrop {
fn drop(&mut self) {}
}
#[allow(irrefutable_let_patterns, dropping_references)]
pub fn irrefutable_pattern() {
let sigdrop = SigDrop;
if let () = drop(&sigdrop) { // Triggers here
} else {
}
} It seems that merely creating a reference to a value that implements drop is enough to trigger the lint. In the hashmap example, it's presumably due to creating a reference to the hashmap itself. I don't know why the lint doesn't fire for the std hashmap though. (Maybe it's a may_dangle somewhere?) |
This comment has been minimized.
This comment has been minimized.
One more example for this issue: #![warn(if_let_rescope)]
pub struct SigDrop;
impl Drop for SigDrop {
fn drop(&mut self) {}
}
pub fn f() {
let s: SigDrop; // uninitialized :-)
if let _ = match s {
_ => (),
} {
} else {
}
} here, It looks like it is just treating place expressions as if they’re values? |
Rollup merge of rust-lang#137444 - compiler-errors:drop-lint, r=oli-obk Improve behavior of `IF_LET_RESCOPE` around temporaries and place expressions Heavily reworks the `IF_LET_RESCOPE` to be more sensitive around 1. temporaries that get consumed/terminated and therefore should not trigger the lint, and 2. borrows of place expressions, which are not temporary values. Fixes rust-lang#137411
hashbrown::HashMap::get
returns a reference which has no significant drop.I've see this on other methods like
hashbrown::HashMap::get_mut
, the equivalent methods onstd::collections::HashMap
don't seem to have this false positive.Code
Code in the playground.
Current output
The text was updated successfully, but these errors were encountered: