aboutsummaryrefslogtreecommitdiffstats
path: root/components/plugins/lints.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/plugins/lints.rs')
-rw-r--r--components/plugins/lints.rs38
1 files changed, 38 insertions, 0 deletions
diff --git a/components/plugins/lints.rs b/components/plugins/lints.rs
index 3cb4cb91e1f..ce744b47150 100644
--- a/components/plugins/lints.rs
+++ b/components/plugins/lints.rs
@@ -21,6 +21,8 @@ declare_lint!(PRIVATIZE, Deny,
"Allows to enforce private fields for struct definitions")
declare_lint!(INHERITANCE_INTEGRITY, Deny,
"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
///
@@ -51,6 +53,11 @@ pub struct PrivatizePass;
/// which itself is a DOM struct (in which case it must be the first field).
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 {
fn get_lints(&self) -> LintArray {
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
+ }
+ }
+ }
+}