a437936d49
Also remove the "use xxx;" blocks to ensure import paths don't change. They don't work anyway since stuff may still be re-exported at the old location, while we need the "canonical" location for the type checks. Plus, the test suite catches all these cases.
69 lines
2.1 KiB
Rust
69 lines
2.1 KiB
Rust
//! Checks for usage of &Vec[_] and &String
|
|
//!
|
|
//! This lint is **warn** by default
|
|
|
|
use rustc::lint::*;
|
|
use syntax::ast::*;
|
|
use rustc::middle::ty;
|
|
|
|
use utils::{span_lint, match_def_path};
|
|
use utils::{STRING_PATH, VEC_PATH};
|
|
|
|
declare_lint! {
|
|
pub PTR_ARG,
|
|
Allow,
|
|
"fn arguments of the type `&Vec<...>` or `&String`, suggesting to use `&[...]` or `&str` \
|
|
instead, respectively"
|
|
}
|
|
|
|
#[derive(Copy,Clone)]
|
|
pub struct PtrArg;
|
|
|
|
impl LintPass for PtrArg {
|
|
fn get_lints(&self) -> LintArray {
|
|
lint_array!(PTR_ARG)
|
|
}
|
|
|
|
fn check_item(&mut self, cx: &Context, item: &Item) {
|
|
if let &ItemFn(ref decl, _, _, _, _, _) = &item.node {
|
|
check_fn(cx, decl);
|
|
}
|
|
}
|
|
|
|
fn check_impl_item(&mut self, cx: &Context, item: &ImplItem) {
|
|
if let &MethodImplItem(ref sig, _) = &item.node {
|
|
check_fn(cx, &sig.decl);
|
|
}
|
|
}
|
|
|
|
fn check_trait_item(&mut self, cx: &Context, item: &TraitItem) {
|
|
if let &MethodTraitItem(ref sig, _) = &item.node {
|
|
check_fn(cx, &sig.decl);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn check_fn(cx: &Context, decl: &FnDecl) {
|
|
for arg in &decl.inputs {
|
|
if arg.ty.node == TyInfer { // "self" arguments
|
|
continue;
|
|
}
|
|
let ref sty = cx.tcx.pat_ty(&*arg.pat).sty;
|
|
if let &ty::TyRef(_, ty::TypeAndMut { ty, mutbl: MutImmutable }) = sty {
|
|
if let ty::TyStruct(did, _) = ty.sty {
|
|
if match_def_path(cx, did.did, &VEC_PATH) {
|
|
span_lint(cx, PTR_ARG, arg.ty.span,
|
|
"writing `&Vec<_>` instead of `&[_]` involves one more reference \
|
|
and cannot be used with non-Vec-based slices. Consider changing \
|
|
the type to `&[...]`");
|
|
}
|
|
else if match_def_path(cx, did.did, &STRING_PATH) {
|
|
span_lint(cx, PTR_ARG, arg.ty.span,
|
|
"writing `&String` instead of `&str` involves a new object \
|
|
where a slice will do. Consider changing the type to `&str`");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|