diff --git a/clippy_lints/src/ptr.rs b/clippy_lints/src/ptr.rs index b5d65542de0..77bf5f002f7 100644 --- a/clippy_lints/src/ptr.rs +++ b/clippy_lints/src/ptr.rs @@ -153,7 +153,9 @@ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_> cx.tcx.fn_sig(item.def_id).skip_binder().inputs(), sig.decl.inputs, &[], - ) { + ) + .filter(|arg| arg.mutability() == Mutability::Not) + { span_lint_and_sugg( cx, PTR_ARG, @@ -170,10 +172,10 @@ fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'_> fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) { let hir = cx.tcx.hir(); let mut parents = hir.parent_iter(body.value.hir_id); - let (item_id, decl) = match parents.next() { + let (item_id, decl, is_trait_item) = match parents.next() { Some((_, Node::Item(i))) => { if let ItemKind::Fn(sig, ..) = &i.kind { - (i.def_id, sig.decl) + (i.def_id, sig.decl, false) } else { return; } @@ -185,14 +187,14 @@ fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) { return; } if let ImplItemKind::Fn(sig, _) = &i.kind { - (i.def_id, sig.decl) + (i.def_id, sig.decl, false) } else { return; } }, Some((_, Node::TraitItem(i))) => { if let TraitItemKind::Fn(sig, _) = &i.kind { - (i.def_id, sig.decl) + (i.def_id, sig.decl, true) } else { return; } @@ -202,7 +204,9 @@ fn check_body(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) { check_mut_from_ref(cx, decl); let sig = cx.tcx.fn_sig(item_id).skip_binder(); - let lint_args: Vec<_> = check_fn_args(cx, sig.inputs(), decl.inputs, body.params).collect(); + let lint_args: Vec<_> = check_fn_args(cx, sig.inputs(), decl.inputs, body.params) + .filter(|arg| !is_trait_item || arg.mutability() == Mutability::Not) + .collect(); let results = check_ptr_arg_usage(cx, body, &lint_args); for (result, args) in results.iter().zip(lint_args.iter()).filter(|(r, _)| !r.skip) { @@ -318,6 +322,10 @@ fn build_msg(&self) -> String { self.deref_ty.argless_str(), ) } + + fn mutability(&self) -> Mutability { + self.ref_prefix.mutability + } } struct RefPrefix { diff --git a/tests/ui/ptr_arg.rs b/tests/ui/ptr_arg.rs index ed724237808..00b99da2631 100644 --- a/tests/ui/ptr_arg.rs +++ b/tests/ui/ptr_arg.rs @@ -180,3 +180,9 @@ fn dyn_fn_requires_vec(v: &Vec, f: &dyn Fn(&Vec)) { // No error for types behind an alias (#7699) type A = Vec; fn aliased(a: &A) {} + +// Issue #8366 +pub trait Trait { + fn f(v: &mut Vec); + fn f2(v: &mut Vec) {} +}