From 2703038f937f169090754c4b19ce7a3ddd457f05 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Mon, 15 Dec 2014 20:23:45 +0530 Subject: [PATCH] Add seanmonstar's StrToString lint --- README.md | 1 + src/lib.rs | 1 + src/misc.rs | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/README.md b/README.md index 0e04459bbd1..91caaeba41a 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ Lints included in this crate: - `clippy_single_match`: Warns when a match statement with a single nontrivial arm (i.e, where the other arm is `_ => {}`) is used, and recommends `if let` instead. - `clippy_box_vec`: Warns on usage of `Box>` - `clippy_dlist`: Warns on usage of `DList` + - `clippy_str_to_string`: Warns on usage of `str::to_string()` More to come, please [file an issue](https://github.com/Manishearth/rust-clippy/issues) if you have ideas! diff --git a/src/lib.rs b/src/lib.rs index 380a530283c..386e8180c22 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,4 +20,5 @@ pub mod misc; pub fn plugin_registrar(reg: &mut Registry) { reg.register_lint_pass(box types::TypePass as LintPassObject); reg.register_lint_pass(box misc::MiscPass as LintPassObject); + reg.register_lint_pass(box misc::StrToStringPass as LintPassObject); } diff --git a/src/misc.rs b/src/misc.rs index c70d4b48c1c..2a77ecc3467 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -2,6 +2,7 @@ use syntax::ptr::P; use syntax::ast; use syntax::ast::*; use rustc::lint::{Context, LintPass, LintArray, Lint, Level}; +use rustc::middle::ty::{mod, expr_ty, ty_str, ty_ptr, ty_rptr}; use syntax::codemap::Span; use types::span_note_and_lint; @@ -44,3 +45,39 @@ impl LintPass for MiscPass { } } } + + +declare_lint!(CLIPPY_STR_TO_STRING, Warn, "Warn when a String could use into_string() instead of to_string()") + +pub struct StrToStringPass; + +impl LintPass for StrToStringPass { + fn get_lints(&self) -> LintArray { + lint_array!(CLIPPY_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(CLIPPY_STR_TO_STRING, expr.span, "str.into_string() is faster"); + }, + _ => () + } + + fn is_str(cx: &Context, expr: &ast::Expr) -> bool { + fn walk_ty<'t>(ty: ty::Ty<'t>) -> ty::Ty<'t> { + //println!("{}: -> {}", depth, ty); + match ty.sty { + ty_ptr(ref tm) | ty_rptr(_, ref tm) => walk_ty(tm.ty), + _ => ty + } + } + match walk_ty(expr_ty(cx.tcx, expr)).sty { + ty_str => true, + _ => false + } + } + } +}