Skip to content

Commit 149f0c5

Browse files
committed
impl
1 parent 81f8ecc commit 149f0c5

File tree

2 files changed

+30
-19
lines changed

2 files changed

+30
-19
lines changed

clippy_lints/src/absolute_paths.rs

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -64,24 +64,37 @@ impl<'tcx> LateLintPass<'tcx> for AbsolutePaths {
6464
// we don't need to use a visitor or anything as we can just check if the `Node` for `hir_id` isn't
6565
// a `Use`
6666
fn check_path(&mut self, cx: &LateContext<'tcx>, path: &Path<'tcx>, hir_id: HirId) {
67-
let (first, len) = match path.segments {
68-
// Any path starting with `::` must have the second segment refer to an external crate.
69-
// Make sure not to include the `::` segment when counting the segments.
70-
[root, first, ..] if root.ident.name == kw::PathRoot => (first, path.segments.len() - 1),
71-
[first, _, ..]
72-
if first.ident.name == kw::Crate
73-
|| matches!(first.res, Res::Def(DefKind::Mod, DefId { index, .. }) if index == CRATE_DEF_INDEX) =>
67+
let segments = match path.segments {
68+
[] | [_] => return,
69+
// Don't count enum variants and trait items as part of the length.
70+
[rest @ .., _]
71+
if let [.., s] = rest
72+
&& matches!(s.res, Res::Def(DefKind::Enum | DefKind::Trait | DefKind::TraitAlias, _)) =>
7473
{
75-
(first, path.segments.len())
74+
rest
7675
},
77-
_ => return,
76+
path => path,
7877
};
79-
80-
if len as u64 > self.absolute_paths_max_segments
78+
if let [s1, s2, ..] = segments
79+
&& let has_root = s1.ident.name == kw::PathRoot
80+
&& let first = if has_root { s2 } else { s1 }
81+
&& let len = segments.len() - usize::from(has_root)
82+
&& len as u64 > self.absolute_paths_max_segments
83+
&& let crate_name = if let Res::Def(DefKind::Mod, DefId { index, .. }) = first.res
84+
&& index == CRATE_DEF_INDEX
85+
{
86+
// `other_crate::foo` or `::other_crate::foo`
87+
first.ident.name
88+
} else if first.ident.name == kw::Crate || has_root {
89+
// `::foo` or `crate::foo`
90+
kw::Crate
91+
} else {
92+
return;
93+
}
8194
&& !path.span.from_expansion()
8295
&& let node = cx.tcx.hir_node(hir_id)
8396
&& !matches!(node, Node::Item(item) if matches!(item.kind, ItemKind::Use(..)))
84-
&& !self.absolute_paths_allowed_crates.contains(&first.ident.name)
97+
&& !self.absolute_paths_allowed_crates.contains(&crate_name)
8598
&& !is_from_proc_macro(cx, path)
8699
{
87100
span_lint(

clippy_utils/src/check_proc_macro.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -123,16 +123,14 @@ fn qpath_search_pat(path: &QPath<'_>) -> (Pat, Pat) {
123123

124124
fn path_search_pat(path: &Path<'_>) -> (Pat, Pat) {
125125
let (head, tail) = match path.segments {
126-
[head, .., tail] => (head, tail),
127-
[p] => (p, p),
128126
[] => return (Pat::Str(""), Pat::Str("")),
127+
[p] => (Pat::Sym(p.ident.name), p),
128+
// QPath::Resolved can have a path that looks like `<Foo as Bar>::baz` where
129+
// the path (`Bar::baz`) has it's span covering the whole QPath.
130+
[.., tail] => (Pat::Str(""), tail),
129131
};
130132
(
131-
if head.ident.name == kw::PathRoot {
132-
Pat::Str("::")
133-
} else {
134-
Pat::Sym(head.ident.name)
135-
},
133+
head,
136134
if tail.args.is_some() {
137135
Pat::Str(">")
138136
} else {

0 commit comments

Comments
 (0)