about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Macleod <alex@macleod.io>2023-06-17 20:40:05 +0000
committerAlex Macleod <alex@macleod.io>2023-06-17 20:55:30 +0000
commit26e78e72bc8d40a8168213620a266d803845e604 (patch)
tree27fbe0bc0b7d6f563e82ff628871df6bf55bd533
parent8c8ff5f31d163afbb9ae5e50a82a4e7439e00309 (diff)
downloadrust-26e78e72bc8d40a8168213620a266d803845e604.tar.gz
rust-26e78e72bc8d40a8168213620a266d803845e604.zip
Fix `find_format_arg_expr` when incremental compilation is enabled
-rw-r--r--clippy_utils/src/macros.rs14
-rw-r--r--tests/ui/to_string_in_format_args_incremental.fixed9
-rw-r--r--tests/ui/to_string_in_format_args_incremental.rs9
-rw-r--r--tests/ui/to_string_in_format_args_incremental.stderr10
4 files changed, 40 insertions, 2 deletions
diff --git a/clippy_utils/src/macros.rs b/clippy_utils/src/macros.rs
index e4a4936ff42..00f3abaec8a 100644
--- a/clippy_utils/src/macros.rs
+++ b/clippy_utils/src/macros.rs
@@ -9,7 +9,7 @@ use rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath};
 use rustc_lint::LateContext;
 use rustc_span::def_id::DefId;
 use rustc_span::hygiene::{self, MacroKind, SyntaxContext};
-use rustc_span::{sym, BytePos, ExpnData, ExpnId, ExpnKind, Span, Symbol};
+use rustc_span::{sym, BytePos, ExpnData, ExpnId, ExpnKind, Span, SpanData, Symbol};
 use std::cell::RefCell;
 use std::ops::ControlFlow;
 use std::sync::atomic::{AtomicBool, Ordering};
@@ -415,8 +415,18 @@ pub fn find_format_arg_expr<'hir, 'ast>(
     start: &'hir Expr<'hir>,
     target: &'ast FormatArgument,
 ) -> Result<&'hir rustc_hir::Expr<'hir>, &'ast rustc_ast::Expr> {
+    let SpanData {
+        lo,
+        hi,
+        ctxt,
+        parent: _,
+    } = target.expr.span.data();
+
     for_each_expr(start, |expr| {
-        if expr.span == target.expr.span {
+        // When incremental compilation is enabled spans gain a parent during AST to HIR lowering,
+        // since we're comparing an AST span to a HIR one we need to ignore the parent field
+        let data = expr.span.data();
+        if data.lo == lo && data.hi == hi && data.ctxt == ctxt {
             ControlFlow::Break(expr)
         } else {
             ControlFlow::Continue(())
diff --git a/tests/ui/to_string_in_format_args_incremental.fixed b/tests/ui/to_string_in_format_args_incremental.fixed
new file mode 100644
index 00000000000..9f75ad895cd
--- /dev/null
+++ b/tests/ui/to_string_in_format_args_incremental.fixed
@@ -0,0 +1,9 @@
+//@run-rustfix
+//@compile-flags: -C incremental=target/debug/test/incr
+
+// see https://github.com/rust-lang/rust-clippy/issues/10969
+
+fn main() {
+    let s = "Hello, world!";
+    println!("{}", s);
+}
diff --git a/tests/ui/to_string_in_format_args_incremental.rs b/tests/ui/to_string_in_format_args_incremental.rs
new file mode 100644
index 00000000000..67115f7c5a7
--- /dev/null
+++ b/tests/ui/to_string_in_format_args_incremental.rs
@@ -0,0 +1,9 @@
+//@run-rustfix
+//@compile-flags: -C incremental=target/debug/test/incr
+
+// see https://github.com/rust-lang/rust-clippy/issues/10969
+
+fn main() {
+    let s = "Hello, world!";
+    println!("{}", s.to_string());
+}
diff --git a/tests/ui/to_string_in_format_args_incremental.stderr b/tests/ui/to_string_in_format_args_incremental.stderr
new file mode 100644
index 00000000000..a992c542914
--- /dev/null
+++ b/tests/ui/to_string_in_format_args_incremental.stderr
@@ -0,0 +1,10 @@
+error: `to_string` applied to a type that implements `Display` in `println!` args
+  --> $DIR/to_string_in_format_args_incremental.rs:8:21
+   |
+LL |     println!("{}", s.to_string());
+   |                     ^^^^^^^^^^^^ help: remove this
+   |
+   = note: `-D clippy::to-string-in-format-args` implied by `-D warnings`
+
+error: aborting due to previous error
+