File tree 4 files changed +56
-3
lines changed
4 files changed +56
-3
lines changed Original file line number Diff line number Diff line change 1
1
use clippy_utils:: diagnostics:: span_lint_and_sugg;
2
2
use clippy_utils:: ty:: is_type_diagnostic_item;
3
- use clippy_utils:: { is_expr_untyped_identity_function, is_trait_method} ;
3
+ use clippy_utils:: { is_expr_untyped_identity_function, is_trait_method, path_to_local} ;
4
+ use rustc_ast:: BindingMode ;
4
5
use rustc_errors:: Applicability ;
5
- use rustc_hir as hir;
6
+ use rustc_hir:: { self as hir, Node , PatKind } ;
6
7
use rustc_lint:: LateContext ;
7
8
use rustc_span:: { Span , sym} ;
8
9
@@ -24,6 +25,16 @@ pub(super) fn check(
24
25
&& is_expr_untyped_identity_function ( cx, map_arg)
25
26
&& let Some ( sugg_span) = expr. span . trim_start ( caller. span )
26
27
{
28
+ // If the result of `.map(identity)` is used as a mutable reference,
29
+ // the caller must not be an immutable binding.
30
+ if cx. typeck_results ( ) . expr_ty_adjusted ( expr) . is_mutable_ptr ( )
31
+ && let Some ( hir_id) = path_to_local ( caller)
32
+ && let Node :: Pat ( pat) = cx. tcx . hir_node ( hir_id)
33
+ && !matches ! ( pat. kind, PatKind :: Binding ( BindingMode :: MUT , ..) )
34
+ {
35
+ return ;
36
+ }
37
+
27
38
span_lint_and_sugg (
28
39
cx,
29
40
MAP_IDENTITY ,
Original file line number Diff line number Diff line change @@ -61,3 +61,18 @@ fn issue11764() {
61
61
// no match ergonomics for `(i32, i32)`
62
62
let _ = x.iter().copied();
63
63
}
64
+
65
+ fn issue13904() {
66
+ // don't lint: `it.next()` would not be legal as `it` is immutable
67
+ let it = [1, 2, 3].into_iter();
68
+ let _ = it.map(|x| x).next();
69
+
70
+ // lint
71
+ #[allow(unused_mut)]
72
+ let mut it = [1, 2, 3].into_iter();
73
+ let _ = it.next();
74
+
75
+ // lint
76
+ let it = [1, 2, 3].into_iter();
77
+ let _ = { it }.next();
78
+ }
Original file line number Diff line number Diff line change @@ -65,3 +65,18 @@ fn issue11764() {
65
65
// no match ergonomics for `(i32, i32)`
66
66
let _ = x. iter ( ) . copied ( ) . map ( |( x, y) | ( x, y) ) ;
67
67
}
68
+
69
+ fn issue13904 ( ) {
70
+ // don't lint: `it.next()` would not be legal as `it` is immutable
71
+ let it = [ 1 , 2 , 3 ] . into_iter ( ) ;
72
+ let _ = it. map ( |x| x) . next ( ) ;
73
+
74
+ // lint
75
+ #[ allow( unused_mut) ]
76
+ let mut it = [ 1 , 2 , 3 ] . into_iter ( ) ;
77
+ let _ = it. map ( |x| x) . next ( ) ;
78
+
79
+ // lint
80
+ let it = [ 1 , 2 , 3 ] . into_iter ( ) ;
81
+ let _ = { it } . map ( |x| x) . next ( ) ;
82
+ }
Original file line number Diff line number Diff line change @@ -73,5 +73,17 @@ error: unnecessary map of the identity function
73
73
LL | let _ = x.iter().copied().map(|(x, y)| (x, y));
74
74
| ^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `map`
75
75
76
- error: aborting due to 11 previous errors
76
+ error: unnecessary map of the identity function
77
+ --> tests/ui/map_identity.rs:77:15
78
+ |
79
+ LL | let _ = it.map(|x| x).next();
80
+ | ^^^^^^^^^^^ help: remove the call to `map`
81
+
82
+ error: unnecessary map of the identity function
83
+ --> tests/ui/map_identity.rs:81:19
84
+ |
85
+ LL | let _ = { it }.map(|x| x).next();
86
+ | ^^^^^^^^^^^ help: remove the call to `map`
87
+
88
+ error: aborting due to 13 previous errors
77
89
You can’t perform that action at this time.
0 commit comments