diff options
Diffstat (limited to 'crates/hir_def/src/path.rs')
-rw-r--r-- | crates/hir_def/src/path.rs | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs index 84ea09b53..0e60dc2b6 100644 --- a/crates/hir_def/src/path.rs +++ b/crates/hir_def/src/path.rs | |||
@@ -20,7 +20,7 @@ use crate::{ | |||
20 | #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] | 20 | #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] |
21 | pub struct ModPath { | 21 | pub struct ModPath { |
22 | pub kind: PathKind, | 22 | pub kind: PathKind, |
23 | pub segments: Vec<Name>, | 23 | segments: Vec<Name>, |
24 | } | 24 | } |
25 | 25 | ||
26 | #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] | 26 | #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] |
@@ -53,6 +53,11 @@ impl ModPath { | |||
53 | ModPath { kind, segments } | 53 | ModPath { kind, segments } |
54 | } | 54 | } |
55 | 55 | ||
56 | /// Creates a `ModPath` from a `PathKind`, with no extra path segments. | ||
57 | pub const fn from_kind(kind: PathKind) -> ModPath { | ||
58 | ModPath { kind, segments: Vec::new() } | ||
59 | } | ||
60 | |||
56 | /// Calls `cb` with all paths, represented by this use item. | 61 | /// Calls `cb` with all paths, represented by this use item. |
57 | pub(crate) fn expand_use_item( | 62 | pub(crate) fn expand_use_item( |
58 | item_src: InFile<ast::Use>, | 63 | item_src: InFile<ast::Use>, |
@@ -64,6 +69,18 @@ impl ModPath { | |||
64 | } | 69 | } |
65 | } | 70 | } |
66 | 71 | ||
72 | pub fn segments(&self) -> &[Name] { | ||
73 | &self.segments | ||
74 | } | ||
75 | |||
76 | pub fn push_segment(&mut self, segment: Name) { | ||
77 | self.segments.push(segment); | ||
78 | } | ||
79 | |||
80 | pub fn pop_segment(&mut self) -> Option<Name> { | ||
81 | self.segments.pop() | ||
82 | } | ||
83 | |||
67 | /// Returns the number of segments in the path (counting special segments like `$crate` and | 84 | /// Returns the number of segments in the path (counting special segments like `$crate` and |
68 | /// `super`). | 85 | /// `super`). |
69 | pub fn len(&self) -> usize { | 86 | pub fn len(&self) -> usize { |
@@ -78,7 +95,7 @@ impl ModPath { | |||
78 | } | 95 | } |
79 | 96 | ||
80 | pub fn is_ident(&self) -> bool { | 97 | pub fn is_ident(&self) -> bool { |
81 | self.kind == PathKind::Plain && self.segments.len() == 1 | 98 | self.as_ident().is_some() |
82 | } | 99 | } |
83 | 100 | ||
84 | pub fn is_self(&self) -> bool { | 101 | pub fn is_self(&self) -> bool { |
@@ -87,10 +104,14 @@ impl ModPath { | |||
87 | 104 | ||
88 | /// If this path is a single identifier, like `foo`, return its name. | 105 | /// If this path is a single identifier, like `foo`, return its name. |
89 | pub fn as_ident(&self) -> Option<&Name> { | 106 | pub fn as_ident(&self) -> Option<&Name> { |
90 | if !self.is_ident() { | 107 | if self.kind != PathKind::Plain { |
91 | return None; | 108 | return None; |
92 | } | 109 | } |
93 | self.segments.first() | 110 | |
111 | match &*self.segments { | ||
112 | [name] => Some(name), | ||
113 | _ => None, | ||
114 | } | ||
94 | } | 115 | } |
95 | } | 116 | } |
96 | 117 | ||
@@ -180,10 +201,10 @@ impl Path { | |||
180 | } | 201 | } |
181 | let res = Path { | 202 | let res = Path { |
182 | type_anchor: self.type_anchor.clone(), | 203 | type_anchor: self.type_anchor.clone(), |
183 | mod_path: ModPath { | 204 | mod_path: ModPath::from_segments( |
184 | kind: self.mod_path.kind.clone(), | 205 | self.mod_path.kind.clone(), |
185 | segments: self.mod_path.segments[..self.mod_path.segments.len() - 1].to_vec(), | 206 | self.mod_path.segments[..self.mod_path.segments.len() - 1].iter().cloned(), |
186 | }, | 207 | ), |
187 | generic_args: self.generic_args[..self.generic_args.len() - 1].to_vec(), | 208 | generic_args: self.generic_args[..self.generic_args.len() - 1].to_vec(), |
188 | }; | 209 | }; |
189 | Some(res) | 210 | Some(res) |