Skip to content

Commit 5595d7f

Browse files
committed
Auto merge of #9750 - kraktus:lazy_eval, r=xFrednet
Fix [`unnecessary_lazy_eval`] when type has significant drop fix for #9427 (comment) However current implementation gives too many false positive, rending the lint almost useless. I don't know what's the best way to check if a type has a "significant" drop (in the common meaning, not the internal rustc one, for example Option<(u8, u8)> should not be considered significant) changelog: Fix [`unnecessary_lazy_eval`] when type has significant drop
2 parents 94ce446 + ed183ee commit 5595d7f

File tree

4 files changed

+92
-64
lines changed

4 files changed

+92
-64
lines changed

clippy_utils/src/eager_or_lazy.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,16 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg:
9191
}
9292
}
9393

94+
fn res_has_significant_drop(res: Res, cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
95+
if let Res::Def(DefKind::Ctor(..) | DefKind::Variant, _) | Res::SelfCtor(_) = res {
96+
cx.typeck_results()
97+
.expr_ty(e)
98+
.has_significant_drop(cx.tcx, cx.param_env)
99+
} else {
100+
false
101+
}
102+
}
103+
94104
#[expect(clippy::too_many_lines)]
95105
fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessSuggestion {
96106
struct V<'cx, 'tcx> {
@@ -113,13 +123,8 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
113123
},
114124
args,
115125
) => match self.cx.qpath_res(path, hir_id) {
116-
Res::Def(DefKind::Ctor(..) | DefKind::Variant, _) | Res::SelfCtor(_) => {
117-
if self
118-
.cx
119-
.typeck_results()
120-
.expr_ty(e)
121-
.has_significant_drop(self.cx.tcx, self.cx.param_env)
122-
{
126+
res @ (Res::Def(DefKind::Ctor(..) | DefKind::Variant, _) | Res::SelfCtor(_)) => {
127+
if res_has_significant_drop(res, self.cx, e) {
123128
self.eagerness = ForceNoChange;
124129
return;
125130
}
@@ -147,6 +152,12 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
147152
self.eagerness |= NoChange;
148153
return;
149154
},
155+
ExprKind::Path(ref path) => {
156+
if res_has_significant_drop(self.cx.qpath_res(path, e.hir_id), self.cx, e) {
157+
self.eagerness = ForceNoChange;
158+
return;
159+
}
160+
},
150161
ExprKind::MethodCall(name, ..) => {
151162
self.eagerness |= self
152163
.cx
@@ -206,7 +217,6 @@ fn expr_eagerness<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> EagernessS
206217
| ExprKind::Match(..)
207218
| ExprKind::Closure { .. }
208219
| ExprKind::Field(..)
209-
| ExprKind::Path(_)
210220
| ExprKind::AddrOf(..)
211221
| ExprKind::Struct(..)
212222
| ExprKind::Repeat(..)

tests/ui/unnecessary_lazy_eval.fixed

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ impl Drop for Issue9427 {
3333
}
3434
}
3535

36+
struct Issue9427FollowUp;
37+
38+
impl Drop for Issue9427FollowUp {
39+
fn drop(&mut self) {
40+
panic!("side effect drop");
41+
}
42+
}
43+
3644
fn main() {
3745
let astronomers_pi = 10;
3846
let ext_arr: [usize; 1] = [2];
@@ -87,6 +95,7 @@ fn main() {
8795

8896
// Should not lint - bool
8997
let _ = (0 == 1).then(|| Issue9427(0)); // Issue9427 has a significant drop
98+
let _ = false.then(|| Issue9427FollowUp); // Issue9427FollowUp has a significant drop
9099

91100
// should not lint, bind_instead_of_map takes priority
92101
let _ = Some(10).and_then(|idx| Some(ext_arr[idx]));
@@ -133,13 +142,13 @@ fn main() {
133142
let _: Result<usize, usize> = res.or(Ok(astronomers_pi));
134143
let _: Result<usize, usize> = res.or(Ok(ext_str.some_field));
135144
let _: Result<usize, usize> = res.
136-
// some lines
137-
// some lines
138-
// some lines
139-
// some lines
140-
// some lines
141-
// some lines
142-
or(Ok(ext_str.some_field));
145+
// some lines
146+
// some lines
147+
// some lines
148+
// some lines
149+
// some lines
150+
// some lines
151+
or(Ok(ext_str.some_field));
143152

144153
// neither bind_instead_of_map nor unnecessary_lazy_eval applies here
145154
let _: Result<usize, usize> = res.and_then(|x| Err(x));

tests/ui/unnecessary_lazy_eval.rs

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ impl Drop for Issue9427 {
3333
}
3434
}
3535

36+
struct Issue9427FollowUp;
37+
38+
impl Drop for Issue9427FollowUp {
39+
fn drop(&mut self) {
40+
panic!("side effect drop");
41+
}
42+
}
43+
3644
fn main() {
3745
let astronomers_pi = 10;
3846
let ext_arr: [usize; 1] = [2];
@@ -87,6 +95,7 @@ fn main() {
8795

8896
// Should not lint - bool
8997
let _ = (0 == 1).then(|| Issue9427(0)); // Issue9427 has a significant drop
98+
let _ = false.then(|| Issue9427FollowUp); // Issue9427FollowUp has a significant drop
9099

91100
// should not lint, bind_instead_of_map takes priority
92101
let _ = Some(10).and_then(|idx| Some(ext_arr[idx]));
@@ -133,13 +142,13 @@ fn main() {
133142
let _: Result<usize, usize> = res.or_else(|_| Ok(astronomers_pi));
134143
let _: Result<usize, usize> = res.or_else(|_| Ok(ext_str.some_field));
135144
let _: Result<usize, usize> = res.
136-
// some lines
137-
// some lines
138-
// some lines
139-
// some lines
140-
// some lines
141-
// some lines
142-
or_else(|_| Ok(ext_str.some_field));
145+
// some lines
146+
// some lines
147+
// some lines
148+
// some lines
149+
// some lines
150+
// some lines
151+
or_else(|_| Ok(ext_str.some_field));
143152

144153
// neither bind_instead_of_map nor unnecessary_lazy_eval applies here
145154
let _: Result<usize, usize> = res.and_then(|x| Err(x));

0 commit comments

Comments
 (0)