aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide_db/src/defs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide_db/src/defs.rs')
-rw-r--r--crates/ra_ide_db/src/defs.rs91
1 files changed, 62 insertions, 29 deletions
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs
index bc6e89cbc..80c99935d 100644
--- a/crates/ra_ide_db/src/defs.rs
+++ b/crates/ra_ide_db/src/defs.rs
@@ -136,7 +136,7 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option
136 136
137 match_ast! { 137 match_ast! {
138 match parent { 138 match parent {
139 ast::Alias(it) => { 139 ast::Rename(it) => {
140 let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?; 140 let use_tree = it.syntax().parent().and_then(ast::UseTree::cast)?;
141 let path = use_tree.path()?; 141 let path = use_tree.path()?;
142 let path_segment = path.segment()?; 142 let path_segment = path.segment()?;
@@ -159,7 +159,7 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option
159 159
160 Some(NameClass::Definition(Definition::Local(local))) 160 Some(NameClass::Definition(Definition::Local(local)))
161 }, 161 },
162 ast::RecordFieldDef(it) => { 162 ast::RecordField(it) => {
163 let field: hir::Field = sema.to_def(&it)?; 163 let field: hir::Field = sema.to_def(&it)?;
164 Some(NameClass::Definition(Definition::Field(field))) 164 Some(NameClass::Definition(Definition::Field(field)))
165 }, 165 },
@@ -167,39 +167,39 @@ pub fn classify_name(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option
167 let def = sema.to_def(&it)?; 167 let def = sema.to_def(&it)?;
168 Some(NameClass::Definition(Definition::ModuleDef(def.into()))) 168 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
169 }, 169 },
170 ast::StructDef(it) => { 170 ast::Struct(it) => {
171 let def: hir::Struct = sema.to_def(&it)?; 171 let def: hir::Struct = sema.to_def(&it)?;
172 Some(NameClass::Definition(Definition::ModuleDef(def.into()))) 172 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
173 }, 173 },
174 ast::UnionDef(it) => { 174 ast::Union(it) => {
175 let def: hir::Union = sema.to_def(&it)?; 175 let def: hir::Union = sema.to_def(&it)?;
176 Some(NameClass::Definition(Definition::ModuleDef(def.into()))) 176 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
177 }, 177 },
178 ast::EnumDef(it) => { 178 ast::Enum(it) => {
179 let def: hir::Enum = sema.to_def(&it)?; 179 let def: hir::Enum = sema.to_def(&it)?;
180 Some(NameClass::Definition(Definition::ModuleDef(def.into()))) 180 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
181 }, 181 },
182 ast::TraitDef(it) => { 182 ast::Trait(it) => {
183 let def: hir::Trait = sema.to_def(&it)?; 183 let def: hir::Trait = sema.to_def(&it)?;
184 Some(NameClass::Definition(Definition::ModuleDef(def.into()))) 184 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
185 }, 185 },
186 ast::StaticDef(it) => { 186 ast::Static(it) => {
187 let def: hir::Static = sema.to_def(&it)?; 187 let def: hir::Static = sema.to_def(&it)?;
188 Some(NameClass::Definition(Definition::ModuleDef(def.into()))) 188 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
189 }, 189 },
190 ast::EnumVariant(it) => { 190 ast::Variant(it) => {
191 let def: hir::EnumVariant = sema.to_def(&it)?; 191 let def: hir::EnumVariant = sema.to_def(&it)?;
192 Some(NameClass::Definition(Definition::ModuleDef(def.into()))) 192 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
193 }, 193 },
194 ast::FnDef(it) => { 194 ast::Fn(it) => {
195 let def: hir::Function = sema.to_def(&it)?; 195 let def: hir::Function = sema.to_def(&it)?;
196 Some(NameClass::Definition(Definition::ModuleDef(def.into()))) 196 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
197 }, 197 },
198 ast::ConstDef(it) => { 198 ast::Const(it) => {
199 let def: hir::Const = sema.to_def(&it)?; 199 let def: hir::Const = sema.to_def(&it)?;
200 Some(NameClass::Definition(Definition::ModuleDef(def.into()))) 200 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
201 }, 201 },
202 ast::TypeAliasDef(it) => { 202 ast::TypeAlias(it) => {
203 let def: hir::TypeAlias = sema.to_def(&it)?; 203 let def: hir::TypeAlias = sema.to_def(&it)?;
204 Some(NameClass::Definition(Definition::ModuleDef(def.into()))) 204 Some(NameClass::Definition(Definition::ModuleDef(def.into())))
205 }, 205 },
@@ -253,7 +253,7 @@ pub fn classify_name_ref(
253 } 253 }
254 } 254 }
255 255
256 if let Some(record_field) = ast::RecordField::for_field_name(name_ref) { 256 if let Some(record_field) = ast::RecordExprField::for_field_name(name_ref) {
257 if let Some((field, local)) = sema.resolve_record_field(&record_field) { 257 if let Some((field, local)) = sema.resolve_record_field(&record_field) {
258 let field = Definition::Field(field); 258 let field = Definition::Field(field);
259 let res = match local { 259 let res = match local {
@@ -271,28 +271,61 @@ pub fn classify_name_ref(
271 } 271 }
272 } 272 }
273 273
274 if ast::AssocTypeArg::cast(parent.clone()).is_some() {
275 // `Trait<Assoc = Ty>`
276 // ^^^^^
277 let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?;
278 let resolved = sema.resolve_path(&path)?;
279 if let PathResolution::Def(ModuleDef::Trait(tr)) = resolved {
280 if let Some(ty) = tr
281 .items(sema.db)
282 .iter()
283 .filter_map(|assoc| match assoc {
284 hir::AssocItem::TypeAlias(it) => Some(*it),
285 _ => None,
286 })
287 .find(|alias| alias.name(sema.db).to_string() == **name_ref.text())
288 {
289 return Some(NameRefClass::Definition(Definition::ModuleDef(
290 ModuleDef::TypeAlias(ty),
291 )));
292 }
293 }
294 }
295
274 if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { 296 if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
275 if let Some(macro_def) = sema.resolve_macro_call(&macro_call) { 297 if let Some(path) = macro_call.path() {
276 return Some(NameRefClass::Definition(Definition::Macro(macro_def))); 298 if path.qualifier().is_none() {
299 // Only use this to resolve single-segment macro calls like `foo!()`. Multi-segment
300 // paths are handled below (allowing `log<|>::info!` to resolve to the log crate).
301 if let Some(macro_def) = sema.resolve_macro_call(&macro_call) {
302 return Some(NameRefClass::Definition(Definition::Macro(macro_def)));
303 }
304 }
277 } 305 }
278 } 306 }
279 307
280 let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?; 308 let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?;
281 let resolved = sema.resolve_path(&path)?; 309 let resolved = sema.resolve_path(&path)?;
282 let res = match resolved { 310 Some(NameRefClass::Definition(resolved.into()))
283 PathResolution::Def(def) => Definition::ModuleDef(def), 311}
284 PathResolution::AssocItem(item) => { 312
285 let def = match item { 313impl From<PathResolution> for Definition {
286 hir::AssocItem::Function(it) => it.into(), 314 fn from(path_resolution: PathResolution) -> Self {
287 hir::AssocItem::Const(it) => it.into(), 315 match path_resolution {
288 hir::AssocItem::TypeAlias(it) => it.into(), 316 PathResolution::Def(def) => Definition::ModuleDef(def),
289 }; 317 PathResolution::AssocItem(item) => {
290 Definition::ModuleDef(def) 318 let def = match item {
319 hir::AssocItem::Function(it) => it.into(),
320 hir::AssocItem::Const(it) => it.into(),
321 hir::AssocItem::TypeAlias(it) => it.into(),
322 };
323 Definition::ModuleDef(def)
324 }
325 PathResolution::Local(local) => Definition::Local(local),
326 PathResolution::TypeParam(par) => Definition::TypeParam(par),
327 PathResolution::Macro(def) => Definition::Macro(def),
328 PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def),
291 } 329 }
292 PathResolution::Local(local) => Definition::Local(local), 330 }
293 PathResolution::TypeParam(par) => Definition::TypeParam(par),
294 PathResolution::Macro(def) => Definition::Macro(def),
295 PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def),
296 };
297 Some(NameRefClass::Definition(res))
298} 331}