1 //! Checks for usage of &Vec[_] and &String
3 //! This lint is **warn** by default
6 use rustc_front::hir::*;
8 use rustc::front::map::Node;
10 use utils::{span_lint, match_type};
11 use utils::{STRING_PATH, VEC_PATH};
13 /// **What it does:** This lint checks for function arguments of type `&String` or `&Vec` unless the references are mutable. It is `Warn` by default.
15 /// **Why is this bad?** Requiring the argument to be of the specific size makes the function less useful for no benefit; slices in the form of `&[T]` or `&str` usually suffice and can be obtained from other types, too.
17 /// **Known problems:** None
19 /// **Example:** `fn foo(&Vec<u32>) { .. }`
23 "fn arguments of the type `&Vec<...>` or `&String`, suggesting to use `&[...]` or `&str` \
24 instead, respectively"
30 impl LintPass for PtrArg {
31 fn get_lints(&self) -> LintArray {
36 impl LateLintPass for PtrArg {
37 fn check_item(&mut self, cx: &LateContext, item: &Item) {
38 if let ItemFn(ref decl, _, _, _, _, _) = item.node {
43 fn check_impl_item(&mut self, cx: &LateContext, item: &ImplItem) {
44 if let ImplItemKind::Method(ref sig, _) = item.node {
45 if let Some(Node::NodeItem(it)) = cx.tcx.map.find(cx.tcx.map.get_parent(item.id)) {
46 if let ItemImpl(_, _, _, Some(_), _, _) = it.node {
47 return; // ignore trait impls
50 check_fn(cx, &sig.decl);
54 fn check_trait_item(&mut self, cx: &LateContext, item: &TraitItem) {
55 if let MethodTraitItem(ref sig, _) = item.node {
56 check_fn(cx, &sig.decl);
61 fn check_fn(cx: &LateContext, decl: &FnDecl) {
62 for arg in &decl.inputs {
63 if let Some(ty) = cx.tcx.ast_ty_to_ty_cache.borrow().get(&arg.ty.id) {
64 if let ty::TyRef(_, ty::TypeAndMut { ty, mutbl: MutImmutable }) = ty.sty {
65 if match_type(cx, ty, &VEC_PATH) {
66 span_lint(cx, PTR_ARG, arg.ty.span,
67 "writing `&Vec<_>` instead of `&[_]` involves one more reference \
68 and cannot be used with non-Vec-based slices. Consider changing \
69 the type to `&[...]`");
70 } else if match_type(cx, ty, &STRING_PATH) {
71 span_lint(cx, PTR_ARG, arg.ty.span,
72 "writing `&String` instead of `&str` involves a new object \
73 where a slice will do. Consider changing the type to `&str`");