@@ -64,24 +64,37 @@ impl<'tcx> LateLintPass<'tcx> for AbsolutePaths {
64
64
// we don't need to use a visitor or anything as we can just check if the `Node` for `hir_id` isn't
65
65
// a `Use`
66
66
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 , _) ) =>
74
73
{
75
- ( first , path . segments . len ( ) )
74
+ rest
76
75
} ,
77
- _ => return ,
76
+ path => path ,
78
77
} ;
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
+ }
81
94
&& !path. span . from_expansion ( )
82
95
&& let node = cx. tcx . hir_node ( hir_id)
83
96
&& !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 )
85
98
&& !is_from_proc_macro ( cx, path)
86
99
{
87
100
span_lint (
0 commit comments