diff options
Diffstat (limited to 'crates/hir/src')
-rw-r--r-- | crates/hir/src/lib.rs | 19 | ||||
-rw-r--r-- | crates/hir/src/semantics.rs | 3 | ||||
-rw-r--r-- | crates/hir/src/semantics/source_to_def.rs | 106 |
3 files changed, 77 insertions, 51 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index c2b68a853..dba46df04 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -1351,6 +1351,13 @@ impl MacroDef { | |||
1351 | MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::FuncLike, _) => MacroKind::ProcMacro, | 1351 | MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::FuncLike, _) => MacroKind::ProcMacro, |
1352 | } | 1352 | } |
1353 | } | 1353 | } |
1354 | |||
1355 | pub fn is_fn_like(&self) -> bool { | ||
1356 | match self.kind() { | ||
1357 | MacroKind::Declarative | MacroKind::BuiltIn | MacroKind::ProcMacro => true, | ||
1358 | MacroKind::Attr | MacroKind::Derive => false, | ||
1359 | } | ||
1360 | } | ||
1354 | } | 1361 | } |
1355 | 1362 | ||
1356 | /// Invariant: `inner.as_assoc_item(db).is_some()` | 1363 | /// Invariant: `inner.as_assoc_item(db).is_some()` |
@@ -2496,6 +2503,18 @@ impl ScopeDef { | |||
2496 | 2503 | ||
2497 | items | 2504 | items |
2498 | } | 2505 | } |
2506 | |||
2507 | pub fn is_value_def(&self) -> bool { | ||
2508 | matches!( | ||
2509 | self, | ||
2510 | ScopeDef::ModuleDef(ModuleDef::Function(_)) | ||
2511 | | ScopeDef::ModuleDef(ModuleDef::Variant(_)) | ||
2512 | | ScopeDef::ModuleDef(ModuleDef::Const(_)) | ||
2513 | | ScopeDef::ModuleDef(ModuleDef::Static(_)) | ||
2514 | | ScopeDef::GenericParam(GenericParam::ConstParam(_)) | ||
2515 | | ScopeDef::Local(_) | ||
2516 | ) | ||
2517 | } | ||
2499 | } | 2518 | } |
2500 | 2519 | ||
2501 | impl From<ItemInNs> for ScopeDef { | 2520 | impl From<ItemInNs> for ScopeDef { |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 2d08a7704..827e23e2b 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -35,8 +35,9 @@ pub enum PathResolution { | |||
35 | Def(ModuleDef), | 35 | Def(ModuleDef), |
36 | /// A local binding (only value namespace) | 36 | /// A local binding (only value namespace) |
37 | Local(Local), | 37 | Local(Local), |
38 | /// A generic parameter | 38 | /// A type parameter |
39 | TypeParam(TypeParam), | 39 | TypeParam(TypeParam), |
40 | /// A const parameter | ||
40 | ConstParam(ConstParam), | 41 | ConstParam(ConstParam), |
41 | SelfType(Impl), | 42 | SelfType(Impl), |
42 | Macro(MacroDef), | 43 | Macro(MacroDef), |
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs index 22e196196..e8c2ed48e 100644 --- a/crates/hir/src/semantics/source_to_def.rs +++ b/crates/hir/src/semantics/source_to_def.rs | |||
@@ -211,62 +211,68 @@ impl SourceToDefCtx<'_, '_> { | |||
211 | 211 | ||
212 | pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> { | 212 | pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> { |
213 | for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) { | 213 | for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) { |
214 | let res: ChildContainer = match_ast! { | 214 | if let Some(res) = self.container_to_def(container) { |
215 | match (container.value) { | 215 | return Some(res); |
216 | ast::Module(it) => { | 216 | } |
217 | let def = self.module_to_def(container.with_value(it))?; | ||
218 | def.into() | ||
219 | }, | ||
220 | ast::Trait(it) => { | ||
221 | let def = self.trait_to_def(container.with_value(it))?; | ||
222 | def.into() | ||
223 | }, | ||
224 | ast::Impl(it) => { | ||
225 | let def = self.impl_to_def(container.with_value(it))?; | ||
226 | def.into() | ||
227 | }, | ||
228 | ast::Fn(it) => { | ||
229 | let def = self.fn_to_def(container.with_value(it))?; | ||
230 | DefWithBodyId::from(def).into() | ||
231 | }, | ||
232 | ast::Struct(it) => { | ||
233 | let def = self.struct_to_def(container.with_value(it))?; | ||
234 | VariantId::from(def).into() | ||
235 | }, | ||
236 | ast::Enum(it) => { | ||
237 | let def = self.enum_to_def(container.with_value(it))?; | ||
238 | def.into() | ||
239 | }, | ||
240 | ast::Union(it) => { | ||
241 | let def = self.union_to_def(container.with_value(it))?; | ||
242 | VariantId::from(def).into() | ||
243 | }, | ||
244 | ast::Static(it) => { | ||
245 | let def = self.static_to_def(container.with_value(it))?; | ||
246 | DefWithBodyId::from(def).into() | ||
247 | }, | ||
248 | ast::Const(it) => { | ||
249 | let def = self.const_to_def(container.with_value(it))?; | ||
250 | DefWithBodyId::from(def).into() | ||
251 | }, | ||
252 | ast::TypeAlias(it) => { | ||
253 | let def = self.type_alias_to_def(container.with_value(it))?; | ||
254 | def.into() | ||
255 | }, | ||
256 | ast::Variant(it) => { | ||
257 | let def = self.enum_variant_to_def(container.with_value(it))?; | ||
258 | VariantId::from(def).into() | ||
259 | }, | ||
260 | _ => continue, | ||
261 | } | ||
262 | }; | ||
263 | return Some(res); | ||
264 | } | 217 | } |
265 | 218 | ||
266 | let def = self.file_to_def(src.file_id.original_file(self.db.upcast())).get(0).copied()?; | 219 | let def = self.file_to_def(src.file_id.original_file(self.db.upcast())).get(0).copied()?; |
267 | Some(def.into()) | 220 | Some(def.into()) |
268 | } | 221 | } |
269 | 222 | ||
223 | fn container_to_def(&mut self, container: InFile<SyntaxNode>) -> Option<ChildContainer> { | ||
224 | let cont = match_ast! { | ||
225 | match (container.value) { | ||
226 | ast::Module(it) => { | ||
227 | let def = self.module_to_def(container.with_value(it))?; | ||
228 | def.into() | ||
229 | }, | ||
230 | ast::Trait(it) => { | ||
231 | let def = self.trait_to_def(container.with_value(it))?; | ||
232 | def.into() | ||
233 | }, | ||
234 | ast::Impl(it) => { | ||
235 | let def = self.impl_to_def(container.with_value(it))?; | ||
236 | def.into() | ||
237 | }, | ||
238 | ast::Fn(it) => { | ||
239 | let def = self.fn_to_def(container.with_value(it))?; | ||
240 | DefWithBodyId::from(def).into() | ||
241 | }, | ||
242 | ast::Struct(it) => { | ||
243 | let def = self.struct_to_def(container.with_value(it))?; | ||
244 | VariantId::from(def).into() | ||
245 | }, | ||
246 | ast::Enum(it) => { | ||
247 | let def = self.enum_to_def(container.with_value(it))?; | ||
248 | def.into() | ||
249 | }, | ||
250 | ast::Union(it) => { | ||
251 | let def = self.union_to_def(container.with_value(it))?; | ||
252 | VariantId::from(def).into() | ||
253 | }, | ||
254 | ast::Static(it) => { | ||
255 | let def = self.static_to_def(container.with_value(it))?; | ||
256 | DefWithBodyId::from(def).into() | ||
257 | }, | ||
258 | ast::Const(it) => { | ||
259 | let def = self.const_to_def(container.with_value(it))?; | ||
260 | DefWithBodyId::from(def).into() | ||
261 | }, | ||
262 | ast::TypeAlias(it) => { | ||
263 | let def = self.type_alias_to_def(container.with_value(it))?; | ||
264 | def.into() | ||
265 | }, | ||
266 | ast::Variant(it) => { | ||
267 | let def = self.enum_variant_to_def(container.with_value(it))?; | ||
268 | VariantId::from(def).into() | ||
269 | }, | ||
270 | _ => return None, | ||
271 | } | ||
272 | }; | ||
273 | Some(cont) | ||
274 | } | ||
275 | |||
270 | fn find_generic_param_container(&mut self, src: InFile<&SyntaxNode>) -> Option<GenericDefId> { | 276 | fn find_generic_param_container(&mut self, src: InFile<&SyntaxNode>) -> Option<GenericDefId> { |
271 | for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) { | 277 | for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) { |
272 | let res: GenericDefId = match_ast! { | 278 | let res: GenericDefId = match_ast! { |