fix: significant_drop_tightening suggests wrongly for non-method usage
This commit is contained in:
parent
6c83a47592
commit
4976fdf203
4 changed files with 152 additions and 12 deletions
|
|
@ -2,6 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
|
|||
use clippy_utils::res::MaybeResPath;
|
||||
use clippy_utils::source::{indent_of, snippet};
|
||||
use clippy_utils::{expr_or_init, get_builtin_attr, peel_hir_expr_unary, sym};
|
||||
use rustc_ast::BindingMode;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_hir::def::{DefKind, Res};
|
||||
|
|
@ -89,13 +90,14 @@ impl<'tcx> LateLintPass<'tcx> for SignificantDropTightening<'tcx> {
|
|||
|diag| {
|
||||
match apa.counter {
|
||||
0 | 1 => {},
|
||||
2 => {
|
||||
2 if let Some(last_method_span) = apa.last_method_span => {
|
||||
let indent = " ".repeat(indent_of(cx, apa.last_stmt_span).unwrap_or(0));
|
||||
let init_method = snippet(cx, apa.first_method_span, "..");
|
||||
let usage_method = snippet(cx, apa.last_method_span, "..");
|
||||
let stmt = if let Some(last_bind_ident) = apa.last_bind_ident {
|
||||
let usage_method = snippet(cx, last_method_span, "..");
|
||||
let stmt = if let Some((binding_mode, last_bind_ident)) = apa.last_bind_ident {
|
||||
format!(
|
||||
"\n{indent}let {} = {init_method}.{usage_method};",
|
||||
"\n{indent}let {}{} = {init_method}.{usage_method};",
|
||||
binding_mode.prefix_str(),
|
||||
snippet(cx, last_bind_ident.span, ".."),
|
||||
)
|
||||
} else {
|
||||
|
|
@ -310,13 +312,13 @@ impl<'tcx> Visitor<'tcx> for StmtsChecker<'_, '_, '_, '_, 'tcx> {
|
|||
};
|
||||
match self.ap.curr_stmt.kind {
|
||||
hir::StmtKind::Let(local) => {
|
||||
if let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind {
|
||||
apa.last_bind_ident = Some(ident);
|
||||
if let hir::PatKind::Binding(binding_mode, _, ident, _) = local.pat.kind {
|
||||
apa.last_bind_ident = Some((binding_mode, ident));
|
||||
}
|
||||
if let Some(local_init) = local.init
|
||||
&& let hir::ExprKind::MethodCall(_, _, _, span) = local_init.kind
|
||||
{
|
||||
apa.last_method_span = span;
|
||||
apa.last_method_span = Some(span);
|
||||
}
|
||||
},
|
||||
hir::StmtKind::Semi(semi_expr) => {
|
||||
|
|
@ -326,7 +328,7 @@ impl<'tcx> Visitor<'tcx> for StmtsChecker<'_, '_, '_, '_, 'tcx> {
|
|||
return;
|
||||
}
|
||||
if let hir::ExprKind::MethodCall(_, _, _, span) = semi_expr.kind {
|
||||
apa.last_method_span = span;
|
||||
apa.last_method_span = Some(span);
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
|
|
@ -385,9 +387,9 @@ struct AuxParamsAttr {
|
|||
|
||||
/// The last visited binding or variable span within a block that had any referenced inner type
|
||||
/// marked with `#[has_significant_drop]`.
|
||||
last_bind_ident: Option<Ident>,
|
||||
last_bind_ident: Option<(BindingMode, Ident)>,
|
||||
/// Similar to `last_bind_span` but encompasses the right-hand method call.
|
||||
last_method_span: Span,
|
||||
last_method_span: Option<Span>,
|
||||
/// Similar to `last_bind_span` but encompasses the whole contained statement.
|
||||
last_stmt_span: Span,
|
||||
}
|
||||
|
|
@ -403,7 +405,7 @@ impl Default for AuxParamsAttr {
|
|||
first_method_span: DUMMY_SP,
|
||||
first_stmt_span: DUMMY_SP,
|
||||
last_bind_ident: None,
|
||||
last_method_span: DUMMY_SP,
|
||||
last_method_span: None,
|
||||
last_stmt_span: DUMMY_SP,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,3 +146,39 @@ pub fn unnecessary_contention_with_single_owned_results() {
|
|||
pub fn do_heavy_computation_that_takes_time<T>(_: T) {}
|
||||
|
||||
fn main() {}
|
||||
|
||||
fn issue15574() {
|
||||
use std::io::{BufRead, Read, stdin};
|
||||
use std::process;
|
||||
|
||||
println!("Hello, what's your name?");
|
||||
|
||||
let mut stdin = stdin().lock().take(40);
|
||||
//~^ significant_drop_tightening
|
||||
let mut buffer = String::with_capacity(10);
|
||||
|
||||
|
||||
//~^ significant_drop_tightening
|
||||
if stdin.read_line(&mut buffer).is_err() {
|
||||
eprintln!("An error has occured while reading.");
|
||||
return;
|
||||
}
|
||||
drop(stdin);
|
||||
println!("Our string has a capacity of {}", buffer.capacity());
|
||||
println!("Hello {}!", buffer);
|
||||
}
|
||||
|
||||
fn issue16343() {
|
||||
fn get_items(x: &()) -> Vec<()> {
|
||||
vec![*x]
|
||||
}
|
||||
|
||||
let storage = Mutex::new(());
|
||||
let lock = storage.lock().unwrap();
|
||||
//~^ significant_drop_tightening
|
||||
let items = get_items(&lock);
|
||||
drop(lock);
|
||||
for item in items {
|
||||
println!("item {:?}", item);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -142,3 +142,36 @@ pub fn unnecessary_contention_with_single_owned_results() {
|
|||
pub fn do_heavy_computation_that_takes_time<T>(_: T) {}
|
||||
|
||||
fn main() {}
|
||||
|
||||
fn issue15574() {
|
||||
use std::io::{BufRead, Read, stdin};
|
||||
use std::process;
|
||||
|
||||
println!("Hello, what's your name?");
|
||||
let stdin = stdin().lock();
|
||||
//~^ significant_drop_tightening
|
||||
let mut buffer = String::with_capacity(10);
|
||||
|
||||
let mut stdin = stdin.take(40);
|
||||
//~^ significant_drop_tightening
|
||||
if stdin.read_line(&mut buffer).is_err() {
|
||||
eprintln!("An error has occured while reading.");
|
||||
return;
|
||||
}
|
||||
println!("Our string has a capacity of {}", buffer.capacity());
|
||||
println!("Hello {}!", buffer);
|
||||
}
|
||||
|
||||
fn issue16343() {
|
||||
fn get_items(x: &()) -> Vec<()> {
|
||||
vec![*x]
|
||||
}
|
||||
|
||||
let storage = Mutex::new(());
|
||||
let lock = storage.lock().unwrap();
|
||||
//~^ significant_drop_tightening
|
||||
let items = get_items(&lock);
|
||||
for item in items {
|
||||
println!("item {:?}", item);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,5 +83,74 @@ LL |
|
|||
LL ~
|
||||
|
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
error: temporary with significant `Drop` can be early dropped
|
||||
--> tests/ui/significant_drop_tightening.rs:151:9
|
||||
|
|
||||
LL | fn issue15574() {
|
||||
| _________________-
|
||||
LL | | use std::io::{BufRead, Read, stdin};
|
||||
LL | | use std::process;
|
||||
... |
|
||||
LL | | let stdin = stdin().lock();
|
||||
| | ^^^^^
|
||||
... |
|
||||
LL | | println!("Hello {}!", buffer);
|
||||
LL | | }
|
||||
| |_- temporary `stdin` is currently being dropped at the end of its contained scope
|
||||
|
|
||||
= note: this might lead to unnecessary resource contention
|
||||
help: merge the temporary construction with its single usage
|
||||
|
|
||||
LL ~
|
||||
LL + let mut stdin = stdin().lock().take(40);
|
||||
LL |
|
||||
LL | let mut buffer = String::with_capacity(10);
|
||||
LL |
|
||||
LL ~
|
||||
|
|
||||
|
||||
error: temporary with significant `Drop` can be early dropped
|
||||
--> tests/ui/significant_drop_tightening.rs:155:13
|
||||
|
|
||||
LL | fn issue15574() {
|
||||
| _________________-
|
||||
LL | | use std::io::{BufRead, Read, stdin};
|
||||
LL | | use std::process;
|
||||
... |
|
||||
LL | | let mut stdin = stdin.take(40);
|
||||
| | ^^^^^
|
||||
... |
|
||||
LL | | println!("Hello {}!", buffer);
|
||||
LL | | }
|
||||
| |_- temporary `stdin` is currently being dropped at the end of its contained scope
|
||||
|
|
||||
= note: this might lead to unnecessary resource contention
|
||||
help: drop the temporary after the end of its last usage
|
||||
|
|
||||
LL ~ }
|
||||
LL + drop(stdin);
|
||||
|
|
||||
|
||||
error: temporary with significant `Drop` can be early dropped
|
||||
--> tests/ui/significant_drop_tightening.rs:171:9
|
||||
|
|
||||
LL | fn issue16343() {
|
||||
| _________________-
|
||||
LL | | fn get_items(x: &()) -> Vec<()> {
|
||||
LL | | vec![*x]
|
||||
... |
|
||||
LL | | let lock = storage.lock().unwrap();
|
||||
| | ^^^^
|
||||
... |
|
||||
LL | | }
|
||||
| |_- temporary `lock` is currently being dropped at the end of its contained scope
|
||||
|
|
||||
= note: this might lead to unnecessary resource contention
|
||||
help: drop the temporary after the end of its last usage
|
||||
|
|
||||
LL ~ let items = get_items(&lock);
|
||||
LL + drop(lock);
|
||||
|
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue