aboutsummaryrefslogtreecommitdiff
path: root/crates/hir/src/semantics
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-06-08 20:01:23 +0100
committerGitHub <[email protected]>2021-06-08 20:01:23 +0100
commit4e3769fbf2ff94a863ddb931cf6dfa7da9ac8172 (patch)
treefc27726da074c677ef7c603740dd674c60ed2419 /crates/hir/src/semantics
parent16e142cd395f264ba5c6c3814ece92431415c089 (diff)
parent8482329d65ab4c916c5c385818b056c8176a6c75 (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/hir/src/semantics')
-rw-r--r--crates/hir/src/semantics/source_to_def.rs106
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! {