diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/code_model.rs | 88 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/semantics.rs | 26 | ||||
-rw-r--r-- | crates/ra_hir/src/semantics/source_to_def.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/source_analyzer.rs | 55 |
5 files changed, 149 insertions, 26 deletions
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index af59aa1b6..4a06f3bcd 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -19,11 +19,14 @@ use hir_def::{ | |||
19 | use hir_expand::{ | 19 | use hir_expand::{ |
20 | diagnostics::DiagnosticSink, | 20 | diagnostics::DiagnosticSink, |
21 | name::{name, AsName}, | 21 | name::{name, AsName}, |
22 | MacroDefId, | 22 | MacroDefId, MacroDefKind, |
23 | }; | 23 | }; |
24 | use hir_ty::{ | 24 | use hir_ty::{ |
25 | autoderef, display::HirFormatter, expr::ExprValidator, method_resolution, ApplicationTy, | 25 | autoderef, |
26 | Canonical, InEnvironment, Substs, TraitEnvironment, Ty, TyDefId, TypeCtor, | 26 | display::{HirDisplayError, HirFormatter}, |
27 | expr::ExprValidator, | ||
28 | method_resolution, ApplicationTy, Canonical, InEnvironment, Substs, TraitEnvironment, Ty, | ||
29 | TyDefId, TypeCtor, | ||
27 | }; | 30 | }; |
28 | use ra_db::{CrateId, CrateName, Edition, FileId}; | 31 | use ra_db::{CrateId, CrateName, Edition, FileId}; |
29 | use ra_prof::profile; | 32 | use ra_prof::profile; |
@@ -145,6 +148,26 @@ impl ModuleDef { | |||
145 | ModuleDef::BuiltinType(_) => None, | 148 | ModuleDef::BuiltinType(_) => None, |
146 | } | 149 | } |
147 | } | 150 | } |
151 | |||
152 | pub fn definition_visibility(&self, db: &dyn HirDatabase) -> Option<Visibility> { | ||
153 | let module = match self { | ||
154 | ModuleDef::Module(it) => it.parent(db)?, | ||
155 | ModuleDef::Function(it) => return Some(it.visibility(db)), | ||
156 | ModuleDef::Adt(it) => it.module(db), | ||
157 | ModuleDef::EnumVariant(it) => { | ||
158 | let parent = it.parent_enum(db); | ||
159 | let module = it.module(db); | ||
160 | return module.visibility_of(db, &ModuleDef::Adt(Adt::Enum(parent))); | ||
161 | } | ||
162 | ModuleDef::Const(it) => return Some(it.visibility(db)), | ||
163 | ModuleDef::Static(it) => it.module(db), | ||
164 | ModuleDef::Trait(it) => it.module(db), | ||
165 | ModuleDef::TypeAlias(it) => return Some(it.visibility(db)), | ||
166 | ModuleDef::BuiltinType(_) => return None, | ||
167 | }; | ||
168 | |||
169 | module.visibility_of(db, self) | ||
170 | } | ||
148 | } | 171 | } |
149 | 172 | ||
150 | pub use hir_def::{ | 173 | pub use hir_def::{ |
@@ -509,7 +532,7 @@ impl Adt { | |||
509 | Some(self.module(db).krate()) | 532 | Some(self.module(db).krate()) |
510 | } | 533 | } |
511 | 534 | ||
512 | pub fn name(&self, db: &dyn HirDatabase) -> Name { | 535 | pub fn name(self, db: &dyn HirDatabase) -> Name { |
513 | match self { | 536 | match self { |
514 | Adt::Struct(s) => s.name(db), | 537 | Adt::Struct(s) => s.name(db), |
515 | Adt::Union(u) => u.name(db), | 538 | Adt::Union(u) => u.name(db), |
@@ -614,6 +637,10 @@ impl Function { | |||
614 | db.function_data(self.id).params.clone() | 637 | db.function_data(self.id).params.clone() |
615 | } | 638 | } |
616 | 639 | ||
640 | pub fn is_unsafe(self, db: &dyn HirDatabase) -> bool { | ||
641 | db.function_data(self.id).is_unsafe | ||
642 | } | ||
643 | |||
617 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { | 644 | pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { |
618 | let _p = profile("Function::diagnostics"); | 645 | let _p = profile("Function::diagnostics"); |
619 | let infer = db.infer(self.id.into()); | 646 | let infer = db.infer(self.id.into()); |
@@ -675,6 +702,10 @@ impl Static { | |||
675 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { | 702 | pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { |
676 | db.static_data(self.id).name.clone() | 703 | db.static_data(self.id).name.clone() |
677 | } | 704 | } |
705 | |||
706 | pub fn is_mut(self, db: &dyn HirDatabase) -> bool { | ||
707 | db.static_data(self.id).mutable | ||
708 | } | ||
678 | } | 709 | } |
679 | 710 | ||
680 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 711 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -762,13 +793,12 @@ impl MacroDef { | |||
762 | 793 | ||
763 | /// Indicate it is a proc-macro | 794 | /// Indicate it is a proc-macro |
764 | pub fn is_proc_macro(&self) -> bool { | 795 | pub fn is_proc_macro(&self) -> bool { |
765 | match self.id.kind { | 796 | matches!(self.id.kind, MacroDefKind::CustomDerive(_)) |
766 | hir_expand::MacroDefKind::Declarative => false, | 797 | } |
767 | hir_expand::MacroDefKind::BuiltIn(_) => false, | 798 | |
768 | hir_expand::MacroDefKind::BuiltInDerive(_) => false, | 799 | /// Indicate it is a derive macro |
769 | hir_expand::MacroDefKind::BuiltInEager(_) => false, | 800 | pub fn is_derive_macro(&self) -> bool { |
770 | hir_expand::MacroDefKind::CustomDerive(_) => true, | 801 | matches!(self.id.kind, MacroDefKind::CustomDerive(_) | MacroDefKind::BuiltInDerive(_)) |
771 | } | ||
772 | } | 802 | } |
773 | } | 803 | } |
774 | 804 | ||
@@ -963,6 +993,17 @@ impl TypeParam { | |||
963 | ty: InEnvironment { value: ty, environment }, | 993 | ty: InEnvironment { value: ty, environment }, |
964 | } | 994 | } |
965 | } | 995 | } |
996 | |||
997 | pub fn default(self, db: &dyn HirDatabase) -> Option<Type> { | ||
998 | let params = db.generic_defaults(self.id.parent); | ||
999 | let local_idx = hir_ty::param_idx(db, self.id)?; | ||
1000 | let resolver = self.id.parent.resolver(db.upcast()); | ||
1001 | let environment = TraitEnvironment::lower(db, &resolver); | ||
1002 | params.get(local_idx).cloned().map(|ty| Type { | ||
1003 | krate: self.id.parent.module(db.upcast()).krate, | ||
1004 | ty: InEnvironment { value: ty, environment }, | ||
1005 | }) | ||
1006 | } | ||
966 | } | 1007 | } |
967 | 1008 | ||
968 | // FIXME: rename from `ImplDef` to `Impl` | 1009 | // FIXME: rename from `ImplDef` to `Impl` |
@@ -981,15 +1022,15 @@ impl ImplDef { | |||
981 | impls.lookup_impl_defs_for_trait(trait_.id).map(Self::from).collect() | 1022 | impls.lookup_impl_defs_for_trait(trait_.id).map(Self::from).collect() |
982 | } | 1023 | } |
983 | 1024 | ||
984 | pub fn target_trait(&self, db: &dyn HirDatabase) -> Option<TypeRef> { | 1025 | pub fn target_trait(self, db: &dyn HirDatabase) -> Option<TypeRef> { |
985 | db.impl_data(self.id).target_trait.clone() | 1026 | db.impl_data(self.id).target_trait.clone() |
986 | } | 1027 | } |
987 | 1028 | ||
988 | pub fn target_type(&self, db: &dyn HirDatabase) -> TypeRef { | 1029 | pub fn target_type(self, db: &dyn HirDatabase) -> TypeRef { |
989 | db.impl_data(self.id).target_type.clone() | 1030 | db.impl_data(self.id).target_type.clone() |
990 | } | 1031 | } |
991 | 1032 | ||
992 | pub fn target_ty(&self, db: &dyn HirDatabase) -> Type { | 1033 | pub fn target_ty(self, db: &dyn HirDatabase) -> Type { |
993 | let impl_data = db.impl_data(self.id); | 1034 | let impl_data = db.impl_data(self.id); |
994 | let resolver = self.id.resolver(db.upcast()); | 1035 | let resolver = self.id.resolver(db.upcast()); |
995 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | 1036 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); |
@@ -1001,23 +1042,23 @@ impl ImplDef { | |||
1001 | } | 1042 | } |
1002 | } | 1043 | } |
1003 | 1044 | ||
1004 | pub fn items(&self, db: &dyn HirDatabase) -> Vec<AssocItem> { | 1045 | pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> { |
1005 | db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect() | 1046 | db.impl_data(self.id).items.iter().map(|it| (*it).into()).collect() |
1006 | } | 1047 | } |
1007 | 1048 | ||
1008 | pub fn is_negative(&self, db: &dyn HirDatabase) -> bool { | 1049 | pub fn is_negative(self, db: &dyn HirDatabase) -> bool { |
1009 | db.impl_data(self.id).is_negative | 1050 | db.impl_data(self.id).is_negative |
1010 | } | 1051 | } |
1011 | 1052 | ||
1012 | pub fn module(&self, db: &dyn HirDatabase) -> Module { | 1053 | pub fn module(self, db: &dyn HirDatabase) -> Module { |
1013 | self.id.lookup(db.upcast()).container.module(db.upcast()).into() | 1054 | self.id.lookup(db.upcast()).container.module(db.upcast()).into() |
1014 | } | 1055 | } |
1015 | 1056 | ||
1016 | pub fn krate(&self, db: &dyn HirDatabase) -> Crate { | 1057 | pub fn krate(self, db: &dyn HirDatabase) -> Crate { |
1017 | Crate { id: self.module(db).id.krate } | 1058 | Crate { id: self.module(db).id.krate } |
1018 | } | 1059 | } |
1019 | 1060 | ||
1020 | pub fn is_builtin_derive(&self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> { | 1061 | pub fn is_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> { |
1021 | let src = self.source(db); | 1062 | let src = self.source(db); |
1022 | let item = src.file_id.is_builtin_derive(db.upcast())?; | 1063 | let item = src.file_id.is_builtin_derive(db.upcast())?; |
1023 | let hygenic = hir_expand::hygiene::Hygiene::new(db.upcast(), item.file_id); | 1064 | let hygenic = hir_expand::hygiene::Hygiene::new(db.upcast(), item.file_id); |
@@ -1153,6 +1194,10 @@ impl Type { | |||
1153 | ) | 1194 | ) |
1154 | } | 1195 | } |
1155 | 1196 | ||
1197 | pub fn is_raw_ptr(&self) -> bool { | ||
1198 | matches!(&self.ty.value, Ty::Apply(ApplicationTy { ctor: TypeCtor::RawPtr(..), .. })) | ||
1199 | } | ||
1200 | |||
1156 | pub fn contains_unknown(&self) -> bool { | 1201 | pub fn contains_unknown(&self) -> bool { |
1157 | return go(&self.ty.value); | 1202 | return go(&self.ty.value); |
1158 | 1203 | ||
@@ -1212,7 +1257,7 @@ impl Type { | |||
1212 | 1257 | ||
1213 | // This would be nicer if it just returned an iterator, but that runs into | 1258 | // This would be nicer if it just returned an iterator, but that runs into |
1214 | // lifetime problems, because we need to borrow temp `CrateImplDefs`. | 1259 | // lifetime problems, because we need to borrow temp `CrateImplDefs`. |
1215 | pub fn iterate_impl_items<T>( | 1260 | pub fn iterate_assoc_items<T>( |
1216 | self, | 1261 | self, |
1217 | db: &dyn HirDatabase, | 1262 | db: &dyn HirDatabase, |
1218 | krate: Crate, | 1263 | krate: Crate, |
@@ -1320,12 +1365,13 @@ impl Type { | |||
1320 | } | 1365 | } |
1321 | 1366 | ||
1322 | impl HirDisplay for Type { | 1367 | impl HirDisplay for Type { |
1323 | fn hir_fmt(&self, f: &mut HirFormatter) -> std::fmt::Result { | 1368 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { |
1324 | self.ty.value.hir_fmt(f) | 1369 | self.ty.value.hir_fmt(f) |
1325 | } | 1370 | } |
1326 | } | 1371 | } |
1327 | 1372 | ||
1328 | /// For IDE only | 1373 | /// For IDE only |
1374 | #[derive(Debug)] | ||
1329 | pub enum ScopeDef { | 1375 | pub enum ScopeDef { |
1330 | ModuleDef(ModuleDef), | 1376 | ModuleDef(ModuleDef), |
1331 | MacroDef(MacroDef), | 1377 | MacroDef(MacroDef), |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index 312ef3814..3364a822f 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -62,6 +62,7 @@ pub use crate::{ | |||
62 | 62 | ||
63 | pub use hir_def::{ | 63 | pub use hir_def::{ |
64 | adt::StructKind, | 64 | adt::StructKind, |
65 | attr::Attrs, | ||
65 | body::scope::ExprScopes, | 66 | body::scope::ExprScopes, |
66 | builtin_type::BuiltinType, | 67 | builtin_type::BuiltinType, |
67 | docs::Documentation, | 68 | docs::Documentation, |
@@ -70,6 +71,7 @@ pub use hir_def::{ | |||
70 | type_ref::Mutability, | 71 | type_ref::Mutability, |
71 | }; | 72 | }; |
72 | pub use hir_expand::{ | 73 | pub use hir_expand::{ |
73 | name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, MacroFile, Origin, | 74 | hygiene::Hygiene, name::Name, HirFileId, InFile, MacroCallId, MacroCallLoc, MacroDefId, |
75 | MacroFile, Origin, | ||
74 | }; | 76 | }; |
75 | pub use hir_ty::{display::HirDisplay, CallableDef}; | 77 | pub use hir_ty::{display::HirDisplay, CallableDef}; |
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs index a0a0f234b..7c1f79f27 100644 --- a/crates/ra_hir/src/semantics.rs +++ b/crates/ra_hir/src/semantics.rs | |||
@@ -8,7 +8,7 @@ use hir_def::{ | |||
8 | resolver::{self, HasResolver, Resolver}, | 8 | resolver::{self, HasResolver, Resolver}, |
9 | AsMacroCall, TraitId, | 9 | AsMacroCall, TraitId, |
10 | }; | 10 | }; |
11 | use hir_expand::ExpansionInfo; | 11 | use hir_expand::{hygiene::Hygiene, ExpansionInfo}; |
12 | use hir_ty::associated_type_shorthand_candidates; | 12 | use hir_ty::associated_type_shorthand_candidates; |
13 | use itertools::Itertools; | 13 | use itertools::Itertools; |
14 | use ra_db::{FileId, FileRange}; | 14 | use ra_db::{FileId, FileRange}; |
@@ -23,7 +23,7 @@ use crate::{ | |||
23 | db::HirDatabase, | 23 | db::HirDatabase, |
24 | diagnostics::Diagnostic, | 24 | diagnostics::Diagnostic, |
25 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, | 25 | semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx}, |
26 | source_analyzer::{resolve_hir_path, SourceAnalyzer}, | 26 | source_analyzer::{resolve_hir_path, resolve_hir_path_qualifier, SourceAnalyzer}, |
27 | AssocItem, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, Module, ModuleDef, | 27 | AssocItem, Field, Function, HirFileId, ImplDef, InFile, Local, MacroDef, Module, ModuleDef, |
28 | Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, | 28 | Name, Origin, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam, |
29 | }; | 29 | }; |
@@ -246,6 +246,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
246 | self.analyze(path.syntax()).resolve_path(self.db, path) | 246 | self.analyze(path.syntax()).resolve_path(self.db, path) |
247 | } | 247 | } |
248 | 248 | ||
249 | pub fn lower_path(&self, path: &ast::Path) -> Option<Path> { | ||
250 | let src = self.find_file(path.syntax().clone()); | ||
251 | Path::from_src(path.clone(), &Hygiene::new(self.db.upcast(), src.file_id.into())) | ||
252 | } | ||
253 | |||
249 | pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> { | 254 | pub fn resolve_bind_pat_to_const(&self, pat: &ast::BindPat) -> Option<ModuleDef> { |
250 | self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat) | 255 | self.analyze(pat.syntax()).resolve_bind_pat_to_const(self.db, pat) |
251 | } | 256 | } |
@@ -446,6 +451,23 @@ impl<'a, DB: HirDatabase> SemanticsScope<'a, DB> { | |||
446 | pub fn resolve_hir_path(&self, path: &Path) -> Option<PathResolution> { | 451 | pub fn resolve_hir_path(&self, path: &Path) -> Option<PathResolution> { |
447 | resolve_hir_path(self.db, &self.resolver, path) | 452 | resolve_hir_path(self.db, &self.resolver, path) |
448 | } | 453 | } |
454 | |||
455 | /// Resolves a path where we know it is a qualifier of another path. | ||
456 | /// | ||
457 | /// For example, if we have: | ||
458 | /// ``` | ||
459 | /// mod my { | ||
460 | /// pub mod foo { | ||
461 | /// struct Bar; | ||
462 | /// } | ||
463 | /// | ||
464 | /// pub fn foo() {} | ||
465 | /// } | ||
466 | /// ``` | ||
467 | /// then we know that `foo` in `my::foo::Bar` refers to the module, not the function. | ||
468 | pub fn resolve_hir_path_qualifier(&self, path: &Path) -> Option<PathResolution> { | ||
469 | resolve_hir_path_qualifier(self.db, &self.resolver, path) | ||
470 | } | ||
449 | } | 471 | } |
450 | 472 | ||
451 | // FIXME: Change `HasSource` trait to work with `Semantics` and remove this? | 473 | // FIXME: Change `HasSource` trait to work with `Semantics` and remove this? |
diff --git a/crates/ra_hir/src/semantics/source_to_def.rs b/crates/ra_hir/src/semantics/source_to_def.rs index 6f3b5b2da..8af64fdc1 100644 --- a/crates/ra_hir/src/semantics/source_to_def.rs +++ b/crates/ra_hir/src/semantics/source_to_def.rs | |||
@@ -151,7 +151,7 @@ impl SourceToDefCtx<'_, '_> { | |||
151 | let krate = self.file_to_def(file_id)?.krate; | 151 | let krate = self.file_to_def(file_id)?.krate; |
152 | let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); | 152 | let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); |
153 | let ast_id = Some(AstId::new(src.file_id, file_ast_id)); | 153 | let ast_id = Some(AstId::new(src.file_id, file_ast_id)); |
154 | Some(MacroDefId { krate: Some(krate), ast_id, kind }) | 154 | Some(MacroDefId { krate: Some(krate), ast_id, kind, local_inner: false }) |
155 | } | 155 | } |
156 | 156 | ||
157 | pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> { | 157 | pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> { |
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs index 74d64c97d..4b509f07c 100644 --- a/crates/ra_hir/src/source_analyzer.rs +++ b/crates/ra_hir/src/source_analyzer.rs | |||
@@ -224,7 +224,19 @@ impl SourceAnalyzer { | |||
224 | } | 224 | } |
225 | } | 225 | } |
226 | // This must be a normal source file rather than macro file. | 226 | // This must be a normal source file rather than macro file. |
227 | let hir_path = crate::Path::from_ast(path.clone())?; | 227 | let hir_path = |
228 | crate::Path::from_src(path.clone(), &Hygiene::new(db.upcast(), self.file_id))?; | ||
229 | |||
230 | // Case where path is a qualifier of another path, e.g. foo::bar::Baz where we | ||
231 | // trying to resolve foo::bar. | ||
232 | if let Some(outer_path) = path.syntax().parent().and_then(ast::Path::cast) { | ||
233 | if let Some(qualifier) = outer_path.qualifier() { | ||
234 | if path == &qualifier { | ||
235 | return resolve_hir_path_qualifier(db, &self.resolver, &hir_path); | ||
236 | } | ||
237 | } | ||
238 | } | ||
239 | |||
228 | resolve_hir_path(db, &self.resolver, &hir_path) | 240 | resolve_hir_path(db, &self.resolver, &hir_path) |
229 | } | 241 | } |
230 | 242 | ||
@@ -403,6 +415,7 @@ pub(crate) fn resolve_hir_path( | |||
403 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), | 415 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), |
404 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), | 416 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), |
405 | }); | 417 | }); |
418 | |||
406 | let body_owner = resolver.body_owner(); | 419 | let body_owner = resolver.body_owner(); |
407 | let values = | 420 | let values = |
408 | resolver.resolve_path_in_value_ns_fully(db.upcast(), path.mod_path()).and_then(|val| { | 421 | resolver.resolve_path_in_value_ns_fully(db.upcast(), path.mod_path()).and_then(|val| { |
@@ -416,6 +429,7 @@ pub(crate) fn resolve_hir_path( | |||
416 | ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()), | 429 | ValueNs::StaticId(it) => PathResolution::Def(Static::from(it).into()), |
417 | ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), | 430 | ValueNs::StructId(it) => PathResolution::Def(Struct::from(it).into()), |
418 | ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), | 431 | ValueNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), |
432 | ValueNs::ImplSelf(impl_id) => PathResolution::SelfType(impl_id.into()), | ||
419 | }; | 433 | }; |
420 | Some(res) | 434 | Some(res) |
421 | }); | 435 | }); |
@@ -424,9 +438,48 @@ pub(crate) fn resolve_hir_path( | |||
424 | .resolve_module_path_in_items(db.upcast(), path.mod_path()) | 438 | .resolve_module_path_in_items(db.upcast(), path.mod_path()) |
425 | .take_types() | 439 | .take_types() |
426 | .map(|it| PathResolution::Def(it.into())); | 440 | .map(|it| PathResolution::Def(it.into())); |
441 | |||
427 | types.or(values).or(items).or_else(|| { | 442 | types.or(values).or(items).or_else(|| { |
428 | resolver | 443 | resolver |
429 | .resolve_path_as_macro(db.upcast(), path.mod_path()) | 444 | .resolve_path_as_macro(db.upcast(), path.mod_path()) |
430 | .map(|def| PathResolution::Macro(def.into())) | 445 | .map(|def| PathResolution::Macro(def.into())) |
431 | }) | 446 | }) |
432 | } | 447 | } |
448 | |||
449 | /// Resolves a path where we know it is a qualifier of another path. | ||
450 | /// | ||
451 | /// For example, if we have: | ||
452 | /// ``` | ||
453 | /// mod my { | ||
454 | /// pub mod foo { | ||
455 | /// struct Bar; | ||
456 | /// } | ||
457 | /// | ||
458 | /// pub fn foo() {} | ||
459 | /// } | ||
460 | /// ``` | ||
461 | /// then we know that `foo` in `my::foo::Bar` refers to the module, not the function. | ||
462 | pub(crate) fn resolve_hir_path_qualifier( | ||
463 | db: &dyn HirDatabase, | ||
464 | resolver: &Resolver, | ||
465 | path: &crate::Path, | ||
466 | ) -> Option<PathResolution> { | ||
467 | let items = resolver | ||
468 | .resolve_module_path_in_items(db.upcast(), path.mod_path()) | ||
469 | .take_types() | ||
470 | .map(|it| PathResolution::Def(it.into())); | ||
471 | |||
472 | if items.is_some() { | ||
473 | return items; | ||
474 | } | ||
475 | |||
476 | resolver.resolve_path_in_type_ns_fully(db.upcast(), path.mod_path()).map(|ty| match ty { | ||
477 | TypeNs::SelfType(it) => PathResolution::SelfType(it.into()), | ||
478 | TypeNs::GenericParam(id) => PathResolution::TypeParam(TypeParam { id }), | ||
479 | TypeNs::AdtSelfType(it) | TypeNs::AdtId(it) => PathResolution::Def(Adt::from(it).into()), | ||
480 | TypeNs::EnumVariantId(it) => PathResolution::Def(EnumVariant::from(it).into()), | ||
481 | TypeNs::TypeAliasId(it) => PathResolution::Def(TypeAlias::from(it).into()), | ||
482 | TypeNs::BuiltinType(it) => PathResolution::Def(it.into()), | ||
483 | TypeNs::TraitId(it) => PathResolution::Def(Trait::from(it).into()), | ||
484 | }) | ||
485 | } | ||