Skip to content

Commit 611b74e

Browse files
committed
Add support for using qualified paths with structs in expression and pattern
position.
1 parent 626dc59 commit 611b74e

File tree

5 files changed

+25
-14
lines changed

5 files changed

+25
-14
lines changed

clippy_lints/src/misc_early/unneeded_field_pattern.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use rustc_lint::{EarlyContext, LintContext};
55
use super::UNNEEDED_FIELD_PATTERN;
66

77
pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
8-
if let PatKind::Struct(ref npat, ref pfields, _) = pat.kind {
8+
if let PatKind::Struct(_, ref npat, ref pfields, _) = pat.kind {
99
let mut wilds = 0;
1010
let type_name = npat
1111
.segments

clippy_lints/src/misc_early/unneeded_wildcard_pattern.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use rustc_span::source_map::Span;
77
use super::UNNEEDED_WILDCARD_PATTERN;
88

99
pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
10-
if let PatKind::TupleStruct(_, ref patterns) | PatKind::Tuple(ref patterns) = pat.kind {
10+
if let PatKind::TupleStruct(_, _, ref patterns) | PatKind::Tuple(ref patterns) = pat.kind {
1111
if let Some(rest_index) = patterns.iter().position(|pat| pat.is_rest()) {
1212
if let Some((left_index, left_pat)) = patterns[..rest_index]
1313
.iter()

clippy_lints/src/non_expressive_names.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ impl<'a, 'tcx, 'b> Visitor<'tcx> for SimilarNamesNameVisitor<'a, 'tcx, 'b> {
139139
self.check_ident(ident);
140140
}
141141
},
142-
PatKind::Struct(_, ref fields, _) => {
142+
PatKind::Struct(_, _, ref fields, _) => {
143143
for field in fields {
144144
if !field.is_shorthand {
145145
self.visit_pat(&field.pat);

clippy_lints/src/unnested_or_patterns.rs

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

3-
use clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_pat, eq_path};
3+
use clippy_utils::ast_utils::{eq_field_pat, eq_id, eq_pat, eq_path, eq_maybe_qself};
44
use clippy_utils::diagnostics::span_lint_and_then;
55
use clippy_utils::{meets_msrv, msrvs, over};
66
use rustc_ast::mut_visit::*;
@@ -273,16 +273,16 @@ fn transform_with_focus_on_idx(alternatives: &mut Vec<P<Pat>>, focus_idx: usize)
273273
|k| always_pat!(k, Tuple(ps) => ps),
274274
),
275275
// Transform `S(pre, x, post) | ... | S(pre, y, post)` into `S(pre, x | y, post)`.
276-
TupleStruct(path1, ps1) => extend_with_matching_product(
276+
TupleStruct(qself1, path1, ps1) => extend_with_matching_product(
277277
ps1, start, alternatives,
278278
|k, ps1, idx| matches!(
279279
k,
280-
TupleStruct(path2, ps2) if eq_path(path1, path2) && eq_pre_post(ps1, ps2, idx)
280+
TupleStruct(qself2, path2, ps2) if eq_maybe_qself(qself1, qself2) && eq_path(path1, path2) && eq_pre_post(ps1, ps2, idx)
281281
),
282-
|k| always_pat!(k, TupleStruct(_, ps) => ps),
282+
|k| always_pat!(k, TupleStruct(_, _, ps) => ps),
283283
),
284284
// Transform a record pattern `S { fp_0, ..., fp_n }`.
285-
Struct(path1, fps1, rest1) => extend_with_struct_pat(path1, fps1, *rest1, start, alternatives),
285+
Struct(qself1, path1, fps1, rest1) => extend_with_struct_pat(qself1, path1, fps1, *rest1, start, alternatives),
286286
};
287287

288288
alternatives[focus_idx].kind = focus_kind;
@@ -294,6 +294,7 @@ fn transform_with_focus_on_idx(alternatives: &mut Vec<P<Pat>>, focus_idx: usize)
294294
/// So when we fixate on some `ident_k: pat_k`, we try to find `ident_k` in the other pattern
295295
/// and check that all `fp_i` where `i ∈ ((0...n) \ k)` between two patterns are equal.
296296
fn extend_with_struct_pat(
297+
qself1: &Option<ast::QSelf>,
297298
path1: &ast::Path,
298299
fps1: &mut Vec<ast::PatField>,
299300
rest1: bool,
@@ -306,8 +307,9 @@ fn extend_with_struct_pat(
306307
start,
307308
alternatives,
308309
|k| {
309-
matches!(k, Struct(path2, fps2, rest2)
310+
matches!(k, Struct(qself2, path2, fps2, rest2)
310311
if rest1 == *rest2 // If one struct pattern has `..` so must the other.
312+
&& eq_maybe_qself(qself1, qself2)
311313
&& eq_path(path1, path2)
312314
&& fps1.len() == fps2.len()
313315
&& fps1.iter().enumerate().all(|(idx_1, fp1)| {
@@ -323,7 +325,7 @@ fn extend_with_struct_pat(
323325
}))
324326
},
325327
// Extract `p2_k`.
326-
|k| always_pat!(k, Struct(_, mut fps, _) => fps.swap_remove(pos_in_2.take().unwrap()).pat),
328+
|k| always_pat!(k, Struct(_, _, mut fps, _) => fps.swap_remove(pos_in_2.take().unwrap()).pat),
327329
);
328330
extend_with_tail_or(&mut fps1[idx].pat, tail_or)
329331
})

clippy_utils/src/ast_utils.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@ pub fn eq_pat(l: &Pat, r: &Pat) -> bool {
4747
| (Ref(l, Mutability::Mut), Ref(r, Mutability::Mut)) => eq_pat(l, r),
4848
(Tuple(l), Tuple(r)) | (Slice(l), Slice(r)) => over(l, r, |l, r| eq_pat(l, r)),
4949
(Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp),
50-
(TupleStruct(lp, lfs), TupleStruct(rp, rfs)) => eq_path(lp, rp) && over(lfs, rfs, |l, r| eq_pat(l, r)),
51-
(Struct(lp, lfs, lr), Struct(rp, rfs, rr)) => {
52-
lr == rr && eq_path(lp, rp) && unordered_over(lfs, rfs, |lf, rf| eq_field_pat(lf, rf))
50+
(TupleStruct(lqself, lp, lfs), TupleStruct(rqself, rp, rfs)) => eq_maybe_qself(lqself, rqself) && eq_path(lp, rp) && over(lfs, rfs, |l, r| eq_pat(l, r)),
51+
(Struct(lqself, lp, lfs, lr), Struct(rqself, rp, rfs, rr)) => {
52+
lr == rr && eq_maybe_qself(lqself, rqself) &&eq_path(lp, rp) && unordered_over(lfs, rfs, |lf, rf| eq_field_pat(lf, rf))
5353
},
5454
(Or(ls), Or(rs)) => unordered_over(ls, rs, |l, r| eq_pat(l, r)),
5555
(MacCall(l), MacCall(r)) => eq_mac_call(l, r),
@@ -78,6 +78,14 @@ pub fn eq_qself(l: &QSelf, r: &QSelf) -> bool {
7878
l.position == r.position && eq_ty(&l.ty, &r.ty)
7979
}
8080

81+
pub fn eq_maybe_qself(l: &Option<QSelf>, r: &Option<QSelf>) -> bool {
82+
match (l, r) {
83+
(Some(l), Some(r)) => eq_qself(l, r),
84+
(None, None) => true,
85+
_ => false
86+
}
87+
}
88+
8189
pub fn eq_path(l: &Path, r: &Path) -> bool {
8290
over(&l.segments, &r.segments, |l, r| eq_path_seg(l, r))
8391
}
@@ -170,7 +178,8 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
170178
(Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp),
171179
(MacCall(l), MacCall(r)) => eq_mac_call(l, r),
172180
(Struct(lse), Struct(rse)) => {
173-
eq_path(&lse.path, &rse.path)
181+
eq_maybe_qself(&lse.qself, &rse.qself)
182+
&& eq_path(&lse.path, &rse.path)
174183
&& eq_struct_rest(&lse.rest, &rse.rest)
175184
&& unordered_over(&lse.fields, &rse.fields, |l, r| eq_field(l, r))
176185
},

0 commit comments

Comments
 (0)