diff options
author | Ville Penttinen <[email protected]> | 2019-02-22 08:15:23 +0000 |
---|---|---|
committer | Ville Penttinen <[email protected]> | 2019-02-22 08:15:23 +0000 |
commit | 247d1c17b385ff8a8c1dda2e899495146b643b98 (patch) | |
tree | d0b80f6321d596cc151488e88a2747d168f7137c /crates/ra_hir/src | |
parent | 39679d499f5e0b5d26ae0f0b707f6db8901cdb66 (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/src')
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/resolve.rs | 29 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 39 |
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)] |
36 | pub struct PathResult { | 36 | pub(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 { | |||
45 | impl PathResult { | 45 | impl 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, |