about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-06-19 17:54:57 +0000
committerbors <bors@rust-lang.org>2023-06-19 17:54:57 +0000
commitebcbba93ad8ee0edd3e0657989538456547e1cba (patch)
tree3ab901eb47bcffcb45ec63f680a632a729266303
parent06b444b2d10284d9be3db8b702654a74e2d2ac5f (diff)
parent26e78e72bc8d40a8168213620a266d803845e604 (diff)
downloadrust-ebcbba93ad8ee0edd3e0657989538456547e1cba.tar.gz
rust-ebcbba93ad8ee0edd3e0657989538456547e1cba.zip
Auto merge of #10980 - Alexendoo:format-args-incremental-spans, r=dswij
Fix `find_format_arg_expr` when incremental compilation is enabled

Fixes #10969

[`lower_span`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_ast_lowering/struct.LoweringContext.html#method.lower_span) gives AST spans a [parent](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/struct.SpanData.html#structfield.parent) when lowering to the HIR. That meant the `==` span comparison would return false even though the spans are pointing to the same thing. We now ignore the parent when comparing the spans

Debugging this was quite the puzzle, because the parent is not included in the debug output of `Span`s or `SpanData` 😬

changelog: none
-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
+