diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2021-06-08 20:01:23 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2021-06-08 20:01:23 +0100 |
commit | 4e3769fbf2ff94a863ddb931cf6dfa7da9ac8172 (patch) | |
tree | fc27726da074c677ef7c603740dd674c60ed2419 /crates | |
parent | 16e142cd395f264ba5c6c3814ece92431415c089 (diff) | |
parent | 8482329d65ab4c916c5c385818b056c8176a6c75 (diff) |
Merge #9180
9180: fix: fix some IDE functionality inside attribute macros r=jonas-schievink a=jonas-schievink
In `SourceToDefCtx::find_container`, we might encounter a container that has an attribute macro. We need to skip that item, instead of bailing out and creating an empty `Resolver`, otherwise all names in the macro stay unresolved.
Part of https://github.com/rust-analyzer/rust-analyzer/issues/9142
bors r+
Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir/src/semantics/source_to_def.rs | 106 |
1 files changed, 56 insertions, 50 deletions
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! { |