1
1
use clippy_utils:: diagnostics:: { span_lint_and_note, span_lint_and_then} ;
2
2
use clippy_utils:: source:: { first_line_of_span, indent_of, reindent_multiline, snippet, snippet_opt} ;
3
- use clippy_utils:: ty:: needs_ordered_drop;
3
+ use clippy_utils:: ty:: { is_interior_mut_ty , needs_ordered_drop} ;
4
4
use clippy_utils:: visitors:: for_each_expr;
5
5
use clippy_utils:: {
6
6
capture_local_usage, def_path_def_ids, eq_expr_value, find_binding_init, get_enclosing_block, hash_expr, hash_stmt,
@@ -164,12 +164,14 @@ declare_clippy_lint! {
164
164
165
165
pub struct CopyAndPaste {
166
166
ignore_interior_mutability : Vec < String > ,
167
+ ignored_ty_ids : FxHashSet < DefId > ,
167
168
}
168
169
169
170
impl CopyAndPaste {
170
171
pub fn new ( ignore_interior_mutability : Vec < String > ) -> Self {
171
172
Self {
172
173
ignore_interior_mutability,
174
+ ignored_ty_ids : FxHashSet :: default ( ) ,
173
175
}
174
176
}
175
177
}
@@ -182,17 +184,18 @@ impl_lint_pass!(CopyAndPaste => [
182
184
] ) ;
183
185
184
186
impl < ' tcx > LateLintPass < ' tcx > for CopyAndPaste {
187
+ fn check_crate ( & mut self , cx : & LateContext < ' tcx > ) {
188
+ for ignored_ty in & self . ignore_interior_mutability {
189
+ let path: Vec < & str > = ignored_ty. split ( "::" ) . collect ( ) ;
190
+ for id in def_path_def_ids ( cx, path. as_slice ( ) ) {
191
+ self . ignored_ty_ids . insert ( id) ;
192
+ }
193
+ }
194
+ }
185
195
fn check_expr ( & mut self , cx : & LateContext < ' tcx > , expr : & ' tcx Expr < ' _ > ) {
186
196
if !expr. span . from_expansion ( ) && matches ! ( expr. kind, ExprKind :: If ( ..) ) && !is_else_clause ( cx. tcx , expr) {
187
197
let ( conds, blocks) = if_sequence ( expr) ;
188
- let mut ignored_ty_ids = FxHashSet :: default ( ) ;
189
- for ignored_ty in & self . ignore_interior_mutability {
190
- let path: Vec < & str > = ignored_ty. split ( "::" ) . collect ( ) ;
191
- for id in def_path_def_ids ( cx, path. as_slice ( ) ) {
192
- ignored_ty_ids. insert ( id) ;
193
- }
194
- }
195
- lint_same_cond ( cx, & conds, & ignored_ty_ids) ;
198
+ lint_same_cond ( cx, & conds, & self . ignored_ty_ids ) ;
196
199
lint_same_fns_in_if_cond ( cx, & conds) ;
197
200
let all_same =
198
201
!is_lint_allowed ( cx, IF_SAME_THEN_ELSE , expr. hir_id ) && lint_if_same_then_else ( cx, & conds, & blocks) ;
@@ -569,28 +572,18 @@ fn check_for_warn_of_moved_symbol(cx: &LateContext<'_>, symbols: &[(HirId, Symbo
569
572
} )
570
573
}
571
574
572
- fn method_caller_is_ignored_or_mutable (
573
- cx : & LateContext < ' _ > ,
574
- caller_expr : & Expr < ' _ > ,
575
- ignored_ty_ids : & FxHashSet < DefId > ,
576
- ) -> bool {
575
+ fn method_caller_is_mutable ( cx : & LateContext < ' _ > , caller_expr : & Expr < ' _ > , ignored_ty_ids : & FxHashSet < DefId > ) -> bool {
577
576
let caller_ty = cx. typeck_results ( ) . expr_ty ( caller_expr) ;
578
- let is_ignored_ty = if let Some ( adt_id) = caller_ty. ty_adt_id ( ) && ignored_ty_ids. contains ( & adt_id) {
579
- true
580
- } else {
581
- false
582
- } ;
577
+ // Check if given type has inner mutability and was not set to ignored by the configuration
578
+ let is_inner_mut_ty = is_interior_mut_ty ( cx, caller_ty)
579
+ && !matches ! ( caller_ty. ty_adt_id( ) , Some ( adt_id) if ignored_ty_ids. contains( & adt_id) ) ;
583
580
584
- if is_ignored_ty
581
+ is_inner_mut_ty
585
582
|| caller_ty. is_mutable_ptr ( )
583
+ // `find_binding_init` will return the binding iff its not mutable
586
584
|| path_to_local ( caller_expr)
587
585
. and_then ( |hid| find_binding_init ( cx, hid) )
588
586
. is_none ( )
589
- {
590
- return true ;
591
- }
592
-
593
- false
594
587
}
595
588
596
589
/// Implementation of `IFS_SAME_COND`.
@@ -599,8 +592,10 @@ fn lint_same_cond(cx: &LateContext<'_>, conds: &[&Expr<'_>], ignored_ty_ids: &Fx
599
592
conds,
600
593
|e| hash_expr ( cx, e) ,
601
594
|lhs, rhs| {
595
+ // Ignore eq_expr side effects iff one of the expressin kind is a method call
596
+ // and the caller is not a mutable, including inner mutable type.
602
597
if let ExprKind :: MethodCall ( _, caller, _, _) = lhs. kind {
603
- if method_caller_is_ignored_or_mutable ( cx, caller, ignored_ty_ids) {
598
+ if method_caller_is_mutable ( cx, caller, ignored_ty_ids) {
604
599
false
605
600
} else {
606
601
SpanlessEq :: new ( cx) . eq_expr ( lhs, rhs)
0 commit comments