Skip to content

Commit ecb2f4a

Browse files
committed
update dbg! clippy lint
1 parent 039e1c0 commit ecb2f4a

File tree

1 file changed

+52
-28
lines changed

1 file changed

+52
-28
lines changed

src/tools/clippy/clippy_lints/src/dbg_macro.rs

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use clippy_utils::macros::{MacroCall, macro_backtrace};
55
use clippy_utils::source::snippet_with_applicability;
66
use rustc_data_structures::fx::FxHashSet;
77
use rustc_errors::Applicability;
8-
use rustc_hir::{Closure, ClosureKind, CoroutineKind, Expr, ExprKind, LetStmt, LocalSource, Node, Stmt, StmtKind};
8+
use rustc_hir::{Arm, Closure, ClosureKind, CoroutineKind, Expr, ExprKind, LetStmt, LocalSource, Node, Stmt, StmtKind};
99
use rustc_lint::{LateContext, LateLintPass, LintContext};
1010
use rustc_session::impl_lint_pass;
1111
use rustc_span::{Span, SyntaxContext, sym};
@@ -90,33 +90,27 @@ impl LateLintPass<'_> for DbgMacro {
9090
(macro_call.span, String::from("()"))
9191
}
9292
},
93-
// dbg!(1)
94-
ExprKind::Match(val, ..) => (
95-
macro_call.span,
96-
snippet_with_applicability(cx, val.span.source_callsite(), "..", &mut applicability)
97-
.to_string(),
98-
),
99-
// dbg!(2, 3)
100-
ExprKind::Tup(
101-
[
102-
Expr {
103-
kind: ExprKind::Match(first, ..),
104-
..
105-
},
106-
..,
107-
Expr {
108-
kind: ExprKind::Match(last, ..),
109-
..
110-
},
111-
],
112-
) => {
113-
let snippet = snippet_with_applicability(
114-
cx,
115-
first.span.source_callsite().to(last.span.source_callsite()),
116-
"..",
117-
&mut applicability,
118-
);
119-
(macro_call.span, format!("({snippet})"))
93+
ExprKind::Match(first, arms, _) => {
94+
let vals = collect_vals(first, arms);
95+
let suggestion = match vals.as_slice() {
96+
// dbg!(1) => 1
97+
&[val] => {
98+
snippet_with_applicability(cx, val.span.source_callsite(), "..", &mut applicability)
99+
.to_string()
100+
}
101+
// dbg!(2, 3) => (2, 3)
102+
&[first, .., last] => {
103+
let snippet = snippet_with_applicability(
104+
cx,
105+
first.span.source_callsite().to(last.span.source_callsite()),
106+
"..",
107+
&mut applicability,
108+
);
109+
format!("({snippet})")
110+
}
111+
_ => unreachable!(),
112+
};
113+
(macro_call.span, suggestion)
120114
},
121115
_ => unreachable!(),
122116
};
@@ -169,3 +163,33 @@ fn is_async_move_desugar<'tcx>(expr: &'tcx Expr<'tcx>) -> Option<&'tcx Expr<'tcx
169163
fn first_dbg_macro_in_expansion(cx: &LateContext<'_>, span: Span) -> Option<MacroCall> {
170164
macro_backtrace(span).find(|mc| cx.tcx.is_diagnostic_item(sym::dbg_macro, mc.def_id))
171165
}
166+
167+
/// Extracts all value expressions from the `match`-tree generated by `dbg!`.
168+
///
169+
/// E.g. from
170+
/// ```rust, ignore
171+
/// match 1 {
172+
/// tmp_1 => match 2 {
173+
/// tmp_2 => {
174+
/// /* printing */
175+
/// (tmp_1, tmp_2)
176+
/// }
177+
/// }
178+
/// }
179+
/// ```
180+
/// this extracts `1` and `2`.
181+
fn collect_vals<'hir>(first: &'hir Expr<'hir>, mut arms: &'hir [Arm<'hir>]) -> Vec<&'hir Expr<'hir>> {
182+
let mut vals = vec![first];
183+
loop {
184+
let [arm] = arms else { unreachable!("dbg! macro expansion only has single-arm matches") };
185+
186+
match is_async_move_desugar(arm.body).unwrap_or(arm.body).peel_drop_temps().kind {
187+
ExprKind::Block(..) => return vals,
188+
ExprKind::Match(val, a, _) => {
189+
vals.push(val);
190+
arms = a;
191+
}
192+
_ => unreachable!("dbg! macro expansion only results in block or match expressions"),
193+
}
194+
}
195+
}

0 commit comments

Comments
 (0)