aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir
diff options
context:
space:
mode:
authorVille Penttinen <[email protected]>2019-02-22 08:15:23 +0000
committerVille Penttinen <[email protected]>2019-02-22 08:15:23 +0000
commit247d1c17b385ff8a8c1dda2e899495146b643b98 (patch)
treed0b80f6321d596cc151488e88a2747d168f7137c /crates/ra_hir
parent39679d499f5e0b5d26ae0f0b707f6db8901cdb66 (diff)
Change resolve_path to return the fully resolved path or PerNs::none
This also adds new pub(crate) resolve_path_segments which returns the PathResult, which may or may not be fully resolved. PathResult is also now pub(crate) since it is an implementation detail.
Diffstat (limited to 'crates/ra_hir')
-rw-r--r--crates/ra_hir/src/impl_block.rs2
-rw-r--r--crates/ra_hir/src/resolve.rs29
-rw-r--r--crates/ra_hir/src/ty.rs39
3 files changed, 36 insertions, 34 deletions
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs
index f4dccf165..7ecf8c368 100644
--- a/crates/ra_hir/src/impl_block.rs
+++ b/crates/ra_hir/src/impl_block.rs
@@ -88,7 +88,7 @@ impl ImplBlock {
88 if let Some(TypeRef::Path(path)) = self.target_trait_ref(db) { 88 if let Some(TypeRef::Path(path)) = self.target_trait_ref(db) {
89 let resolver = self.resolver(db); 89 let resolver = self.resolver(db);
90 if let Some(Resolution::Def(ModuleDef::Trait(tr))) = 90 if let Some(Resolution::Def(ModuleDef::Trait(tr))) =
91 resolver.resolve_path(db, &path).into_per_ns().take_types() 91 resolver.resolve_path(db, &path).take_types()
92 { 92 {
93 return Some(tr); 93 return Some(tr);
94 } 94 }
diff --git a/crates/ra_hir/src/resolve.rs b/crates/ra_hir/src/resolve.rs
index 9f4d4ab42..57e7d0b9a 100644
--- a/crates/ra_hir/src/resolve.rs
+++ b/crates/ra_hir/src/resolve.rs
@@ -33,7 +33,7 @@ pub(crate) struct ExprScope {
33} 33}
34 34
35#[derive(Debug, Clone)] 35#[derive(Debug, Clone)]
36pub struct PathResult { 36pub(crate) struct PathResult {
37 /// The actual path resolution 37 /// The actual path resolution
38 resolution: PerNs<Resolution>, 38 resolution: PerNs<Resolution>,
39 /// The first index in the path that we 39 /// The first index in the path that we
@@ -45,7 +45,7 @@ pub struct PathResult {
45impl PathResult { 45impl PathResult {
46 /// Returns the remaining index in the result 46 /// Returns the remaining index in the result
47 /// returns None if the path was fully resolved 47 /// returns None if the path was fully resolved
48 pub fn remaining_index(&self) -> Option<usize> { 48 pub(crate) fn remaining_index(&self) -> Option<usize> {
49 if self.remaining_index > 0 { 49 if self.remaining_index > 0 {
50 Some(self.remaining_index) 50 Some(self.remaining_index)
51 } else { 51 } else {
@@ -55,8 +55,8 @@ impl PathResult {
55 55
56 /// Consumes `PathResult` and returns the contained `PerNs<Resolution>` 56 /// Consumes `PathResult` and returns the contained `PerNs<Resolution>`
57 /// if the path was fully resolved, meaning we have no remaining items 57 /// if the path was fully resolved, meaning we have no remaining items
58 pub fn into_per_ns(self) -> PerNs<Resolution> { 58 pub(crate) fn into_fully_resolved(self) -> PerNs<Resolution> {
59 if self.remaining_index().is_none() { 59 if self.is_fully_resolved() {
60 self.resolution 60 self.resolution
61 } else { 61 } else {
62 PerNs::none() 62 PerNs::none()
@@ -65,23 +65,17 @@ impl PathResult {
65 65
66 /// Consumes `PathResult` and returns the resolution and the 66 /// Consumes `PathResult` and returns the resolution and the
67 /// remaining_index as a tuple. 67 /// remaining_index as a tuple.
68 pub fn into_inner(self) -> (PerNs<Resolution>, Option<usize>) { 68 pub(crate) fn into_inner(self) -> (PerNs<Resolution>, Option<usize>) {
69 let index = self.remaining_index(); 69 let index = self.remaining_index();
70 (self.resolution, index) 70 (self.resolution, index)
71 } 71 }
72 72
73 /// Path is fully resolved when `remaining_index` is none 73 /// Path is fully resolved when `remaining_index` is none
74 /// and the resolution contains anything 74 /// and the resolution contains anything
75 pub fn is_fully_resolved(&self) -> bool { 75 pub(crate) fn is_fully_resolved(&self) -> bool {
76 !self.resolution.is_none() && self.remaining_index().is_none() 76 !self.resolution.is_none() && self.remaining_index().is_none()
77 } 77 }
78 78
79 /// Empty path result is where the resolution is `none`
80 /// and the remaining index is 0
81 pub fn is_empty(&self) -> bool {
82 self.resolution.is_none() && self.remaining_index().is_none()
83 }
84
85 fn empty() -> PathResult { 79 fn empty() -> PathResult {
86 PathResult { resolution: PerNs::none(), remaining_index: 0 } 80 PathResult { resolution: PerNs::none(), remaining_index: 0 }
87 } 81 }
@@ -134,7 +128,9 @@ impl Resolver {
134 resolution 128 resolution
135 } 129 }
136 130
137 pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PathResult { 131 /// Returns the resolved path segments
132 /// Which may be fully resolved, empty or partially resolved.
133 pub(crate) fn resolve_path_segments(&self, db: &impl HirDatabase, path: &Path) -> PathResult {
138 if let Some(name) = path.as_ident() { 134 if let Some(name) = path.as_ident() {
139 PathResult::from_resolution(self.resolve_name(db, name)) 135 PathResult::from_resolution(self.resolve_name(db, name))
140 } else if path.is_self() { 136 } else if path.is_self() {
@@ -156,6 +152,13 @@ impl Resolver {
156 } 152 }
157 } 153 }
158 154
155 /// Returns the fully resolved path if we were able to resolve it.
156 /// otherwise returns `PerNs::none`
157 pub fn resolve_path(&self, db: &impl HirDatabase, path: &Path) -> PerNs<Resolution> {
158 // into_fully_resolved() returns the fully resolved path or PerNs::none() otherwise
159 self.resolve_path_segments(db, path).into_fully_resolved()
160 }
161
159 pub fn all_names(&self, db: &impl HirDatabase) -> FxHashMap<Name, PerNs<Resolution>> { 162 pub fn all_names(&self, db: &impl HirDatabase) -> FxHashMap<Name, PerNs<Resolution>> {
160 let mut names = FxHashMap::default(); 163 let mut names = FxHashMap::default();
161 for scope in self.scopes.iter().rev() { 164 for scope in self.scopes.iter().rev() {
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs
index b1f35ab1f..89e854dd7 100644
--- a/crates/ra_hir/src/ty.rs
+++ b/crates/ra_hir/src/ty.rs
@@ -370,7 +370,7 @@ impl Ty {
370 } 370 }
371 371
372 // Resolve the path (in type namespace) 372 // Resolve the path (in type namespace)
373 let resolution = resolver.resolve_path(db, path).into_per_ns().take_types(); 373 let resolution = resolver.resolve_path(db, path).take_types();
374 374
375 let def = match resolution { 375 let def = match resolution {
376 Some(Resolution::Def(def)) => def, 376 Some(Resolution::Def(def)) => def,
@@ -1172,7 +1172,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1172 } 1172 }
1173 1173
1174 fn infer_path_expr(&mut self, resolver: &Resolver, path: &Path) -> Option<Ty> { 1174 fn infer_path_expr(&mut self, resolver: &Resolver, path: &Path) -> Option<Ty> {
1175 let resolved = resolver.resolve_path(self.db, &path); 1175 let resolved = resolver.resolve_path_segments(self.db, &path);
1176 1176
1177 let (def, remaining_index) = resolved.into_inner(); 1177 let (def, remaining_index) = resolved.into_inner();
1178 1178
@@ -1244,24 +1244,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
1244 None => return (Ty::Unknown, None), 1244 None => return (Ty::Unknown, None),
1245 }; 1245 };
1246 let resolver = &self.resolver; 1246 let resolver = &self.resolver;
1247 let typable: Option<TypableDef> = 1247 let typable: Option<TypableDef> = match resolver.resolve_path(self.db, &path).take_types() {
1248 match resolver.resolve_path(self.db, &path).into_per_ns().take_types() { 1248 Some(Resolution::Def(def)) => def.into(),
1249 Some(Resolution::Def(def)) => def.into(), 1249 Some(Resolution::LocalBinding(..)) => {
1250 Some(Resolution::LocalBinding(..)) => { 1250 // this cannot happen
1251 // this cannot happen 1251 log::error!("path resolved to local binding in type ns");
1252 log::error!("path resolved to local binding in type ns"); 1252 return (Ty::Unknown, None);
1253 return (Ty::Unknown, None); 1253 }
1254 } 1254 Some(Resolution::GenericParam(..)) => {
1255 Some(Resolution::GenericParam(..)) => { 1255 // generic params can't be used in struct literals
1256 // generic params can't be used in struct literals 1256 return (Ty::Unknown, None);
1257 return (Ty::Unknown, None); 1257 }
1258 } 1258 Some(Resolution::SelfType(..)) => {
1259 Some(Resolution::SelfType(..)) => { 1259 // TODO this is allowed in an impl for a struct, handle this
1260 // TODO this is allowed in an impl for a struct, handle this 1260 return (Ty::Unknown, None);
1261 return (Ty::Unknown, None); 1261 }
1262 } 1262 None => return (Ty::Unknown, None),
1263 None => return (Ty::Unknown, None), 1263 };
1264 };
1265 let def = match typable { 1264 let def = match typable {
1266 None => return (Ty::Unknown, None), 1265 None => return (Ty::Unknown, None),
1267 Some(it) => it, 1266 Some(it) => it,