From dbb8a872a3aea4bb9510d109f5f7dbe5273446da Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Sat, 31 Oct 2015 05:18:05 +0530 Subject: [PATCH] Fix ptr-arg false positive for trait impls Fixes #425 --- src/ptr_arg.rs | 10 ++++++++-- tests/compile-fail/ptr_arg.rs | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/ptr_arg.rs b/src/ptr_arg.rs index 4baba7118..78a3c146c 100644 --- a/src/ptr_arg.rs +++ b/src/ptr_arg.rs @@ -5,6 +5,7 @@ use rustc::lint::*; use rustc_front::hir::*; use rustc::middle::ty; +use rustc::front::map::Node; use utils::{span_lint, match_type}; use utils::{STRING_PATH, VEC_PATH}; @@ -34,6 +35,11 @@ impl LateLintPass for PtrArg { fn check_impl_item(&mut self, cx: &LateContext, item: &ImplItem) { if let &MethodImplItem(ref sig, _) = &item.node { + if let Some(Node::NodeItem(it)) = cx.tcx.map.find(cx.tcx.map.get_parent(item.id)) { + if let ItemImpl(_, _, _, Some(_), _, _) = it.node { + return; // ignore trait impls + } + } check_fn(cx, &sig.decl); } } @@ -47,8 +53,8 @@ impl LateLintPass for PtrArg { fn check_fn(cx: &LateContext, decl: &FnDecl) { for arg in &decl.inputs { - if let Some(pat_ty) = cx.tcx.pat_ty_opt(&arg.pat) { - if let ty::TyRef(_, ty::TypeAndMut { ty, mutbl: MutImmutable }) = pat_ty.sty { + if let Some(ty) = cx.tcx.ast_ty_to_ty_cache.borrow().get(&arg.ty.id) { + if let ty::TyRef(_, ty::TypeAndMut { ty, mutbl: MutImmutable }) = ty.sty { if match_type(cx, ty, &VEC_PATH) { span_lint(cx, PTR_ARG, arg.ty.span, "writing `&Vec<_>` instead of `&[_]` involves one more reference \ diff --git a/tests/compile-fail/ptr_arg.rs b/tests/compile-fail/ptr_arg.rs index d0615be49..e49712087 100755 --- a/tests/compile-fail/ptr_arg.rs +++ b/tests/compile-fail/ptr_arg.rs @@ -21,3 +21,18 @@ fn do_str_mut(x: &mut String) { // no error here fn main() { } + +trait Foo { + type Item; + fn do_vec(x: &Vec); //~ERROR writing `&Vec<_>` + fn do_item(x: &Self::Item); +} + +struct Bar; + +// no error, in trait impl (#425) +impl Foo for Bar { + type Item = Vec; + fn do_vec(x: &Vec) {} + fn do_item(x: &Vec) {} +}