plugins: Add seanmonstar's to_string() lint

This commit is contained in:
Manish Goregaokar 2014-12-13 04:30:03 +05:30 committed by Ms2ger
parent b6117a57aa
commit 0410d3d9b2
2 changed files with 39 additions and 0 deletions

View file

@ -48,6 +48,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
reg.register_lint_pass(box lints::UnrootedPass as LintPassObject); reg.register_lint_pass(box lints::UnrootedPass as LintPassObject);
reg.register_lint_pass(box lints::PrivatizePass as LintPassObject); reg.register_lint_pass(box lints::PrivatizePass as LintPassObject);
reg.register_lint_pass(box lints::InheritancePass as LintPassObject); reg.register_lint_pass(box lints::InheritancePass as LintPassObject);
reg.register_lint_pass(box lints::StrToStringPass as LintPassObject);
} }

View file

@ -21,6 +21,8 @@ declare_lint!(PRIVATIZE, Deny,
"Allows to enforce private fields for struct definitions") "Allows to enforce private fields for struct definitions")
declare_lint!(INHERITANCE_INTEGRITY, Deny, declare_lint!(INHERITANCE_INTEGRITY, Deny,
"Ensures that struct fields are properly laid out for inheritance to work") "Ensures that struct fields are properly laid out for inheritance to work")
declare_lint!(STR_TO_STRING, Deny,
"Warn when a String could use into_string() instead of to_string()")
/// Lint for auditing transmutes /// Lint for auditing transmutes
/// ///
@ -51,6 +53,11 @@ pub struct PrivatizePass;
/// which itself is a DOM struct (in which case it must be the first field). /// which itself is a DOM struct (in which case it must be the first field).
pub struct InheritancePass; pub struct InheritancePass;
/// Prefer str.into_string() over str.to_string()
///
/// The latter creates a `Formatter` and is 5x slower than the former
pub struct StrToStringPass;
impl LintPass for TransmutePass { impl LintPass for TransmutePass {
fn get_lints(&self) -> LintArray { fn get_lints(&self) -> LintArray {
lint_array!(TRANSMUTE_TYPE_LINT) lint_array!(TRANSMUTE_TYPE_LINT)
@ -332,3 +339,34 @@ impl LintPass for InheritancePass {
} }
} }
} }
impl LintPass for StrToStringPass {
fn get_lints(&self) -> LintArray {
lint_array!(STR_TO_STRING)
}
fn check_expr(&mut self, cx: &Context, expr: &ast::Expr) {
match expr.node {
ast::ExprMethodCall(ref method, _, ref args)
if method.node.as_str() == "to_string"
&& is_str(cx, &*args[0]) => {
cx.span_lint(STR_TO_STRING, expr.span,
"str.into_string() is more efficient than str.to_string(), please use it instead");
},
_ => ()
}
fn is_str(cx: &Context, expr: &ast::Expr) -> bool {
fn walk_ty<'t>(ty: ty::t) -> ty::t {
match ty::get(ty).sty {
ty::ty_ptr(ref tm) | ty::ty_rptr(_, ref tm) => walk_ty(tm.ty),
_ => ty
}
}
match ty::get(walk_ty(expr_ty(cx.tcx, expr))).sty {
ty::ty_str => true,
_ => false
}
}
}
}