diff options
Diffstat (limited to 'crates/hir/src')
-rw-r--r-- | crates/hir/src/code_model.rs | 50 | ||||
-rw-r--r-- | crates/hir/src/semantics.rs | 19 |
2 files changed, 62 insertions, 7 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 7a9747fc7..567fd91af 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -383,6 +383,16 @@ impl Module { | |||
383 | pub fn find_use_path(self, db: &dyn DefDatabase, item: impl Into<ItemInNs>) -> Option<ModPath> { | 383 | pub fn find_use_path(self, db: &dyn DefDatabase, item: impl Into<ItemInNs>) -> Option<ModPath> { |
384 | hir_def::find_path::find_path(db, item.into(), self.into()) | 384 | hir_def::find_path::find_path(db, item.into(), self.into()) |
385 | } | 385 | } |
386 | |||
387 | /// Finds a path that can be used to refer to the given item from within | ||
388 | /// this module, if possible. This is used for returning import paths for use-statements. | ||
389 | pub fn find_use_path_prefixed( | ||
390 | self, | ||
391 | db: &dyn DefDatabase, | ||
392 | item: impl Into<ItemInNs>, | ||
393 | ) -> Option<ModPath> { | ||
394 | hir_def::find_path::find_path_prefixed(db, item.into(), self.into()) | ||
395 | } | ||
386 | } | 396 | } |
387 | 397 | ||
388 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 398 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -709,11 +719,23 @@ impl Function { | |||
709 | } | 719 | } |
710 | 720 | ||
711 | pub fn params(self, db: &dyn HirDatabase) -> Vec<Param> { | 721 | pub fn params(self, db: &dyn HirDatabase) -> Vec<Param> { |
722 | let resolver = self.id.resolver(db.upcast()); | ||
723 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | ||
724 | let environment = TraitEnvironment::lower(db, &resolver); | ||
712 | db.function_data(self.id) | 725 | db.function_data(self.id) |
713 | .params | 726 | .params |
714 | .iter() | 727 | .iter() |
715 | .skip(if self.self_param(db).is_some() { 1 } else { 0 }) | 728 | .skip(if self.self_param(db).is_some() { 1 } else { 0 }) |
716 | .map(|_| Param { _ty: () }) | 729 | .map(|type_ref| { |
730 | let ty = Type { | ||
731 | krate: self.id.lookup(db.upcast()).container.module(db.upcast()).krate, | ||
732 | ty: InEnvironment { | ||
733 | value: Ty::from_hir_ext(&ctx, type_ref).0, | ||
734 | environment: environment.clone(), | ||
735 | }, | ||
736 | }; | ||
737 | Param { ty } | ||
738 | }) | ||
717 | .collect() | 739 | .collect() |
718 | } | 740 | } |
719 | 741 | ||
@@ -742,15 +764,21 @@ impl From<Mutability> for Access { | |||
742 | } | 764 | } |
743 | } | 765 | } |
744 | 766 | ||
767 | pub struct Param { | ||
768 | ty: Type, | ||
769 | } | ||
770 | |||
771 | impl Param { | ||
772 | pub fn ty(&self) -> &Type { | ||
773 | &self.ty | ||
774 | } | ||
775 | } | ||
776 | |||
745 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 777 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
746 | pub struct SelfParam { | 778 | pub struct SelfParam { |
747 | func: FunctionId, | 779 | func: FunctionId, |
748 | } | 780 | } |
749 | 781 | ||
750 | pub struct Param { | ||
751 | _ty: (), | ||
752 | } | ||
753 | |||
754 | impl SelfParam { | 782 | impl SelfParam { |
755 | pub fn access(self, db: &dyn HirDatabase) -> Access { | 783 | pub fn access(self, db: &dyn HirDatabase) -> Access { |
756 | let func_data = db.function_data(self.func); | 784 | let func_data = db.function_data(self.func); |
@@ -908,12 +936,12 @@ impl MacroDef { | |||
908 | 936 | ||
909 | /// Indicate it is a proc-macro | 937 | /// Indicate it is a proc-macro |
910 | pub fn is_proc_macro(&self) -> bool { | 938 | pub fn is_proc_macro(&self) -> bool { |
911 | matches!(self.id.kind, MacroDefKind::CustomDerive(_)) | 939 | matches!(self.id.kind, MacroDefKind::ProcMacro(_)) |
912 | } | 940 | } |
913 | 941 | ||
914 | /// Indicate it is a derive macro | 942 | /// Indicate it is a derive macro |
915 | pub fn is_derive_macro(&self) -> bool { | 943 | pub fn is_derive_macro(&self) -> bool { |
916 | matches!(self.id.kind, MacroDefKind::CustomDerive(_) | MacroDefKind::BuiltInDerive(_)) | 944 | matches!(self.id.kind, MacroDefKind::ProcMacro(_) | MacroDefKind::BuiltInDerive(_)) |
917 | } | 945 | } |
918 | } | 946 | } |
919 | 947 | ||
@@ -1276,6 +1304,14 @@ impl Type { | |||
1276 | ) | 1304 | ) |
1277 | } | 1305 | } |
1278 | 1306 | ||
1307 | pub fn remove_ref(&self) -> Option<Type> { | ||
1308 | if let Ty::Apply(ApplicationTy { ctor: TypeCtor::Ref(_), .. }) = self.ty.value { | ||
1309 | self.ty.value.substs().map(|substs| self.derived(substs[0].clone())) | ||
1310 | } else { | ||
1311 | None | ||
1312 | } | ||
1313 | } | ||
1314 | |||
1279 | pub fn is_unknown(&self) -> bool { | 1315 | pub fn is_unknown(&self) -> bool { |
1280 | matches!(self.ty.value, Ty::Unknown) | 1316 | matches!(self.ty.value, Ty::Unknown) |
1281 | } | 1317 | } |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 0516a05b4..c61a430e1 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -697,6 +697,25 @@ fn find_root(node: &SyntaxNode) -> SyntaxNode { | |||
697 | node.ancestors().last().unwrap() | 697 | node.ancestors().last().unwrap() |
698 | } | 698 | } |
699 | 699 | ||
700 | /// `SemanticScope` encapsulates the notion of a scope (the set of visible | ||
701 | /// names) at a particular program point. | ||
702 | /// | ||
703 | /// It is a bit tricky, as scopes do not really exist inside the compiler. | ||
704 | /// Rather, the compiler directly computes for each reference the definition it | ||
705 | /// refers to. It might transiently compute the explicit scope map while doing | ||
706 | /// so, but, generally, this is not something left after the analysis. | ||
707 | /// | ||
708 | /// However, we do very much need explicit scopes for IDE purposes -- | ||
709 | /// completion, at its core, lists the contents of the current scope. The notion | ||
710 | /// of scope is also useful to answer questions like "what would be the meaning | ||
711 | /// of this piece of code if we inserted it into this position?". | ||
712 | /// | ||
713 | /// So `SemanticsScope` is constructed from a specific program point (a syntax | ||
714 | /// node or just a raw offset) and provides access to the set of visible names | ||
715 | /// on a somewhat best-effort basis. | ||
716 | /// | ||
717 | /// Note that if you are wondering "what does this specific existing name mean?", | ||
718 | /// you'd better use the `resolve_` family of methods. | ||
700 | #[derive(Debug)] | 719 | #[derive(Debug)] |
701 | pub struct SemanticsScope<'a> { | 720 | pub struct SemanticsScope<'a> { |
702 | pub db: &'a dyn HirDatabase, | 721 | pub db: &'a dyn HirDatabase, |