From aa7bcb9074f3a7235e43d1da910d80248e53357d Mon Sep 17 00:00:00 2001 From: Philipp Hansch <dev@phansch.net> Date: Sat, 27 Oct 2018 11:01:27 +0200 Subject: [PATCH] Don't expand macro in identity_conversion suggestion --- clippy_lints/src/identity_conversion.rs | 5 +++-- clippy_lints/src/utils/mod.rs | 6 ++++++ tests/ui/identity_conversion.rs | 1 + tests/ui/identity_conversion.stderr | 8 +++++++- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/clippy_lints/src/identity_conversion.rs b/clippy_lints/src/identity_conversion.rs index e9761616696..00ce58f00b0 100644 --- a/clippy_lints/src/identity_conversion.rs +++ b/clippy_lints/src/identity_conversion.rs @@ -12,7 +12,7 @@ use crate::rustc::lint::{LateContext, LateLintPass, LintArray, LintPass}; use crate::rustc::{declare_tool_lint, lint_array}; use crate::rustc::hir::*; use crate::syntax::ast::NodeId; -use crate::utils::{in_macro, match_def_path, match_trait_method, same_tys, snippet, span_lint_and_then}; +use crate::utils::{in_macro, match_def_path, match_trait_method, same_tys, snippet, snippet_with_macro_callsite, span_lint_and_then}; use crate::utils::{opt_def_id, paths, resolve_node}; use crate::rustc_errors::Applicability; @@ -72,7 +72,8 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for IdentityConversion { let a = cx.tables.expr_ty(e); let b = cx.tables.expr_ty(&args[0]); if same_tys(cx, a, b) { - let sugg = snippet(cx, args[0].span, "<expr>").into_owned(); + let sugg = snippet_with_macro_callsite(cx, args[0].span, "<expr>").to_string(); + span_lint_and_then(cx, IDENTITY_CONVERSION, e.span, "identical conversion", |db| { db.span_suggestion_with_applicability( e.span, diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 1a8db837f32..5ff246630e0 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -362,6 +362,12 @@ pub fn snippet<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &'a str) snippet_opt(cx, span).map_or_else(|| Cow::Borrowed(default), From::from) } +/// Same as `snippet`, but should only be used when it's clear that the input span is +/// not a macro argument. +pub fn snippet_with_macro_callsite<'a, 'b, T: LintContext<'b>>(cx: &T, span: Span, default: &'a str) -> Cow<'a, str> { + snippet(cx, span.source_callsite(), default) +} + /// Convert a span to a code snippet. Returns `None` if not available. pub fn snippet_opt<'a, T: LintContext<'a>>(cx: &T, span: Span) -> Option<String> { cx.sess().source_map().span_to_snippet(span).ok() diff --git a/tests/ui/identity_conversion.rs b/tests/ui/identity_conversion.rs index 9384c9eb206..b5cb92c6d5a 100644 --- a/tests/ui/identity_conversion.rs +++ b/tests/ui/identity_conversion.rs @@ -53,4 +53,5 @@ fn main() { let _ = String::from(format!("A: {:04}", 123)); let _ = "".lines().into_iter(); let _ = vec![1, 2, 3].into_iter().into_iter(); + let _: String = format!("Hello {}", "world").into(); } diff --git a/tests/ui/identity_conversion.stderr b/tests/ui/identity_conversion.stderr index 2ac74191931..15bef8b125e 100644 --- a/tests/ui/identity_conversion.stderr +++ b/tests/ui/identity_conversion.stderr @@ -58,5 +58,11 @@ error: identical conversion 55 | let _ = vec![1, 2, 3].into_iter().into_iter(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()` -error: aborting due to 9 previous errors +error: identical conversion + --> $DIR/identity_conversion.rs:56:21 + | +56 | let _: String = format!("Hello {}", "world").into(); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!("Hello {}", "world")` + +error: aborting due to 10 previous errors