aboutsummaryrefslogtreecommitdiff
path: root/crates/hir/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir/src')
-rw-r--r--crates/hir/src/source_analyzer.rs45
1 files changed, 31 insertions, 14 deletions
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 524120d08..626c3078a 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -222,6 +222,7 @@ impl SourceAnalyzer {
222 db: &dyn HirDatabase, 222 db: &dyn HirDatabase,
223 path: &ast::Path, 223 path: &ast::Path,
224 ) -> Option<PathResolution> { 224 ) -> Option<PathResolution> {
225 let mut prefer_value_ns = false;
225 if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) { 226 if let Some(path_expr) = path.syntax().parent().and_then(ast::PathExpr::cast) {
226 let expr_id = self.expr_id(db, &path_expr.into())?; 227 let expr_id = self.expr_id(db, &path_expr.into())?;
227 let infer = self.infer.as_ref()?; 228 let infer = self.infer.as_ref()?;
@@ -233,9 +234,7 @@ impl SourceAnalyzer {
233 { 234 {
234 return Some(PathResolution::Def(ModuleDef::Variant(variant.into()))); 235 return Some(PathResolution::Def(ModuleDef::Variant(variant.into())));
235 } 236 }
236 if let Some(func) = infer[expr_id].as_fn_def() { 237 prefer_value_ns = true;
237 return Some(PathResolution::Def(ModuleDef::Function(func.into())));
238 }
239 } 238 }
240 239
241 if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) { 240 if let Some(path_pat) = path.syntax().parent().and_then(ast::PathPat::cast) {
@@ -281,7 +280,7 @@ impl SourceAnalyzer {
281 } 280 }
282 } 281 }
283 282
284 resolve_hir_path(db, &self.resolver, &hir_path) 283 resolve_hir_path_(db, &self.resolver, &hir_path, prefer_value_ns)
285 } 284 }
286 285
287 pub(crate) fn record_literal_missing_fields( 286 pub(crate) fn record_literal_missing_fields(
@@ -451,12 +450,22 @@ fn adjust(
451 .map(|(_ptr, scope)| *scope) 450 .map(|(_ptr, scope)| *scope)
452} 451}
453 452
453#[inline]
454pub(crate) fn resolve_hir_path( 454pub(crate) fn resolve_hir_path(
455 db: &dyn HirDatabase, 455 db: &dyn HirDatabase,
456 resolver: &Resolver, 456 resolver: &Resolver,
457 path: &Path, 457 path: &Path,
458) -> Option<PathResolution> { 458) -> Option<PathResolution> {
459 let types = 459 resolve_hir_path_(db, resolver, path, false)
460}
461
462fn resolve_hir_path_(
463 db: &dyn HirDatabase,
464 resolver: &Resolver,
465 path: &Path,
466 prefer_value_ns: bool,
467) -> Option<PathResolution> {
468 let types = || {
460 resolver.resolve_path_in_type_ns_fully(db.upcast(), path.mod_path()).map(|ty| match ty { 469 resolver.resolve_path_in_type_ns_fully(db.upcast(), path.mod_path()).map(|ty| match ty {
461 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), 470 TypeNs::SelfType(it) => PathResolution::SelfType(it.into()),
462 TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), 471 TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }),
@@ -467,10 +476,11 @@ pub(crate) fn resolve_hir_path(
467 TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), 476 TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()),
468 TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), 477 TypeNs::BuiltinType(it) => PathResolution::Def(it.into()),
469 TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), 478 TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()),
470 }); 479 })
480 };
471 481
472 let body_owner = resolver.body_owner(); 482 let body_owner = resolver.body_owner();
473 let values = 483 let values = || {
474 resolver.resolve_path_in_value_ns_fully(db.upcast(), path.mod_path()).and_then(|val| { 484 resolver.resolve_path_in_value_ns_fully(db.upcast(), path.mod_path()).and_then(|val| {
475 let res = match val { 485 let res = match val {
476 ValueNs::LocalBinding(pat_id) => { 486 ValueNs::LocalBinding(pat_id) => {
@@ -486,18 +496,25 @@ pub(crate) fn resolve_hir_path(
486 ValueNs::GenericParam(it) => PathResolution::ConstParam(it.into()), 496 ValueNs::GenericParam(it) => PathResolution::ConstParam(it.into()),
487 }; 497 };
488 Some(res) 498 Some(res)
489 }); 499 })
500 };
490 501
491 let items = resolver 502 let items = || {
492 .resolve_module_path_in_items(db.upcast(), path.mod_path()) 503 resolver
493 .take_types() 504 .resolve_module_path_in_items(db.upcast(), path.mod_path())
494 .map(|it| PathResolution::Def(it.into())); 505 .take_types()
506 .map(|it| PathResolution::Def(it.into()))
507 };
495 508
496 types.or(values).or(items).or_else(|| { 509 let macros = || {
497 resolver 510 resolver
498 .resolve_path_as_macro(db.upcast(), path.mod_path()) 511 .resolve_path_as_macro(db.upcast(), path.mod_path())
499 .map(|def| PathResolution::Macro(def.into())) 512 .map(|def| PathResolution::Macro(def.into()))
500 }) 513 };
514
515 if prefer_value_ns { values().or_else(types) } else { types().or_else(values) }
516 .or_else(items)
517 .or_else(macros)
501} 518}
502 519
503/// Resolves a path where we know it is a qualifier of another path. 520/// Resolves a path where we know it is a qualifier of another path.