diff options
Diffstat (limited to 'crates/hir/src')
-rw-r--r-- | crates/hir/src/source_analyzer.rs | 45 |
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] | ||
454 | pub(crate) fn resolve_hir_path( | 454 | pub(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 | |||
462 | fn 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. |