From a24475093954141168d30ef510f20171db4843ac Mon Sep 17 00:00:00 2001 From: llogiq Date: Thu, 9 Jul 2015 17:02:21 +0200 Subject: [PATCH] new 'snippet' utils method, used where applicable --- src/identity_op.rs | 5 +++-- src/misc.rs | 18 +++++++----------- src/utils.rs | 8 ++++++++ 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/identity_op.rs b/src/identity_op.rs index 25697199dc3..9511bcdee8d 100644 --- a/src/identity_op.rs +++ b/src/identity_op.rs @@ -7,6 +7,8 @@ use syntax::ast_util::{is_comparison_binop, binop_to_string}; use syntax::ptr::P; use syntax::codemap::Span; +use utils::snippet; + declare_lint! { pub IDENTITY_OP, Warn, "Warn on identity operations, e.g. '_ + 0'"} @@ -46,10 +48,9 @@ impl LintPass for IdentityOp { fn check(cx: &Context, e: &Expr, m: i8, span: Span, arg: Span) { if have_lit(cx, e, m) { - let map = cx.sess().codemap(); cx.span_lint(IDENTITY_OP, span, &format!( "The operation is ineffective. Consider reducing it to '{}'", - &*map.span_to_snippet(arg).unwrap_or("..".to_string()))); + snippet(cx, arg, ".."))); } } diff --git a/src/misc.rs b/src/misc.rs index 646b6308e4a..ffa16543f25 100644 --- a/src/misc.rs +++ b/src/misc.rs @@ -8,7 +8,7 @@ use rustc::middle::ty; use syntax::codemap::{Span, Spanned}; use types::span_note_and_lint; -use utils::match_path; +use utils::{match_path, snippet}; pub fn walk_ty<'t>(ty: ty::Ty<'t>) -> ty::Ty<'t> { match ty.sty { @@ -43,12 +43,11 @@ impl LintPass for MiscPass { // In some cases, an exhaustive match is preferred to catch situations when // an enum is extended. So we only consider cases where a `_` wildcard is used if arms[1].pats[0].node == PatWild(PatWildSingle) && arms[0].pats.len() == 1 { - let map = cx.sess().codemap(); span_note_and_lint(cx, SINGLE_MATCH, expr.span, "You seem to be trying to use match for destructuring a single type. Did you mean to use `if let`?", &*format!("Try if let {} = {} {{ ... }}", - &*map.span_to_snippet(arms[0].pats[0].span).unwrap_or("..".to_string()), - &*map.span_to_snippet(ex.span).unwrap_or("..".to_string())) + snippet(cx, arms[0].pats[0].span, ".."), + snippet(cx, ex.span, "..")) ); } } @@ -156,11 +155,10 @@ impl LintPass for FloatCmp { if let ExprBinary(ref cmp, ref left, ref right) = expr.node { let op = cmp.node; if (op == BiEq || op == BiNe) && (is_float(cx, left) || is_float(cx, right)) { - let map = cx.sess().codemap(); cx.span_lint(FLOAT_CMP, expr.span, &format!( "{}-Comparison of f32 or f64 detected. You may want to change this to 'abs({} - {}) < epsilon' for some suitable value of epsilon", - binop_to_string(op), &*map.span_to_snippet(left.span).unwrap_or("..".to_string()), - &*map.span_to_snippet(right.span).unwrap_or("..".to_string()))); + binop_to_string(op), snippet(cx, left.span, ".."), + snippet(cx, right.span, ".."))); } } } @@ -246,8 +244,7 @@ fn check_to_owned(cx: &Context, expr: &Expr, other_span: Span) { cx.span_lint(CMP_OWNED, expr.span, &format!( "this creates an owned instance just for comparison. \ Consider using {}.as_slice() to compare without allocation", - cx.sess().codemap().span_to_snippet(other_span).unwrap_or( - "..".to_string()))) + snippet(cx, other_span, ".."))) } }, &ExprCall(ref path, _) => { @@ -257,8 +254,7 @@ fn check_to_owned(cx: &Context, expr: &Expr, other_span: Span) { cx.span_lint(CMP_OWNED, expr.span, &format!( "this creates an owned instance just for comparison. \ Consider using {}.as_slice() to compare without allocation", - cx.sess().codemap().span_to_snippet(other_span).unwrap_or( - "..".to_string()))) + snippet(cx, other_span, ".."))) } } }, diff --git a/src/utils.rs b/src/utils.rs index d754c85f7b5..7d61316367b 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -2,6 +2,8 @@ use rustc::lint::Context; use syntax::ast::{DefId, Name, Path}; use syntax::codemap::{ExpnInfo, Span}; use rustc::middle::ty; +use std::borrow::{Cow, IntoCow}; +use std::convert::From; /// returns true if the macro that expanded the crate was outside of /// the current crate or was a compiler plugin @@ -40,3 +42,9 @@ pub fn match_path(path: &Path, segments: &[&str]) -> bool { path.segments.iter().rev().zip(segments.iter().rev()).all( |(a,b)| a.identifier.as_str() == *b) } + +/// convert a span to a code snippet if available, otherwise use default, e.g. +/// `snippet(cx, expr.span, "..")` +pub fn snippet<'a>(cx: &Context, span: Span, default: &'a str) -> Cow<'a, str> { + cx.sess().codemap().span_to_snippet(span).map(From::from).unwrap_or(Cow::Borrowed(default)) +}