aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/path.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/path.rs')
-rw-r--r--crates/hir_def/src/path.rs37
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)]
21pub struct ModPath { 21pub 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)