Skip to content

Commit 9ede32f

Browse files
authored
needless_option_take: add autofix (rust-lang#14042)
changelog: [`needless_option_take`]: add autofix
2 parents 51d49c1 + f0b99b2 commit 9ede32f

File tree

3 files changed

+99
-13
lines changed

3 files changed

+99
-13
lines changed

clippy_lints/src/methods/needless_option_take.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
use clippy_utils::diagnostics::span_lint_and_note;
1+
use clippy_utils::diagnostics::span_lint_and_then;
22
use clippy_utils::ty::is_type_diagnostic_item;
3+
use rustc_errors::Applicability;
34
use rustc_hir::{Expr, ExprKind, QPath};
45
use rustc_lint::LateContext;
56
use rustc_span::sym;
@@ -10,13 +11,22 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'
1011
// Checks if expression type is equal to sym::Option and if the expr is not a syntactic place
1112
if !recv.is_syntactic_place_expr() && is_expr_option(cx, recv) {
1213
if let Some(function_name) = source_of_temporary_value(recv) {
13-
span_lint_and_note(
14+
span_lint_and_then(
1415
cx,
1516
NEEDLESS_OPTION_TAKE,
1617
expr.span,
1718
"called `Option::take()` on a temporary value",
18-
None,
19-
format!("`{function_name}` creates a temporary value, so calling take() has no effect"),
19+
|diag| {
20+
diag.note(format!(
21+
"`{function_name}` creates a temporary value, so calling take() has no effect"
22+
));
23+
diag.span_suggestion(
24+
expr.span.with_lo(recv.span.hi()),
25+
"remove",
26+
"",
27+
Applicability::MachineApplicable,
28+
);
29+
},
2030
);
2131
}
2232
}

tests/ui/needless_option_take.fixed

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
struct MyStruct;
2+
3+
impl MyStruct {
4+
pub fn get_option() -> Option<Self> {
5+
todo!()
6+
}
7+
}
8+
9+
fn return_option() -> Option<i32> {
10+
todo!()
11+
}
12+
13+
fn main() {
14+
println!("Testing non erroneous option_take_on_temporary");
15+
let mut option = Some(1);
16+
let _ = Box::new(move || option.take().unwrap());
17+
18+
println!("Testing non erroneous option_take_on_temporary");
19+
let x = Some(3);
20+
x.as_ref();
21+
22+
let x = Some(3);
23+
x.as_ref();
24+
//~^ ERROR: called `Option::take()` on a temporary value
25+
26+
println!("Testing non erroneous option_take_on_temporary");
27+
let mut x = Some(3);
28+
let y = x.as_mut();
29+
30+
let mut x = Some(3);
31+
let y = x.as_mut();
32+
//~^ ERROR: called `Option::take()` on a temporary value
33+
let y = x.replace(289);
34+
//~^ ERROR: called `Option::take()` on a temporary value
35+
36+
let y = Some(3).as_mut();
37+
//~^ ERROR: called `Option::take()` on a temporary value
38+
39+
let y = Option::as_mut(&mut x);
40+
//~^ ERROR: called `Option::take()` on a temporary value
41+
42+
let x = return_option();
43+
let x = return_option();
44+
//~^ ERROR: called `Option::take()` on a temporary value
45+
46+
let x = MyStruct::get_option();
47+
let x = MyStruct::get_option();
48+
//~^ ERROR: called `Option::take()` on a temporary value
49+
50+
let mut my_vec = vec![1, 2, 3];
51+
my_vec.push(4);
52+
let y = my_vec.first();
53+
let y = my_vec.first();
54+
//~^ ERROR: called `Option::take()` on a temporary value
55+
56+
let y = my_vec.first();
57+
//~^ ERROR: called `Option::take()` on a temporary value
58+
}

tests/ui/needless_option_take.stderr

+27-9
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ error: called `Option::take()` on a temporary value
22
--> tests/ui/needless_option_take.rs:23:5
33
|
44
LL | x.as_ref().take();
5-
| ^^^^^^^^^^^^^^^^^
5+
| ^^^^^^^^^^-------
6+
| |
7+
| help: remove
68
|
79
= note: `as_ref` creates a temporary value, so calling take() has no effect
810
= note: `-D clippy::needless-option-take` implied by `-D warnings`
@@ -12,63 +14,79 @@ error: called `Option::take()` on a temporary value
1214
--> tests/ui/needless_option_take.rs:31:13
1315
|
1416
LL | let y = x.as_mut().take();
15-
| ^^^^^^^^^^^^^^^^^
17+
| ^^^^^^^^^^-------
18+
| |
19+
| help: remove
1620
|
1721
= note: `as_mut` creates a temporary value, so calling take() has no effect
1822

1923
error: called `Option::take()` on a temporary value
2024
--> tests/ui/needless_option_take.rs:33:13
2125
|
2226
LL | let y = x.replace(289).take();
23-
| ^^^^^^^^^^^^^^^^^^^^^
27+
| ^^^^^^^^^^^^^^-------
28+
| |
29+
| help: remove
2430
|
2531
= note: `replace` creates a temporary value, so calling take() has no effect
2632

2733
error: called `Option::take()` on a temporary value
2834
--> tests/ui/needless_option_take.rs:36:13
2935
|
3036
LL | let y = Some(3).as_mut().take();
31-
| ^^^^^^^^^^^^^^^^^^^^^^^
37+
| ^^^^^^^^^^^^^^^^-------
38+
| |
39+
| help: remove
3240
|
3341
= note: `as_mut` creates a temporary value, so calling take() has no effect
3442

3543
error: called `Option::take()` on a temporary value
3644
--> tests/ui/needless_option_take.rs:39:13
3745
|
3846
LL | let y = Option::as_mut(&mut x).take();
39-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
47+
| ^^^^^^^^^^^^^^^^^^^^^^-------
48+
| |
49+
| help: remove
4050
|
4151
= note: `as_mut` creates a temporary value, so calling take() has no effect
4252

4353
error: called `Option::take()` on a temporary value
4454
--> tests/ui/needless_option_take.rs:43:13
4555
|
4656
LL | let x = return_option().take();
47-
| ^^^^^^^^^^^^^^^^^^^^^^
57+
| ^^^^^^^^^^^^^^^-------
58+
| |
59+
| help: remove
4860
|
4961
= note: `return_option` creates a temporary value, so calling take() has no effect
5062

5163
error: called `Option::take()` on a temporary value
5264
--> tests/ui/needless_option_take.rs:47:13
5365
|
5466
LL | let x = MyStruct::get_option().take();
55-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
67+
| ^^^^^^^^^^^^^^^^^^^^^^-------
68+
| |
69+
| help: remove
5670
|
5771
= note: `get_option` creates a temporary value, so calling take() has no effect
5872

5973
error: called `Option::take()` on a temporary value
6074
--> tests/ui/needless_option_take.rs:53:13
6175
|
6276
LL | let y = my_vec.first().take();
63-
| ^^^^^^^^^^^^^^^^^^^^^
77+
| ^^^^^^^^^^^^^^-------
78+
| |
79+
| help: remove
6480
|
6581
= note: `first` creates a temporary value, so calling take() has no effect
6682

6783
error: called `Option::take()` on a temporary value
6884
--> tests/ui/needless_option_take.rs:56:13
6985
|
7086
LL | let y = my_vec.first().take();
71-
| ^^^^^^^^^^^^^^^^^^^^^
87+
| ^^^^^^^^^^^^^^-------
88+
| |
89+
| help: remove
7290
|
7391
= note: `first` creates a temporary value, so calling take() has no effect
7492

0 commit comments

Comments
 (0)