Skip to content

Commit 91b9b9c

Browse files
committed
Refactor and complete spanless_eq for AST nods.
1 parent dfabba0 commit 91b9b9c

File tree

6 files changed

+1842
-978
lines changed

6 files changed

+1842
-978
lines changed

clippy_lints/src/operators/eq_op.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use clippy_utils::ast_utils::is_useless_with_eq_exprs;
1+
use clippy_utils::ast::is_useless_with_eq_exprs;
22
use clippy_utils::diagnostics::{span_lint, span_lint_and_then};
33
use clippy_utils::macros::{find_assert_eq_args, first_node_macro_backtrace};
44
use clippy_utils::{eq_expr_value, is_in_test_function, sym};

clippy_lints/src/suspicious_operation_groupings.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use clippy_utils::ast_utils::{IdentIter, is_useless_with_eq_exprs};
1+
use clippy_utils::ast::{IdentIter, is_useless_with_eq_exprs};
22
use clippy_utils::diagnostics::span_lint_and_sugg;
33
use clippy_utils::source::snippet_with_applicability;
44
use core::ops::{Add, AddAssign};

clippy_lints/src/unnested_or_patterns.rs

Lines changed: 33 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
#![allow(clippy::wildcard_imports, clippy::enum_glob_use)]
22

33
use clippy_config::Conf;
4-
use clippy_utils::ast_utils::{eq_field_pat, eq_maybe_qself, eq_pat, eq_path};
4+
use clippy_utils::ast::EqCtxt;
55
use clippy_utils::diagnostics::span_lint_and_then;
66
use clippy_utils::msrvs::{self, MsrvStack};
7-
use clippy_utils::over;
87
use rustc_ast::PatKind::*;
98
use rustc_ast::mut_visit::*;
109
use rustc_ast::{self as ast, DUMMY_NODE_ID, Mutability, Pat, PatKind};
@@ -50,12 +49,14 @@ declare_clippy_lint! {
5049

5150
pub struct UnnestedOrPatterns {
5251
msrv: MsrvStack,
52+
eq_ctxt: EqCtxt,
5353
}
5454

5555
impl UnnestedOrPatterns {
5656
pub fn new(conf: &'static Conf) -> Self {
5757
Self {
5858
msrv: MsrvStack::new(conf.msrv),
59+
eq_ctxt: EqCtxt::default(),
5960
}
6061
}
6162
}
@@ -65,34 +66,34 @@ impl_lint_pass!(UnnestedOrPatterns => [UNNESTED_OR_PATTERNS]);
6566
impl EarlyLintPass for UnnestedOrPatterns {
6667
fn check_arm(&mut self, cx: &EarlyContext<'_>, a: &ast::Arm) {
6768
if self.msrv.meets(msrvs::OR_PATTERNS) {
68-
lint_unnested_or_patterns(cx, &a.pat);
69+
lint_unnested_or_patterns(cx, &a.pat, &mut self.eq_ctxt);
6970
}
7071
}
7172

7273
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
7374
if self.msrv.meets(msrvs::OR_PATTERNS)
7475
&& let ast::ExprKind::Let(pat, _, _, _) = &e.kind
7576
{
76-
lint_unnested_or_patterns(cx, pat);
77+
lint_unnested_or_patterns(cx, pat, &mut self.eq_ctxt);
7778
}
7879
}
7980

8081
fn check_param(&mut self, cx: &EarlyContext<'_>, p: &ast::Param) {
8182
if self.msrv.meets(msrvs::OR_PATTERNS) {
82-
lint_unnested_or_patterns(cx, &p.pat);
83+
lint_unnested_or_patterns(cx, &p.pat, &mut self.eq_ctxt);
8384
}
8485
}
8586

8687
fn check_local(&mut self, cx: &EarlyContext<'_>, l: &ast::Local) {
8788
if self.msrv.meets(msrvs::OR_PATTERNS) {
88-
lint_unnested_or_patterns(cx, &l.pat);
89+
lint_unnested_or_patterns(cx, &l.pat, &mut self.eq_ctxt);
8990
}
9091
}
9192

9293
extract_msrv_attr!();
9394
}
9495

95-
fn lint_unnested_or_patterns(cx: &EarlyContext<'_>, pat: &Pat) {
96+
fn lint_unnested_or_patterns(cx: &EarlyContext<'_>, pat: &Pat, eq_ctxt: &mut EqCtxt) {
9697
if let Ident(.., None) | Expr(_) | Wild | Path(..) | Range(..) | Rest | MacCall(_) = pat.kind {
9798
// This is a leaf pattern, so cloning is unprofitable.
9899
return;
@@ -104,7 +105,7 @@ fn lint_unnested_or_patterns(cx: &EarlyContext<'_>, pat: &Pat) {
104105
remove_all_parens(&mut pat);
105106

106107
// Transform all unnested or-patterns into nested ones, and if there were none, quit.
107-
if !unnest_or_patterns(&mut pat) {
108+
if !unnest_or_patterns(&mut pat, eq_ctxt) {
108109
return;
109110
}
110111

@@ -163,11 +164,12 @@ fn insert_necessary_parens(pat: &mut Box<Pat>) {
163164

164165
/// Unnest or-patterns `p0 | ... | p1` in the pattern `pat`.
165166
/// For example, this would transform `Some(0) | FOO | Some(2)` into `Some(0 | 2) | FOO`.
166-
fn unnest_or_patterns(pat: &mut Box<Pat>) -> bool {
167-
struct Visitor {
167+
fn unnest_or_patterns(pat: &mut Box<Pat>, eq_ctxt: &mut EqCtxt) -> bool {
168+
struct Visitor<'a> {
168169
changed: bool,
170+
eq_ctxt: &'a mut EqCtxt,
169171
}
170-
impl MutVisitor for Visitor {
172+
impl MutVisitor for Visitor<'_> {
171173
fn visit_pat(&mut self, p: &mut Pat) {
172174
// This is a bottom up transformation, so recurse first.
173175
walk_pat(self, p);
@@ -192,7 +194,7 @@ fn unnest_or_patterns(pat: &mut Box<Pat>) -> bool {
192194
// Focus on `p_n` and then try to transform all `p_i` where `i > n`.
193195
let mut focus_idx = 0;
194196
while focus_idx < alternatives.len() {
195-
this_level_changed |= transform_with_focus_on_idx(alternatives, focus_idx);
197+
this_level_changed |= transform_with_focus_on_idx(alternatives, focus_idx, self.eq_ctxt);
196198
focus_idx += 1;
197199
}
198200
self.changed |= this_level_changed;
@@ -204,7 +206,10 @@ fn unnest_or_patterns(pat: &mut Box<Pat>) -> bool {
204206
}
205207
}
206208

207-
let mut visitor = Visitor { changed: false };
209+
let mut visitor = Visitor {
210+
changed: false,
211+
eq_ctxt,
212+
};
208213
visitor.visit_pat(pat);
209214
visitor.changed
210215
}
@@ -223,7 +228,7 @@ macro_rules! always_pat {
223228
/// Focus on `focus_idx` in `alternatives`,
224229
/// attempting to extend it with elements of the same constructor `C`
225230
/// in `alternatives[focus_idx + 1..]`.
226-
fn transform_with_focus_on_idx(alternatives: &mut ThinVec<Box<Pat>>, focus_idx: usize) -> bool {
231+
fn transform_with_focus_on_idx(alternatives: &mut ThinVec<Box<Pat>>, focus_idx: usize, eq_cx: &mut EqCtxt) -> bool {
227232
// Extract the kind; we'll need to make some changes in it.
228233
let mut focus_kind = mem::replace(&mut alternatives[focus_idx].kind, Wild);
229234
// We'll focus on `alternatives[focus_idx]`,
@@ -269,13 +274,13 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<Box<Pat>>, focus_idx:
269274
// Transform `[pre, x, post] | ... | [pre, y, post]` into `[pre, x | y, post]`.
270275
Slice(ps1) => extend_with_matching_product(
271276
ps1, start, alternatives,
272-
|k, ps1, idx| matches!(k, Slice(ps2) if eq_pre_post(ps1, ps2, idx)),
277+
|k, ps1, idx| matches!(k, Slice(ps2) if eq_pre_post(ps1, ps2, idx, eq_cx)),
273278
|k| always_pat!(k, Slice(ps) => ps),
274279
),
275280
// Transform `(pre, x, post) | ... | (pre, y, post)` into `(pre, x | y, post)`.
276281
Tuple(ps1) => extend_with_matching_product(
277282
ps1, start, alternatives,
278-
|k, ps1, idx| matches!(k, Tuple(ps2) if eq_pre_post(ps1, ps2, idx)),
283+
|k, ps1, idx| matches!(k, Tuple(ps2) if eq_pre_post(ps1, ps2, idx, eq_cx)),
279284
|k| always_pat!(k, Tuple(ps) => ps),
280285
),
281286
// Transform `S(pre, x, post) | ... | S(pre, y, post)` into `S(pre, x | y, post)`.
@@ -284,14 +289,14 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<Box<Pat>>, focus_idx:
284289
|k, ps1, idx| matches!(
285290
k,
286291
TupleStruct(qself2, path2, ps2)
287-
if eq_maybe_qself(qself1.as_deref(), qself2.as_deref())
288-
&& eq_path(path1, path2) && eq_pre_post(ps1, ps2, idx)
292+
if eq_cx.eq(qself1, qself2)
293+
&& eq_cx.eq(path1, path2) && eq_pre_post(ps1, ps2, idx, eq_cx)
289294
),
290295
|k| always_pat!(k, TupleStruct(_, _, ps) => ps),
291296
),
292297
// Transform a record pattern `S { fp_0, ..., fp_n }`.
293298
Struct(qself1, path1, fps1, rest1) => {
294-
extend_with_struct_pat(qself1.as_deref(), path1, fps1, *rest1, start, alternatives)
299+
extend_with_struct_pat(qself1.as_deref(), path1, fps1, *rest1, start, alternatives, eq_cx)
295300
},
296301
};
297302

@@ -310,6 +315,7 @@ fn extend_with_struct_pat(
310315
rest1: ast::PatFieldsRest,
311316
start: usize,
312317
alternatives: &mut ThinVec<Box<Pat>>,
318+
eq_cx: &mut EqCtxt,
313319
) -> bool {
314320
(0..fps1.len()).any(|idx| {
315321
let pos_in_2 = Cell::new(None); // The element `k`.
@@ -319,8 +325,8 @@ fn extend_with_struct_pat(
319325
|k| {
320326
matches!(k, Struct(qself2, path2, fps2, rest2)
321327
if rest1 == *rest2 // If one struct pattern has `..` so must the other.
322-
&& eq_maybe_qself(qself1, qself2.as_deref())
323-
&& eq_path(path1, path2)
328+
&& eq_cx.eq(&qself1, &qself2.as_deref())
329+
&& eq_cx.eq(path1, path2)
324330
&& fps1.len() == fps2.len()
325331
&& fps1.iter().enumerate().all(|(idx_1, fp1)| {
326332
if idx_1 == idx {
@@ -334,7 +340,7 @@ fn extend_with_struct_pat(
334340
pos_in_2.set(pos);
335341
pos.is_some()
336342
} else {
337-
fps2.iter().any(|fp2| eq_field_pat(fp1, fp2))
343+
fps2.iter().any(|fp2| eq_cx.eq(fp1, fp2))
338344
}
339345
}))
340346
},
@@ -354,7 +360,7 @@ fn extend_with_matching_product(
354360
targets: &mut [Box<Pat>],
355361
start: usize,
356362
alternatives: &mut ThinVec<Box<Pat>>,
357-
predicate: impl Fn(&PatKind, &[Box<Pat>], usize) -> bool,
363+
mut predicate: impl FnMut(&PatKind, &[Box<Pat>], usize) -> bool,
358364
extract: impl Fn(PatKind) -> ThinVec<Box<Pat>>,
359365
) -> bool {
360366
(0..targets.len()).any(|idx| {
@@ -409,7 +415,7 @@ fn extend_with_tail_or(target: &mut Pat, tail_or: ThinVec<Box<Pat>>) -> bool {
409415
fn drain_matching(
410416
start: usize,
411417
alternatives: &mut ThinVec<Box<Pat>>,
412-
predicate: impl Fn(&PatKind) -> bool,
418+
mut predicate: impl FnMut(&PatKind) -> bool,
413419
extract: impl Fn(PatKind) -> Box<Pat>,
414420
) -> ThinVec<Box<Pat>> {
415421
let mut tail_or = ThinVec::new();
@@ -451,9 +457,9 @@ fn extend_with_matching(
451457
}
452458

453459
/// Are the patterns in `ps1` and `ps2` equal save for `ps1[idx]` compared to `ps2[idx]`?
454-
fn eq_pre_post(ps1: &[Box<Pat>], ps2: &[Box<Pat>], idx: usize) -> bool {
460+
fn eq_pre_post(ps1: &[Box<Pat>], ps2: &[Box<Pat>], idx: usize, eq_cx: &mut EqCtxt) -> bool {
455461
ps1.len() == ps2.len()
456462
&& ps1[idx].is_rest() == ps2[idx].is_rest() // Avoid `[x, ..] | [x, 0]` => `[x, .. | 0]`.
457-
&& over(&ps1[..idx], &ps2[..idx], |l, r| eq_pat(l, r))
458-
&& over(&ps1[idx + 1..], &ps2[idx + 1..], |l, r| eq_pat(l, r))
463+
&& eq_cx.eq(&ps1[..idx], &ps2[..idx])
464+
&& eq_cx.eq(&ps1[idx + 1..], &ps2[idx + 1..])
459465
}

0 commit comments

Comments
 (0)