1 use clippy_utils::diagnostics::span_lint;
2 use rustc_ast::ast::{Expr, ExprKind, Stmt, StmtKind};
3 use rustc_lint::{EarlyContext, EarlyLintPass};
4 use rustc_session::{declare_lint_pass, declare_tool_lint};
8 /// Checks for nested assignments.
10 /// ### Why is this bad?
11 /// While this is in most cases already a type mismatch,
12 /// the result of an assignment being `()` can throw off people coming from languages like python or C,
13 /// where such assignments return a copy of the assigned value.
26 #[clippy::version = "1.65.0"]
27 pub MULTI_ASSIGNMENTS,
29 "instead of using `a = b = c;` use `a = c; b = c;`"
32 declare_lint_pass!(MultiAssignments => [MULTI_ASSIGNMENTS]);
34 fn strip_paren_blocks(expr: &Expr) -> &Expr {
36 ExprKind::Paren(e) => strip_paren_blocks(e),
37 ExprKind::Block(b, _) => {
40 kind: StmtKind::Expr(e),
54 impl EarlyLintPass for MultiAssignments {
55 fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
56 if let ExprKind::Assign(target, source, _) = &expr.kind {
57 if let ExprKind::Assign(_target, _source, _) = &strip_paren_blocks(target).kind {
58 span_lint(cx, MULTI_ASSIGNMENTS, expr.span, "assignments don't nest intuitively");
60 if let ExprKind::Assign(_target, _source, _) = &strip_paren_blocks(source).kind {
61 span_lint(cx, MULTI_ASSIGNMENTS, expr.span, "assignments don't nest intuitively");